本文主要介紹express+websocket的使用
WebSocket
WebSocket 協(xié)議在2008年誕生库菲,2011年成為國(guó)際標(biāo)準(zhǔn)。所有瀏覽器都已經(jīng)支持了菠齿。
它的最大特點(diǎn)就是佑吝,服務(wù)器可以主動(dòng)向客戶端推送信息,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息绳匀,是真正的雙向平等對(duì)話芋忿,屬于服務(wù)器推送技術(shù)的一種炸客。
其他特點(diǎn)包括:
(1)建立在 TCP 協(xié)議之上,服務(wù)器端的實(shí)現(xiàn)比較容易戈钢。
(2)與 HTTP 協(xié)議有著良好的兼容性痹仙。默認(rèn)端口也是80和443,并且握手階段采用 HTTP 協(xié)議殉了,因此握手時(shí)不容易屏蔽开仰,能通過各種 HTTP 代理服務(wù)器。
(3)數(shù)據(jù)格式比較輕量薪铜,性能開銷小众弓,通信高效。
(4)可以發(fā)送文本隔箍,也可以發(fā)送二進(jìn)制數(shù)據(jù)谓娃。
(5)沒有同源限制,客戶端可以與任意服務(wù)器通信鞍恢。
(6)協(xié)議標(biāo)識(shí)符是ws(如果加密傻粘,則為wss)每窖,服務(wù)器網(wǎng)址就是 URL帮掉。
ws://example.com:80/some/path
Express+WebSocket實(shí)現(xiàn)
依賴庫(kù):express-ws
1. 創(chuàng)建一個(gè)express project
通過express直接創(chuàng)建一個(gè)express template工程,或者通過express-ts-template創(chuàng)建一個(gè)express typescript工程窒典,以下主要介紹在express-ts-template中的使用蟆炊。
在package.json文件中,添加對(duì)express-ws和@types/express-ws的依賴
"devDependencies": {
"typescript": "^2.3.4",
"@types/node": "^7.0.22",
"@types/express": "^4.0.35",
"@types/body-parser": "~1.16.3",
"@types/cookie-parser": "~1.3.30",
"@types/debug": "~0.0.29",
"@types/morgan": "~1.7.22",
"@types/serve-favicon": "~2.2.28",
"@types/jade": "~0.0.30",
"@types/ws":"3.0.0"
},
"dependencies": {
"body-parser": "~1.15.2",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"express": "~4.14.0",
"jade": "~1.11.0",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0",
"express-ws": "~3.0.0"
},
2. 創(chuàng)建wsRouter
在routers目錄創(chuàng)建一個(gè)wsRouter.ts文件瀑志,用于定義ws的router涩搓。 在內(nèi)部定義了WSRouter類,并使用單例模式通過init方法創(chuàng)建劈猪,保證ws只初始化一次昧甘。如下:
/**
* WebSocket router
*/
import * as express from 'express';
import * as expressWS from 'express-ws';
var wsRouter = null;
class WSRouter {
public server = null;
public app :express.Express = null;
public clients = [];
constructor(server) {
this.server = server;
this.app = express();
expressWS(this.app, this.server);
}
/**
* 接受client端連接
*/
public lintenClientConnect() {
var me = this;
this.app.ws('/', function(ws, req) {
console.log("client connect to server successful!");
me.clients.push(ws);
ws.on('message', function(msg) {
console.log("receive client msg :", msg);
me.receiveCmd(msg);
});
ws.on("close", function(msg){
console.log("client is closed");
for(var index = 0; index < me.clients.length; index++){
if(me.clients[index] == this){
me.clients.splice(index, 1)
}
}
});
});
}
/**
* 發(fā)送command到client端
* @param msg
* @param cb
*/
public sendCmd(msg:string, cb){
}
/**
* 接收client的command請(qǐng)求
* @param cmd
*/
public receiveCmd(cmd){
}
}
export function init(server?:any){
if(wsRouter == null && server != null){
wsRouter = new WSRouter(server);
}
return wsRouter;
}
3. 引用wsRouter
在bin/www中添加對(duì)wsRouter的引用,并初始化
.....
var server = http.createServer(app);
/**
* create ws server
*/
const WSRouter = require('./../dist/routes/wsRouter.js');
var wsRouter = WSRouter.init(server);
wsRouter.lintenClientConnect();
.....
測(cè)試
1. 在project目錄執(zhí)行npm start 啟動(dòng)server
2. 在chrome的F12 consle中輸入連接:
var ws = new WebSocket("ws://127.0.0.1:3000");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
3. 結(jié)果查看
chrome中信息
npm控制臺(tái)信息
測(cè)試通過
測(cè)試源碼:express-ws-example