`
DaN_DaN
  • 浏览: 1286 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

HTML5 WebSocket 通讯原理.

    博客分类:
  • Java
阅读更多
在javaeye都好久了.但是从来没发表个什么东西
由于最近在观注 HTML5 于是就看了下WebSocket
又不想找现成的框架去搞.就打算自己弄弄.
开始吧.
提前条件
1> 了解socket.
2> 了解协议,了解HTTP协议更好.(想想为什么需要协议就行.安全?保证数据完整?便于解析?)
3> 理解字节,字节序,如: 32位int 的 30转成 高字节序的字节 及是 0x00 0x00 0x00 0x1E,低字节序则 0x1E 0x00 0x00 0x00. 没数错的话是4个字节^_^

Web Socket参考文章

  1. http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
   因为感觉里面有点乱,顺序没有按常理出牌.
  下面是按我觉得应该有的顺序截取了该文章关键部分
 

  The following diagrams summarise the protocol:

        Handshake
           |
           V
        Frame type byte <-------------------------------------.
           |      |                                           |
           |      `-- (0x00 to 0x7F) --> Data... --> 0xFF -->-+
           |                                                  |
           `-- (0x80 to 0xFF) --> Length --> Data... ------->-'
    一个 WebSocket 通讯流程 简单说.就是先握手.在谈话.(跟见到领导一样)



Internet-Draft           The WebSocket protocol              August 2010

/*请求部分也就是浏览器传到服务器的数据,需要解析*/
        GET /demo HTTP/1.1
        Host: example.com
        Connection: Upgrade
        Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
        Sec-WebSocket-Protocol: sample
        Upgrade: WebSocket
        Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
        Origin: http://example.com

        ^n:ds[4U


   The handshake from the server looks as follows:

        /*响应部分 需要根据 请求消息 来生成响应报文*/
        HTTP/1.1 101 WebSocket Protocol Handshake
        Upgrade: WebSocket
        Connection: Upgrade
        Sec-WebSocket-Origin: http://example.com
        Sec-WebSocket-Location: ws://example.com/demo
        Sec-WebSocket-Protocol: sample

        8jKS'y:G*Co,Wxa-


   //上面request/response部分的以第二行至倒数第三行 都是这种格式,并且顺序无关
   After the leading line in both cases come an unordered ASCII case-
   insensitive set of fields, one per line, that each match the
   following non-normative ABNF: [RFC5234]

     field         = 1*name-char colon [ space ] *any-char cr lf
     colon         = %x003A ; U+003A COLON (:)
     space         = %x0020 ; U+0020 SPACE
     cr            = %x000D ; U+000D CARRIAGE RETURN (CR)
     lf            = %x000A ; U+000A LINE FEED (LF)
     name-char     = %x0000-0009 / %x000B-000C / %x000E-0039 / %x003B-10FFFF
                     ; a Unicode character other than U+000A LINE FEED (LF), U+000D CARRIAGE RETURN (CR), or U+003A COLON (:)
     any-char      = %x0000-0009 / %x000B-000C / %x000E-10FFFF
                     ; a Unicode character other than U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR)

   NOTE: The character set for the above ABNF is Unicode.  The fields
   themselves are encoded as UTF-8.

   Lines that don't match the above production cause the connection to
   be aborted.
  




   /****************重点部分******************/
  
   To prove that the handshake was received, the server has to take
   three pieces of information and combine them to form a response.  The
   first two pieces of information come from the |Sec-WebSocket-Key1|
   and |Sec-WebSocket-Key2| fields in the client handshake:

        Sec-WebSocket-Key1: 18x 6]8vM;54 *(5:  {   U1]8  z [  8
        Sec-WebSocket-Key2: 1_ tx7X d  <  nw  334J702) 7]o}` 0

   For each of these fields, the server has to take the digits from the
   value to obtain a number (in this case 1868545188 and 1733470270
   respectively), then divide that number by the number of spaces
   characters in the value (in this case 12 and 10) to obtain a 32-bit
   number (155712099 and 173347027).  These two resulting numbers are
   then used in the server handshake, as described below.


   with 0x0D 0x0A and followed by 8 random bytes, part of a challenge,
   and the server sends 18 bytes starting with 0x0D 0x0A and followed by
   16 bytes consisting of a challenge response.  The details of this
   challenge and other parts of the handshake are described in the next
   section.

   The concatenation of the number obtained from processing the |Sec-
   WebSocket-Key1| field, expressed as a big-endian 32 bit number, the
   number obtained from processing the |Sec-WebSocket-Key2| field, again
   expressed as a big-endian 32 bit number, and finally the eight bytes
   at the end of the handshake, form a 128 bit string whose MD5 sum is
   then used by the server to prove that it read the handshake.



   大概意思就是说 服务端需要根据 Sec-WebSocket-Key1,Sec-WebSocket-Key2和请求响应部分的最后8个字节 生成一个16个字节的数组(128位)
   再对他进行MD5 签名

