NodeJs使用nodejs-websocket + protobuf

參考:html

HTML5+NodeJs實現WebSocket即時通信 (某人的blog)node

nodejs-websocket使用示例  (www.npmjs.com網站,有示例)web

Buffer API (nodejs api 中文版)npm

 

nodejs-websocket + protobufjsjson

 

 

 一 安裝nodejs-websocket

在服務端項目文件夾下,新建一個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文件夾併發

 

  

二 安裝protobufjs

在服務端項目文件夾下shift+右鍵,在此處打開命令窗口,輸入socket

npm install protobufjs

 

輸入後回車,等待安裝完畢,以下圖:測試

 

三 準備測試用.proto文件

準備一個測試用的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來拼接數據。

相關文章
相關標籤/搜索