WebSocket+WebRTCWeb 前端开发 web前端

WebSocket协议分析及实现

2018-01-03  本文已影响43人  _shen

1.概述

Webscoket是Web浏览器和服务器之间的一种全双工通信协议,其中WebSocket协议由IETF定为标准,WebSocket API由W3C定为标准。一旦Web客户端与服务器建立起连接,之后的全部数据通信都通过这个连接进行。通信过程中,可互相发送JSON、XML、HTML或图片等任意格式的数据。
WS(WebSocket)与HTTP协议相比,相同点主要有:

2.主要特点

推送功能:服务器可以直接向客户端推送消息。之前采取的方式都是客户端主动向服务器发送请求,这样比较耗费资源。
减少通信量:只要第一次建立连接,就可以一直进行通信,不像HTTP协议,需要频繁的建立请求,一问一答的模式。此外,Websocket的头部数据也比较少。

3.握手协议

websocket是基于TCP的一个应用协议,与HTTP协议的关联之处在于websocket的握手数据被HTTP服务器当作HTTP包来处理,主要通过Update request HTTP包建立起连接,之后的通信全部使用websocket自己的协议。
请求:TCP连接建立后,客户端发送websocket的握手请求,请求报文头部如下:

GET /chat HTTP/1.1
Host: server.example.com
**Upgrade: websocket**
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: https://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

响应:服务器接收到请求后,返回状态码为101 Switching Protocols 的响应。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
FIN:1bit,是否为信息的最后一帧
RSV 1-3:1bit,备用,默认为0
opcode:4bit,帧类型
                         0x00 连续消息分片
                         0x01 文本消息分片
                         0x02 二进制消息分片
                         0x03 ~ 0x07 为将来的非控制消息片段保留测操作吗
                         0x08 连接关闭
                         0x09 心跳检查 ping
                         0x0a 心跳检查pong
                         0x0b ~ 0x0f 为将来的控制消息片段保留的操作码
MASK:定义传输的数据是否有加掩码,如果设置为1,掩码键必须放在masking-key区域,客户端发送给服务端的所有消息,此位的值都是1
payload length:7bit,传输数据长度,以字节为单位。当这个长度为7bit数字为126时,紧随其后的2个字节也是表示数据长度。当这个长度为7bit数字为127时,紧随其后的8个字节也是表示数据长度。
Masking-key:0或者4bit,只有当MASK设置为1时才有效。
Playload data:负载数据,为扩展数据和应用数据之和,Extension data + Application data。
Extension data:扩展数据,如果客户端和服务端没有特殊的约定,那么扩展数据长度始终为0
Application data:应用数据,

以上就是WebSocket协议帧的分析

4.实现

客户端

// websocket.js
+function( window ){
  // check whether your browser surpport the WebSocket Protocal
  if ( 'WebSocket' in window ) {
    var url = 'ws://127.0.0.1:8080';
    var ws = new WebSocket(url);
    var msgRecieved;
    
    ws.onopen = function () {
      console.log('Connected to websocket server ...');
    };

    ws.onmessage = function(e){
      msg = e.data;
      console.log('Message from server:' + e.data);
    };

    ws.onclose = function(e){
      console.log('Disconnected');
    }

    // send message to server
    ws.send('message from client');

  } else {
    console.error('Websocket is not supported by your browser!')
  }
  
}( window );

服务端

采用NodeJS+socket.io实现

# 安装模块
npm install --save express
npm install --save socket.io

服务端代码:

var app= require('express')()
var http = require('http').Server(app)
var io= require('socket.io').(http)

app.get('/', function(req, res){
  res.send('<center><h1>WebSocket Test</h1></center>')
})

io.on('connection', function(socket){
    console.log('There is a client connected!');

    socket.on('disconnect', function(){
    console.log('There is a client disconnected')
    socket.on('message', function(msg){
      io.emit('message', msg)
    })

  })

http.listen(8080, function(){
  console.log('listening on *:8080')
})

})

说明

后期,我会对WebSocket即时通信做进一步研究,并开发一个简易的在线聊天系统,加入到我的开源OA系统中,希望大家持续关注……

上一篇下一篇

猜你喜欢

热点阅读