也就是
响应消息最后的 8jKS'y:G*Co,Wxa-
实际上是根据
            Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
           Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
   
                            ^n:ds[4U //请求响应部分的最后8个字节
                 计算出来的
规则:
将的key1值部分"4 @1  46546xW%0l 1 5" 取掉非数字的字符,会得到一个数字
        则: 414654015 在计算该字符串的空格数 假设为 n 让   int key1 = (414654015  / n); 然后将他转成 高字节序的字节数组
  

      伪代码:
  
public byte[] formatKey(String key);

main
{
byte[] bytes = new byte[16];
bytes[0~3] = formatKey(key1);
bytes[4~7] = formatKey(key2);
bytes[8~15] =  请求响应部分的最后8个字节
bytes = md5(bytes);
}
  /***********************************************/

  
   接下来的就简单了===发消息

   This wire format for the data transfer part is described by the
   following non-normative ABNF, which is given in two alternative
   forms: the first describing the wire format as allowed by this
   specification, and the second describing how an arbitrary bytestream
   would be parsed.  [RFC5234]
    //大概意思就是说有两种数据通讯协议,第一种简单的文本,也就是源码里用的,第二种就是二进制数据通讯协议..
   ****传输之前必须先握手****
     ; the wire protocol as allowed by this specification
     frames        = *frame
     frame         = text-frame
     text-frame    = (%x00) *( UTF8-char ) %xFF

     ; the wire protocol including error-handling and forward-compatible parsing rules
     frames        = *frame
     frame         = text-frame / binary-frame
     text-frame    = (%x00-%x7F) *( UTF8-char / %x80-%x7E ) %xFF
     binary-frame  = (%x80-%xFF) length < as many bytes as given by the length >
     length        = *(%x80-%xFF) (%x00-%x7F)


  遵循他的格式. 照着socket 收发消息那样发就OK了!
如:发一个 Hello!
byte[] data = new byte[2+];
byte[0] = 0x00
byte[1~data.length - 1] = "Hello!".getBytes("UTF-8");
byte[data.length - 1] = 0xFF

//源码运行方式
1.WebServerSocket.main();
2.打开 socket.html (用Google Chrome)

我的环境: WindowsXP,JDK1.6 , Google Chrome(version 13.0.782.220 m)
 
第一次写技术性的文章。希望大家喜欢,多多指教 ^_^.
分享到:
评论
2 楼 DaN_DaN 2012-05-19  
wlzz 写道
确实,至少也要nio!

WebSocket 与 nio没有任何关系哈..
这里只是介绍其原理..说白了就是WebSocket协议,以及实现
1 楼 wlzz 2012-04-25  
确实,至少也要nio!

相关推荐

    WebSocket客户端和服务端实例源码

    各个应用服务器及浏览器厂商逐步开始统一,在 JavaEE7 中也实现了 WebSocket 协议,从而无论是客户端还是服务端的 WebSocket 都已完备,读者可以查阅HTML5 规范,熟悉新的 HTML 协议规范及 WebSocket 支持。

    html5 http的轮询和Websocket原理

    ... 长轮询:客户端像传统轮询一样从服务器请求数据。然而,如果服务器没有可以立即返回给客户端的数据,则不会立刻返回一个...WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使

    QT:用QWebSocket实现webchannel,实现C++与HTML通信

    基本原理是通过channel将C++对象暴露给HTML,在HTML中调用qwebchannel.js。前提是建立transport,QT只提供了一个抽象基类QWebChannelAbstractTransport。

    微信小程序 WebSocket详解及应用

    微信的WebSocket接口和HTML5的WebSocket基本一样,是HTTP协议升级来的,做为一个新的Socket在B/S上使用,它实现了浏览器与服务器全双工通信。 因为这里是做小程序,所以就不对WebSocket的底层和协议做过多的说明了,...

    Android使用WebSocket实现多人游戏

    WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是: WebSocket ...

    混合移动应用的消息推送之websocket

    而开发消息推送功能时,我们就既可以使用NativeApp的系统自带推送如GCM和APNS,又可以使用基于html5的websocket推送。对于混合应用的websocket消息推送,其基本原理如下:图1.Hybridappwebsocket工作流程而原生应用...

    JAVA上百实例源码以及开源项目源代码

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    JAVA上百实例源码以及开源项目

     当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。  QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...

    Vue与Node.js通过socket.io通信的示例代码

    HTML5中的WebSocket通信 Flash中使用的WebSocket通信 XHR轮询 JSONP轮询 Forever Iframe 在通信时,客户端与服务器端可以使用相同的API 2、怎么用 原理:创建Scoket.IO服务器,该服务器依赖于一个已经创建的...

Global site tag (gtag.js) - Google Analytics