前段页面引入这三个文件,主要用来按照protobuf buffer协议解编码protobuf数据。
<script src="../protobuf/long.js"></script>
<script src="../protobuf/bytebuffer.js"></script>
<script src="../protobuf/protobuf.js"></script>
先写一份说明书-proto文件,test.protobuf
package TestProtobuf;
option java_package = "com.why.game.protobuf";
option java_outer_classname = "TestProtobuf";
message TestProto{
optional int32 id = 1;
optional string name = 2;
}
使用库文件加载这个proto文件
var ProtoBuf = dcodeIO.ProtoBuf;
var TestProtobuf = ProtoBuf.loadProtoFile("test.proto").build("TestProtobuf");
//的到里面的message
var TestProto = TestProtobuf.TestProto;
用ajax发送/接收protobuf:
xhr.onreadystatechange = function(){
if (xhr.readyState == 4 && xhr.status == 200) {
var data = xhr.responseText;
//解码protobuf
var protobufResp = TestProto.decode(str2bytes(data));
var jsonResp = JSON.stringify(protobufResp);
console.log(jsonResp);
}
};
//实例化一个TestProto
var testProto = new TestProto({
id:10014,
name:"testProtoName测试987"
});
//编码发送
xhr.send(testProto.toBuffer())
使用XMLHttpRequest对象的send方法发送经由TestProto编码(encode)后的buffer数组(本质也是二进制字节流),
接收的时候同样使用TestProto解码(decode)接收到的二进制数据
这里因为浏览器会把Ajax返回的二进制数据当做文本数据,所以写个str2bytes方法把接收到的文本数据按字节一个个做与运算来还原成二进制byte
function str2bytes(str){
var bytes = [];
for (var i = 0, len = str.length; i < len; ++i) {
var c = str.charCodeAt(i);
var byte = c & 0xff;
bytes.push(byte);
}
return bytes;
}
----------------------------------------------------------分割线-----------------------------------------------------------------------------
使用socketio:
客户端
<script type="text/javascript" src="socket.io.js"></script>
//写个example.
proto
//注意这个message是关键字
message Message {
required string text = 1;
}
//客户端js
var ProtoBuf = dcodeIO.ProtoBuf; var Message = ProtoBuf.loadProtoFile("./example.proto").build("Message"); var log = {
value:''
} // socket链接服务器 var socket = io.connect("http://localhost:3000"); socket.on("connect", function () { log.value += "Connected\n"; }); socket.on("disconnect", function () { log.value += "Disconnected\n"; }); socket.on("message", function (message) { try{
//解析服务端数据 var msg = Message.decode(message); log.value += "Received: " + msg.text + "\n"; }catch(err){ log.value += "Error: " + err + "\n"; } }); function send() { if (socket.connected) {
//向服务端发送数据 var msg = new Message({text:3}); socket.send(msg.toBuffer()); log.value += "Sent: " + msg.text + "\n"; } else { log.value += "Not connected\n"; } }
//服务端nodejs部分:
同样需要
protobufjs
var server = http.createServer(function(request, response){ var filePath = false; if(request.url == "/"){ filePath = "index.html"; }else if(request.method === "POST"){ if(request.url.indexOf("protobuf") != -1){ //BufferHelper参考链接 http://www.infoq.com/cn/articles/nodejs-about-buffer/ var bufferHelper = new BufferHelper(); request.on("data", function (chunk) { bufferHelper.concat(chunk); }); request.on("end", function () { var buffer = bufferHelper.toBuffer(); var testProtoData = TestProto.decode(buffer); response.writeHead(200, {"Content-Type": "application/x-protobuf"}); response.end(testProtoData.toBuffer()); }); } return; }else{ filePath = request.url; } var absPath = webRoot+filePath; serveStatic(response, cache, absPath); });
var ProtoBuf = require("protobufjs"); var socketio = require("socket.io"); // Initialize from .proto file var builder = ProtoBuf.loadProtoFile(path.join(__dirname, "www", "example.proto")), Message = builder.build("Message"); // SocketIO adapter var io = socketio.listen(server); io.set("log level", 1); io.sockets.on("connection", function(socket){ console.log(socket.id+" connecting..."); socket.on("disconnect", function() { console.log("WebSocket disconnected"); }); socket.on("message", function(data) { try { // Decode the Message var msg = Message.decode(data); console.log("Received: "+msg.text); // Transform the text to upper case msg.text = msg.text.toUpperCase(); // Re-encode it and send it back socket.send(msg.toBuffer()); //socket.emit('message', msg.toBuffer()); console.log("Sent: "+msg.text); } catch (err) { console.log("Processing failed:", err); } }); });ok