WebKit之WebSocket

转载 2015年11月20日 00:34:32

WebSocket是HTML5的一个重要特性,能提供client和server的双向通信,是很多WebAPP做网络通信的首选,不过它在Android的WebKit中并不支持,也就造就了socket.io的流行。在我们云OS中当然不能漏掉这个特性,我这周的任务就是要在云OS的Webkit中支持websocket,以此让WebApp能直接调用websocket API。

某些平台的webkit(比如Android)不支持websocket并不是webkit没管这块,而是这一特性需要在各个平台特有的网络层中做porting。所以初步判断只需要补全网络层的读写即可。先看看源码WebCore/Modules/websockets,和websocket相关的代码都在这个文件夹中,其结构如下:


通过WebSocket.cpp, WebSocket.h和WebSocket.idl包装websocket js API,所以在js中new WebSocket("...",...");时,反映到webkit就是:

  1. WebSocket.cpp -> WebSocketChannel.cpp -> WebSocketFrame.cpp, WebSocketHandshake.cpp -> SocketStreamHandle  

其中,WebSocket.cpp是JS API包装,WebSocketChannel.cpp是channel的包装,WebSocketFrame.cpp和WebSocketHandshake.cpp处理websocket的上层协议,SocketStreamHandle处理网络流。当SocketStreamHandle读到数据后,又通过:

  1. SocketStreamHandle->SocketStreamHandleClient->WebSocketChannelClient  

这样的路径把消息发送到JS中的onmessage的回调中,其中WebSocketChannel.cpp是SocketStreamHandleClient的实现,WebSocket.cpp是WebSocketChannelClient的实现,因此这么看来WebSocket整个下层的结构和信息回路就清楚了。

分析完webkit代码后,会发现webkit已经把websocket的架子和协议都已做好,唯独缺了SocketStreamHandle中数据的读和写,也证实了我开始的判断。看SocketStreamHandleBase.h和SocketStreamHandleBase.cpp会发现,只需要继承SocketStreamHandleBase并实现虚方法platformSend和platformClose,另外读到数据后调用SocketStreamHandleClient.didReceiveSocketStreamData把数据发送上层,这样整个websocket就完整了。

实现这几个方法并不困难,需要关注的是这里需要基于异步的网络读写,功底好的可以直接epoll或者select,如果新手或者有跨平台的需求,可以用libevent,我就是使用了这个库,具体代码就不贴了,标准libevent读和写足矣。

补全websocket后,不但可以在JS API中提供websocket支持,也可以在native端提供websocket client端的能力,和js不同的是,native没有js的执行环境,也不需要WebSocket.cpp的包装,所以应该直接从WebSocketChannel.cpp开始用起,比如:

  1. RefPtr<WebSocketChannel> wsChannel = WebSocketChannel::create(page->mainFrame()->document(), channel);  
  2. KURL url = KURL(KURL(), String("ws://127.0.0.1:9223"));  
  3. wsChannel->connect(url, String("webkit"));  
这里的channel是WebSocketChannelClient的一个实现,在js环境是这个实现是WebSocket.cpp,而在native端就需要我们单独实现,重要的是实现didReceiveMessage方法,这是websocket协议解析后的message回调,这样就相当于在js中使用onmessage方法了。

其他websocket的部分就不多提了,对协议有兴趣的朋友可以重点看WebSocketFrame.cpp和WebSocketHandshake.cpp,对webkit idl感兴趣的可以看WebSocket.cpp, WebSocket.h和WebSocket.idl。总之,小小的websocket还是有很多干货的。

探索WebKit内核(三)------ WebSocket

WebSocket是HTML5的一个重要特性,能提供client和server的双向通信,是很多WebAPP做网络通信的首选,不过它在Android的WebKit中并不支持,也就造就了socket.i...
  • cutesource
  • cutesource
  • 2013年05月12日 14:57
  • 15080

WebKit之WebSocket

WebSocket是HTML5的一个重要特性,能提供client和server的双向通信,是很多WebAPP做网络通信的首选,不过它在Android的WebKit中并不支持,也就造就了socket.i...
  • sauphy
  • sauphy
  • 2015年11月20日 00:34
  • 639

websocket客户端的代码

网上找了个websocket的代码  不过只提供了服务端的处理, 对于客户端握手 以及订阅等进行了补充开发,实现了相关功能 void parse_str(char *request){ c...
  • bd_jc
  • bd_jc
  • 2017年05月27日 15:08
  • 294

WebKit之WebSocket模块的代码层初步分析

## WebSocket的js代码 var socket = new WebSocket('ws://localhost:8080'); socket.onopen = function(event...
  • sauphy
  • sauphy
  • 2015年12月01日 18:14
  • 234

webkit支持跨域的方法

修改文件WebCore/page/SecurityOrigin.cpp 中的 bool SecurityOrigin::canRequest(const KURL& url) const 让它返...
  • ibingow
  • ibingow
  • 2012年05月29日 16:44
  • 4478

html5 之 websocket

websocket概述 原理简介         WebSocket protocol 是HTML5一种新的协议。它与html协议一样是基于应用层的协议。它实现了浏览器与服务器全双工通信(f...
  • shuliagnyu
  • shuliagnyu
  • 2016年04月21日 20:55
  • 4671

HTML5新特性之WebSocket实例(可下载)

客户端:页面chat.html 在线群聊 var webSocket=new WebSocket("ws://192.168.1.105:8080/html5/websocke...
  • xuxile
  • xuxile
  • 2015年01月14日 10:25
  • 1429

WebKit之Chromium加载网络加速初步研究

本文主要内容翻译自Google的文档Data Compression Proxy,如果您觉得文章写的不明白,请参看原文。 对于一款浏览器而言,速度无疑是非常重要的,其中加载速度更是重中之重。UC...
  • sauphy
  • sauphy
  • 2016年01月13日 22:07
  • 623

WebKit WebInspector 与websocket

接入chromium远程调试的记录 Table of Contents 1 Web Inspector in mobile chromium 1.1 frontend/backe...
  • cjluseacher
  • cjluseacher
  • 2014年01月19日 11:10
  • 893

最近在找关于websocket的简单实现

最近在找关于websocket的简单实现,想移植到miniblink里。 目前找到libpomelo 、libwebsockets、noPoll、 websocketpp...
  • weolar
  • weolar
  • 2016年05月05日 08:53
  • 856
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WebKit之WebSocket
举报原因:
原因补充:

(最多只允许输入30个字)