概述WebSocket是HTML5开始提供的一种在单TCP连接上进行全双工通信的协议。在WebSocketAPI中,浏览器和服务器只需要完成一次握手,两者之间就可以直接建立持久连接,进行双向数据传输。在JS中创建WebSocket后,会向浏览器发送HTTP请求发起请求。获取服务器响应后,建立的连接会使用HTTP升级,将HTTP协议转换为WebSocket协议。ajax轮询与websocket连接握手连接示意图WebSocket是一个应用层协议,是TCP/IP协议的子集,通过HTTP/1.1协议的101状态码进行握手。WebSocket协议的建立首先需要用到HTTP协议。服务器返回101状态码后,即可进行websocket全双工双向通信。web端的请求头:1.首先浏览器发送一个httpget请求,客户端端口为60992,服务器端口为81812,然后服务器返回101字段,说明Connection必须设置为Upgrade.升级字段必须设置为Websocket。Sec-WebSocket-Key是一个随机字符串,服务器将使用这些数据构造SHA-1消息摘要。在“Sec-WebSocket-Key”中添加特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1摘要,再进行BASE-64编码,将结果作为“Sec-WebSocket-Accept”“标头的值返回给客户端。这样做可以尽量避免将普通的HTTP请求误认为是Websocket协议。Sec-WebSocket-Version表示支持的Websocket版本。RFC6455要求的版本是13,之前的草案版本应该被弃用。Origin字段是可选的,通常用于表示在浏览器中发起Websocket连接的页面,类似于Referer。但是,与Referer不同,Origin仅包含协议和主机名。Websocket中也可以使用HTTP协议中定义的其他一些字段,例如Cookie。传输消息客户端向服务器发送消息nick999客户端代码:简单的创建一个websocket连接,连接成功后发送消息,内容为nick999varnick=getQueryString('nick')||'江倩'varurl='ws://localhost:8181/'varSocket=newWebSocket(url);Socket.onopen=function(evt){console.log('open',evt)Socket.send('nick'+nick)}Socket.onclose=function(evt){console.log('close',evt)}Socket.onmessage=function(evt){console.log('message',evt)vardata=JSON.parse(evt.data)console.log(data)updataMsg(data)}Socket.onerror=function(evt){console.log('error',evt)}服务器向客户端发送消息{"type":"nick","message":"346226260347224250346210267:999"}服务器代码:node启动的websocket服务,端口8181,收到客户端的消息后,向客户端发送消息:{"type":"nick","message":"346226260347224250346210267:999"}varWebSocketServer=require('ws').Server;varwss=newWebSocketServer({port:8181});varclients=[]varid=0wss.on('connection',function(ws){console.log('客户端连接');clients.push({id:++id,ws:ws})ws.on('message',function(message){console.log('message',message);if(message.indexOf('nick')===0){letnickname_array=message.split('');if(nickname_array.length>=2){broadcastSend("nick",'NewUser:'+nickname_array[1]);}}elseif(message.indexOf('PRIVMSG')===0){varmsglist=message.split('')broadcastSend("message",msglist[1]);}});functionbroadcastSend(type,message){clients.forEach(function(v,i){if(v.ws.readyState===ws.OPEN){v.ws.send(JSON.stringify({"type":type,"消息":消息}));}})}});可以看到,在websocket发送消息的连接传输中,客户端端口还是60992,服务端端口还是8181,连接一直没有断开。api描述属性readyState只读属性readyState表示连接状态,可以是以下值:0-表示连接还没有建立。1-表示已建立连接并且可以进行通信。2-表示连接正在关闭。3-表示连接已关闭或无法打开连接。bufferedAmount只读属性bufferedAmount已被send()放入队列等待发送,但尚未发送的UTF-8文本字节数。事件open-建立连接时触发消息-customer端从服务器接收数据时触发error-发生通信错误时触发close-关闭连接时触发方法send-使用连接close发送数据-关闭连接完成。2、websocket客户端和服务端之间传输的消息只能是字符串。3.websocket是长连接,需要手动断开。在处理业务聊天时,可以通过添加心跳来更新有效连接。4、ws连接是tcp连接,wss是tls连接。
