參考:html
HTML5+NodeJs實現WebSocket即時通信 (某人的blog)node
nodejs-websocket使用示例 (www.npmjs.com網站,有示例)web
Buffer API (nodejs api 中文版)npm
nodejs-websocket + protobufjsjson
在服務端項目文件夾下,新建一個pageage.jsonapi
{ "name": "realtime-server", "version": "0.0.1", "description": "my first realtime server", "dependencies": { "nodejs-websocket": "^1.7.2", "protobufjs": "^6.8.8" } }
在服務端項目文件夾下shift+右鍵,在此處打開命令窗口,輸入websocket
npm install nodejs-websocket
安裝完畢後,項目目錄下會增長node_modules文件夾併發
在服務端項目文件夾下shift+右鍵,在此處打開命令窗口,輸入socket
npm install protobufjs
輸入後回車,等待安裝完畢,以下圖:測試
準備一個測試用的proto文件,以下
login.proto
//登陸 package login; //登陸請求 message LoginReq{ required int32 uid = 1; //用戶id }
服務端鏈接成功後,等待接收。 若是接收到登陸請求,則解析loginReq,而後返回一個loginReq。
var ws = require("nodejs-websocket"); var protobufjs = require("protobufjs"); var root = protobufjs.loadSync("./login.proto"); console.log("開始建立websocket"); var server = ws.createServer(function(conn){ console.log("鏈接成功"); conn.on("binary", function (inStream) { console.log("接收消息"); var data; inStream.on("readable", function () { data = inStream.read(); }) inStream.on("end", function () { console.log("Received " + data.length + " bytes of binary data"); //解析接收的數據,cmd var cmd = data.readUInt16BE(0); console.log("接收數據的cmd:",cmd); let bytes = Buffer.from(data,1); //解析接收的數據,loginReq var LoginReq = root.lookupType("login.LoginReq"); var loginReq = LoginReq.decode(bytes); console.log("接收數據的uid:", loginReq.uid); //發送的數據,loginReq var sendLoginReq = LoginReq.create(); sendLoginReq.uid = 123; var sendData = LoginReq.encode(sendLoginReq).finish(); //發送的數據,cmd var sendBuffer = Buffer.alloc(2); sendBuffer.writeInt16BE(100); //拼接數據併發送 var totalBuffer = Buffer.concat([sendBuffer,sendData],sendData.length + sendBuffer.length); conn.sendBinary(totalBuffer); }) }) conn.on("close", function (code, reason) { console.log("關閉鏈接") }); conn.on("error", function (code, reason) { console.log("異常關閉") }); }).listen(8001) console.log("開始建立websocket完畢");
客戶端請求鏈接服務端,鏈接成功後發送登陸請求loginReq
/**鏈接成功*/ private onConnect(e:egret.Event){ console.log("ClientSocket 鏈接成功"); this.resetReconnect(); App.EventMananger.sendEvent(ClientSocket.SOCKET_CONNECT); //測試 let loginData:login.LoginReq = new login.LoginReq(); loginData.uid = 123; let buffer = login.LoginReq.encode(loginData).finish(); this.send(100, buffer); } /** * 發送數據 * @param cmd 數據協議 * @param sendByte 發送的數據 */ public send(cmd:number, sendByte:Uint8Array){ console.log("ClientSocket 發送:",cmd); //發送的數據cmd+proto let sendByteArray = new egret.ByteArray(sendByte); let byteArray:egret.ByteArray = new egret.ByteArray(); byteArray.writeUnsignedShort(cmd); byteArray.writeBytes(sendByteArray); //發送 this.socket.writeBytes(byteArray); this.socket.flush(); } /**接收數據*/ private onReceive(e:egret.Event){ //讀取socket數據 var byte:egret.ByteArray = new egret.ByteArray(); this.socket.readBytes(byte); //讀取cmd+proto let cmd:number = byte.readUnsignedShort(); console.log("接收數據,cmd:",cmd); //讀取loginReq let revByteArray:egret.ByteArray = new egret.ByteArray(); byte.readBytes(revByteArray); let buffer:login.LoginReq = login.LoginReq.decode(revByteArray.bytes); console.log("接收數據,uid:",buffer.uid); }
運行服務端和客戶端
1. 客戶端請求鏈接服務端
2. 鏈接成功後,客戶端發送登陸請求loginReq
3. 服務端接收到登陸請求,解析loginReq並打印。 而後再返回一個loginReq。
4. 客戶端接收到服務端返回的loginReq,解析並打印。
服務端輸出:
客戶端輸出:
到此,一個簡單的nodejs-websocket + protobufjs服務單搭建和聯調測試完成。
一 nodejs服務端關於Buffer的操做
看了一下Buffer的Api,沒有找到writeBytes的方法,只有concat來拼接數據。