websocket文档_WebSocket推送 原理扫盲到上手实践
??????關于服務端推送技術,大家比較熟悉的可能就是輪詢,但是輪詢只能是由客戶端先發起http請求。在HTTP1.1中的keep-alive方式建立的http連接,但是一個Request只能對應一個Response,而且這個Response是被動的,不能主動發起。
??????為了在IM、股票等場景下,真正解決服務端實時向客戶端推送數據的問題,出現了基于TCP的長連接通訊協議websocket。
????????websocket協議本身需要注意的一共有兩點:
????????1.為了兼容現有瀏覽器的握手規范而借用了HTTP的協議來完成一部分握手。
????????2.websocket是純事件驅動的,一旦連接建立,通過監聽事件可以處理到來的數據和改變的連接狀態,數據都以幀序列的形式傳輸。服務端發送數據后,消息和事件會異步到達。websocket編程遵循一個異步編程模型,只需要對websocket對象增加回調函數就可以監聽事件。
???????下面來具體介紹一下websocket的這兩點特征,先介紹基于回調函數的事件編程:
異步編程模型
如果大家想切身體驗一下websocket,可以自己下載現成demo。地址:https://github.com/sockjs/sockjs-node/tree/v0.3.19(注意:請通過download下載文件的方式下載代碼,不要直接clone,不然代碼版本不一樣)。不過為了更好地實現瀏覽器兼容性,demo中是通過sockjs-node庫來實現websocket協議的底層協議。更多的sockjs的api請進一步參考git網頁中sockjs-node的文檔。
??????本次用來演示的是example文件夾中的koa項目,在代碼中大家可以著重理解上面提到的websocket需要注意的第二點,在代碼中,主要是通過事件回調函數的方式來實現對消息的處理的。
??????在服務器代碼中首先為sockjs_echo變量賦值了一個websocket連接實例,定義接收到消息后的回調函數,即把接收到的message進行回寫。然后啟動了一個koa服務器,當被訪問的時候返回一個index.html文件,作為webSocket的客戶端。最后通過installHandlers方法,在訪問路由/echo的時候為koa服務器增加websocket連接的回調處理。
var?koa?????=?require('koa');var?sockjs??=?require('sockjs');
var?http????=?require('http');
var?fs??????=?require('fs');
var?path????=?require('path');
//?1.?Echo?sockjs?server
var?sockjs_opts?=?{sockjs_url:?"http://cdn.jsdelivr.net/sockjs/1.0.1/sockjs.min.js"};
var?sockjs_echo?=?sockjs.createServer(sockjs_opts);
sockjs_echo.on('connection',?function(conn)?{
????conn.on('data',?function(message)?{
????????conn.write(message);
????});
});
//?2.?koa?server
var?app?=?new?koa();
app.use(function?*()?{
????var?filePath?=?__dirname?+?'/index.html';
????this.type?=?path.extname(filePath);
????this.body?=?fs.createReadStream(filePath);
});
var?server?=?http.createServer(app.callback());
sockjs_echo.installHandlers(server,?{prefix:'/echo'});
server.listen(9999,?'0.0.0.0');
console.log('?[*]?Listening?on?0.0.0.0:9999'?);
??????而在客戶端實現如下,通過sockjs庫實例化websocket連接實例后,通過onopen、onmessage、onclose這些回調函數來實現消息的發送、接收、連接關閉處理:
var?sockjs_url?=?'/echo';var?sockjs?=?new?SockJS(sockjs_url);
sockjs.onopen??=?function()??{print('[*]?open',?sockjs.protocol);};
sockjs.onmessage?=?function(e)?{print('[.]?message',?e.data);};
sockjs.onclose???=?function()??{print('[*]?close');};
form.submit(function()?{
????print('[?]?sending',?inp.val());
????sockjs.send(inp.val());
????inp.val('');
????return?false;
});
借用HTTP協議完成握手
???????啟動koa服務后,我們訪問http://0.0.0.0:9999/打開頁面,可以在瀏覽器network選項卡中觀察到連接的建立過程。在request的header中通過"Connection:Upgrade;Upgrade:websocket"字段表示瀏覽器通知服務器,如果可以,就升級到websocket協議。response中同樣通過"Connection:Upgrade;Upgrade:websocket"來通知瀏覽器,服務端已經成功切換協議,返回狀態碼為101。
??????我們此時可以試著在網頁中輸入一些內容來通過websocket來發送,還是在瀏覽器的Network選項卡中可以看到我們發送的消息和服務端回寫回來的消息:
??????目前我們已經看到了一個簡單的websocket實現,但是在websocket中傳輸的內容是不是還可以更加豐富一些,比如像http協議一樣,添加上各種header字段來讓我們實現出一些更加規范的語義協議?可以的。stomp協議就是這樣的一個語義協議,可以在websocket的基礎之上,通過stomp協議來更加規范地傳輸消息。
官方文檔:http://jmesnil.net/stomp-websocket/doc/
翻譯文檔:https://blog.csdn.net/quanyuejie/article/details/53896140
??????使用了stomp協議在websocket基礎上傳輸消息的效果如下,我們可以看到在websocket的消息中,一個消息可以看作一個frame,每個frame中有自己的command和headers、body。比如在連接幀中發送了"CONNECT"的命令,后面accept-version作為headers來定義版本號,heart-beat來定義心跳等等這些功能,都可以看作是通過stomp協議來實現的:
參考:
JS 服務器推送技術 WebSocket 入門指北??公眾號:前端下午茶
總結
以上是生活随笔為你收集整理的websocket文档_WebSocket推送 原理扫盲到上手实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qq厘米秀在哪里
- 下一篇: java jdbc 删除_java使用j