WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。
在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。php
在JS中建立WebSocket後,會有一個HTTP請求發向瀏覽器以發起請求。在取得服務器響應後,創建的鏈接會使用HTTP升級將HTTP協議轉換爲WebSocket協議。node
ajax輪詢和 websocket 鏈接示意圖web
WebSocket是應用層協議,是TCP/IP協議的子集,經過HTTP/1.1協議的101狀態碼進行握手。
WebSocket協議的創建須要先借助HTTP協議,在服務器返回101狀態碼以後,就能夠進行websocket全雙工雙向通訊了。ajax
web端的請求頭部:api
1. 首先瀏覽器發送http 的get 請求
客戶端端口 60992 服務端端口 8181瀏覽器
2. 緊接着服務端返回 101服務器
客戶端向服務端發送消息 nick 999websocket
客戶端代碼:
簡單的建立websocket 鏈接,鏈接成功後發送一條消息, 內容爲 nick 999socket
var nick = getQueryString('nick')||'江芊' var url = 'ws://localhost:8181/' var Socket = new WebSocket(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) var data = 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"}tcp
var WebSocketServer = require('ws').Server; var wss = new WebSocketServer({ port: 8181 }); var clients = [] var id = 0 wss.on('connection', function (ws) { console.log('client connected'); clients.push({ id: ++id, ws: ws }) ws.on('message', function (message) { console.log('message', message); if(message.indexOf('nick') === 0) { let nickname_array = message.split(' '); if(nickname_array.length >= 2) { broadcastSend("nick", '新用戶:'+nickname_array[1]); } } else if(message.indexOf('PRIVMSG') === 0) { var msglist = message.split(' ') broadcastSend("message", msglist[1]); } }); function broadcastSend(type, message) { clients.forEach(function(v, i) { if(v.ws.readyState === ws.OPEN) { v.ws.send(JSON.stringify({ "type": type, "message": message })); } }) } });
能夠看出在websocket發送消息的鏈接傳輸中,客戶端端口仍是爲60992 ,服務端仍是爲8181,一直保持連接沒有斷開。
readyState
只讀屬性 readyState 表示鏈接狀態,能夠是如下值:
bufferedAmount
只讀屬性 bufferedAmount 已被 send() 放入正在隊列中等待傳輸,可是尚未發出的 UTF-8 文本字節數
一、websocket 只有一次握手,且是基於http的get 請求實現。二、websocket 客戶端和服務端傳輸消息只能是字符串。三、websocket 爲長鏈接,須要手動斷開,業務上處理聊天時,能夠經過添加心跳來更新有效的鏈接。四、ws 鏈接爲tcp 鏈接,wss 爲tls 鏈接。