背景
服務(wù)端WebSocket + Protobuf + 大報(bào)頭(Big-Endian)
客戶端Web環(huán)境偿荷,JS實(shí)現(xiàn)WS對(duì)接
生成JS版本的Proto
在放置proto的目錄下執(zhí)行
protoc --js_out=import_style=commonjs:./ --plugin=protoc-gen-grpc=./protoc-gen-grpc-web.exe --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./ *.proto
說明:
- protoc-gen-grpc-web.exe需要去官方下載最新版本
- 服務(wù)端需要另外提供一套msg_id的對(duì)應(yīng)js文件
Web客戶端安裝google-protobuf依賴
npm install google-protobuf --save
客戶端需要的文件
連接WS
let wsUri = "ws://127.0.0.1:3658/"
let ws = new WebSocket(wsUri)
ws.binaryType = "arraybuffer" //proto通訊一定要用這個(gè)配置
消息發(fā)送函數(shù)
function doSend(msgID, bytes) {
var buffer = new ArrayBuffer(bytes.length + 2); // 前兩位留給msgID
var view = new DataView(buffer);
view.setUint16(0, msgID);
for (var i = 0; i < bytes.length; i++) {
view.setUint8(i + 2, bytes[i]);
}
ws.send(view);
}
以登錄舉例
let loginMsg = new login_msg.RequestLogin()
loginMsg.setToken("6f35691ccb516ee6c15f1da4427c8d7a")
doSend(login_msg_id.proto_msg.RequestLogin, loginMsg.serializeBinary())
接受消息
function onMessage(evt) {
let ret = loadMsg(evt.data)
}
function loadMsg(data) {
const msgId = view.getUint16(0) // 前兩個(gè)byte是MessagID
const msgName = msgDefine.msg_map[msgId]
const protoMsg = proto[msgName]
const ret = protoMsg.deserializeBinary(data)
return protoMsg.toObject(false, ret)
}