当前位置: 首页 > 工具软件 > Dillo > 使用案例 >

Dillo 2.0 学习笔记一

高才
2023-12-01

花了半年时间,终于把嵌入式Flash播放器写完了,老板们很满意:-) 于是可以停下来研究点新东西了,就拿 Dillo 2.0 下手吧。

 

前面的window框架就不仔细看了,虽然移植的重点在那边,但无非也就是
Window - Tab - Group(UI) - Viewport - Layout
的结构。逻辑上的结构是
Browser - DilloWeb
因此重点是DilloWeb这个对象是如何发出Http请求,解析Http协议,以及进行布局等最终通过Layout显示出来。

 

万事开头难,我们先从Dillo的数据流开始分析。

 

Dillo 数据流


Dillo定义了一个很有趣的数据结构ChainLink,通过它实现了类似状态机的功能。也正是这个ChainLink,让Dillo的可读性大大下降。总的来说,每一个ChainLink定义了一个处理器节点,或者干脆理解成一个状态机,虽然状态都是保存在传入的参数中:-)。

 

刚刚看了Chrome的实现机制,发现Dillo的ChainLink机制和Chrome的Command模式是很相似的,当然Dillo是基于C的,也没有用Message机制,而是完全通过回调函数实现(但因此也就避免了Serialize的难题),除此之外,二者是很相似的......

 

先从发送http请求看起,一上来Dillo就建立下面的一条ChainLink,解释如下:


IO(1) ----- Http(1) ----- Capi(1)


Capi : Dillo 叫 Cache API,作用是封装底层具体数据来源使其对上层透明。
Http : 用于处理Http连接,真正的Http协议解析反而不在里面,汗......
IO : 处理IO请求

 

这条ChainLink的处理状态流程为:
a) 发送一个Capi(1).OpStart命令,启动一次Capi(1)操作,即发送网络命令操作。
b)Capi(1)判断这是一个Http命令,于是挂接Http(1)模块,并向其发送OpStart命令
c)Http(1)尝试连接Http_get,会调用DNS解析操作Dns_resolve - Dns_serve_req - Dns_server。这里可能用到多线程。解析成功后填入对应结构,等待Timer时间到达后启动回调函数Http_dns_cb。
d)至此,Capi(1)启动函数返回。接下来的数据流需要等待Timer来触发。
e)回调函数里开始建立连接并调用Http_send_query,此时挂接IO(1)模块,并向其先后发送OpStart和OpSend命令。
f)IO(1)在OpSend命令中发起实际的Write操作。
g)Http(1)之后向Capi(1)发送OpSend操作,表示Http请求已经发出。

 

至此,第一条数据流分析完毕。在Capi(1)接受到OpStart命令后,它会建立第二条数据流:


IO(2) ----- Dpi(2) ----- Capi(2)


Dpi : Dillo plugin in, 目的是支持基于http协议的多种命令解析,这条数据链里用于处理html协议。

 

本ChainLink的数据流程为:
a)发送一个Capi(2).OpStart命令,启动一次Capi(2)操作,并传入已经建立的socket连接。
b)Capi(2)挂接Dpi(2)模块,并向其发送OpStart命令。
c)Dip(2)挂接IO(2)模块,并向其发送OpStart命令。
d)IO(2)模块尝试从网络获取数据(非阻塞模式)
e)至此,由Http(1)中网络连接产生的回调函数调用结束。
f)回调函数触发后,IO(2)会向Dpi(2)发送OpSend命令,并传入读取的数据流。
g)Dpi(2)收到数据流后,会调用Dpi_get_token和Dpi_parse_token来对数据流进行词法分析,并将分析成功的tag向Capi(2)发送OpSend命令。
h)Capi(2)调用a_Cache_process_dbuf处理数据,根据需要向UI发送对应命令。至此,IO(2)回调函数一次调用结束。

 

今天就看到这里。感觉奇怪的地方是Dpi_parse_token的中token似乎不是http协议,后面再仔细分析。总的来说,Dillo为了提高响应速度,各个环节尽量使用非阻塞的回调函数来实现,并因此引入了ChainLink这个可恶的东西(其实这个东西我感觉不合理的,为啥每个ChainLink需要保存左右两个FCB呢,一个足矣,反正有链表连着)。

 

待续~

 

 类似资料: