websocket文档_WebSocket推送 原理扫盲到上手实践
??????關(guān)于服務(wù)端推送技術(shù),大家比較熟悉的可能就是輪詢(xún),但是輪詢(xún)只能是由客戶(hù)端先發(fā)起http請(qǐng)求。在HTTP1.1中的keep-alive方式建立的http連接,但是一個(gè)Request只能對(duì)應(yīng)一個(gè)Response,而且這個(gè)Response是被動(dòng)的,不能主動(dòng)發(fā)起。
??????為了在IM、股票等場(chǎng)景下,真正解決服務(wù)端實(shí)時(shí)向客戶(hù)端推送數(shù)據(jù)的問(wèn)題,出現(xiàn)了基于TCP的長(zhǎng)連接通訊協(xié)議websocket。
????????websocket協(xié)議本身需要注意的一共有兩點(diǎn):
????????1.為了兼容現(xiàn)有瀏覽器的握手規(guī)范而借用了HTTP的協(xié)議來(lái)完成一部分握手。
????????2.websocket是純事件驅(qū)動(dòng)的,一旦連接建立,通過(guò)監(jiān)聽(tīng)事件可以處理到來(lái)的數(shù)據(jù)和改變的連接狀態(tài),數(shù)據(jù)都以幀序列的形式傳輸。服務(wù)端發(fā)送數(shù)據(jù)后,消息和事件會(huì)異步到達(dá)。websocket編程遵循一個(gè)異步編程模型,只需要對(duì)websocket對(duì)象增加回調(diào)函數(shù)就可以監(jiān)聽(tīng)事件。
???????下面來(lái)具體介紹一下websocket的這兩點(diǎn)特征,先介紹基于回調(diào)函數(shù)的事件編程:
異步編程模型
如果大家想切身體驗(yàn)一下websocket,可以自己下載現(xiàn)成demo。地址:https://github.com/sockjs/sockjs-node/tree/v0.3.19(注意:請(qǐng)通過(guò)download下載文件的方式下載代碼,不要直接clone,不然代碼版本不一樣)。不過(guò)為了更好地實(shí)現(xiàn)瀏覽器兼容性,demo中是通過(guò)sockjs-node庫(kù)來(lái)實(shí)現(xiàn)websocket協(xié)議的底層協(xié)議。更多的sockjs的api請(qǐng)進(jìn)一步參考git網(wǎng)頁(yè)中sockjs-node的文檔。
??????本次用來(lái)演示的是example文件夾中的koa項(xiàng)目,在代碼中大家可以著重理解上面提到的websocket需要注意的第二點(diǎn),在代碼中,主要是通過(guò)事件回調(diào)函數(shù)的方式來(lái)實(shí)現(xiàn)對(duì)消息的處理的。
??????在服務(wù)器代碼中首先為sockjs_echo變量賦值了一個(gè)websocket連接實(shí)例,定義接收到消息后的回調(diào)函數(shù),即把接收到的message進(jìn)行回寫(xiě)。然后啟動(dòng)了一個(gè)koa服務(wù)器,當(dāng)被訪(fǎng)問(wèn)的時(shí)候返回一個(gè)index.html文件,作為webSocket的客戶(hù)端。最后通過(guò)installHandlers方法,在訪(fǎng)問(wèn)路由/echo的時(shí)候?yàn)閗oa服務(wù)器增加websocket連接的回調(diào)處理。
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'?);
??????而在客戶(hù)端實(shí)現(xiàn)如下,通過(guò)sockjs庫(kù)實(shí)例化websocket連接實(shí)例后,通過(guò)onopen、onmessage、onclose這些回調(diào)函數(shù)來(lái)實(shí)現(xiàn)消息的發(fā)送、接收、連接關(guān)閉處理:
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協(xié)議完成握手
???????啟動(dòng)koa服務(wù)后,我們?cè)L問(wèn)http://0.0.0.0:9999/打開(kāi)頁(yè)面,可以在瀏覽器network選項(xiàng)卡中觀(guān)察到連接的建立過(guò)程。在request的header中通過(guò)"Connection:Upgrade;Upgrade:websocket"字段表示瀏覽器通知服務(wù)器,如果可以,就升級(jí)到websocket協(xié)議。response中同樣通過(guò)"Connection:Upgrade;Upgrade:websocket"來(lái)通知瀏覽器,服務(wù)端已經(jīng)成功切換協(xié)議,返回狀態(tài)碼為101。
??????我們此時(shí)可以試著在網(wǎng)頁(yè)中輸入一些內(nèi)容來(lái)通過(guò)websocket來(lái)發(fā)送,還是在瀏覽器的Network選項(xiàng)卡中可以看到我們發(fā)送的消息和服務(wù)端回寫(xiě)回來(lái)的消息:
??????目前我們已經(jīng)看到了一個(gè)簡(jiǎn)單的websocket實(shí)現(xiàn),但是在websocket中傳輸?shù)膬?nèi)容是不是還可以更加豐富一些,比如像http協(xié)議一樣,添加上各種header字段來(lái)讓我們實(shí)現(xiàn)出一些更加規(guī)范的語(yǔ)義協(xié)議?可以的。stomp協(xié)議就是這樣的一個(gè)語(yǔ)義協(xié)議,可以在websocket的基礎(chǔ)之上,通過(guò)stomp協(xié)議來(lái)更加規(guī)范地傳輸消息。
官方文檔:http://jmesnil.net/stomp-websocket/doc/
翻譯文檔:https://blog.csdn.net/quanyuejie/article/details/53896140
??????使用了stomp協(xié)議在websocket基礎(chǔ)上傳輸消息的效果如下,我們可以看到在websocket的消息中,一個(gè)消息可以看作一個(gè)frame,每個(gè)frame中有自己的command和headers、body。比如在連接幀中發(fā)送了"CONNECT"的命令,后面accept-version作為headers來(lái)定義版本號(hào),heart-beat來(lái)定義心跳等等這些功能,都可以看作是通過(guò)stomp協(xié)議來(lái)實(shí)現(xiàn)的:
參考:
JS 服務(wù)器推送技術(shù) WebSocket 入門(mén)指北??公眾號(hào):前端下午茶
總結(jié)
以上是生活随笔為你收集整理的websocket文档_WebSocket推送 原理扫盲到上手实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: qq厘米秀在哪里
- 下一篇: 打开win7系统事件查看器的四种方法