Sails.js socket.io protobuf.js encoded message causes error: "Illegal buffer" on decode in browser
Sails.js socket.io protobuf.js encoded message causes error: "Illegal buffer" on decode in browser
我正在向 this 示例添加 protobuf 消息加密。
为此我有:
Chat.proto
package Chat;
message Message{
required string user = 1;
optional string message = 2;
optional string id = 3;
}
ChatController.js:
...
var builder = ProtoBuf.loadProtoFile(require('path').resolve(sails.config.appPath, "assets/proto/Chat.proto")),
Message = builder.build("Chat").Message;
var encodeMessage = function (message) {
"use strict";
sails.log.info("WILL ENCODE", message);
var msg = new Message(message);
sails.log.info("ENCODED", msg);
return msg;
};
module.exports = {
addConv: function (req, res) {
var data_from_client = req.params.all();
if (req.isSocket && req.method === 'POST') {
// This is the new message
Chat.create(data_from_client).exec(function (err, data_from_client){
Chat.publishCreate({ id: (data_from_client.id),
// I encode only on sending from server
data : encodeMessage({
message: data_from_client.message,
user: data_from_client.user }).toBuffer()
});
});
}
else if (req.isSocket) {
Chat.watch(req.socket);
sails.log.info('USER SUBSCRIBED TO ' + req.socket.id);
}
}
};
前端 和 socketApp.js:
...
ProtoBuf.loadProtoFile("/proto/Chat.proto", function (err, builder) {
Chat = builder.build("Chat"),
Message = Chat.Message;
});
socketApp.controller('ChatController', ['$http', '$log', '$scope', function ($http, $log, $scope) {
var decodeMessage = function (message) {
console.log("WILL DECODE", message);
var msg = Message.decode(message); //Line 23 !Here goes the error!
console.log("DECODED", msg);
return msg;
};
...
io.socket.on('chat', function (obj, keys) {
console.log('chat', obj, keys); //Says that object is: {id: 41, data: ArrayBuffer}
if (obj.verb === 'created') {
console.log(decodeMessage(obj.data));
$scope.chatList.push(decodeMessage(obj.data));
$scope.$digest();
}
});
$scope.sendMsg = function () {
...
};
}]);
每次客户端从服务器获取编码消息时我都会遇到错误:
Uncaught TypeError: Illegal bufferByteBuffer.wrap @ ByteBufferAB.js:390
ProtoBuf.Reflect.MessagePrototype.build.Message.decode @ ProtoBuf.js:2904
decodeMessage @ socketApp.js:23
(anonymous function) @ socketApp.js:56
u.8.Emitter.emit @ sails.io.js:3
u.5.Socket.onevent @ sails.io.js:3
u.5.Socket.onpacket @ sails.io.js:3
u.7.module.exports @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.3.Manager.ondecoded @ sails.io.js:3
u.7.module.exports @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.43.Decoder.add @ sails.io.js:5
u.3.Manager.ondata @ sails.io.js:3
u.7.module.exports @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.12.Socket.onPacket @ sails.io.js:3
(anonymous function) @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.13.Transport.onPacket @ sails.io.js:3
u.13.Transport.onData @ sails.io.js:3
u.18.WS.addEventListeners.ws.onmessage @ sails.io.js:4
怎么了?我怎样才能使这项工作?
sails-hook-sockets on receiving data by socket and providing it to other middlewares uses lodash's _.extend
: See here: body : _.extend({}, options.incomingSailsIOMsg.params || {}, options.incomingSailsIOMsg.data || {}),
,我希望在其他几个地方。以某种方式扩展刹车 ArrayBuffer。
所以我发现的唯一方法是在 sails-hook-sockets 处理之前反序列化消息。所以我可以在服务的某个地方写:
ProtoDeserializationService:
ProtoBuf.loadProtoFile("/proto/Chat.proto", function (err, builder) {
Chat = builder.build("Chat"), Message = Chat.Message;;
sails.io.on('connect', function (socket) {
var _onevent = socket.onevent;
sails.log.silly("socket_protobuf: Overriding socket.io onevent method to support deserialization of incoming message");
/**
* Overriden socket.io onevent metod that receives packages
*
* If `packet.data.data` field contains fields `protobuf` and `model` then it should be deserialized according to Protocol Buffers message scheme with name stored in `model`.
*
* @param {Object} packet received data
*/
socket.onevent = function (packet) {
sails.log.silly("socket_protobuf: onevent");
var args = packet.data || [],
data = args[1].data || args[1],
protobuf = data.protobuf || null,
model = data.model|| null;
if (protobuf && model) {
_.extend(data, Message.decode(protobuf));
delete data.protobuf;
delete data.model;
}
_onevent.call(this, packet);
};
});
但我写了更通用的解决方案:hook to be able to serialize protocol buffer messages on both plain socket.io requests and sails.socket.io Pub/Sub。
我正在向 this 示例添加 protobuf 消息加密。
为此我有:
Chat.proto
package Chat;
message Message{
required string user = 1;
optional string message = 2;
optional string id = 3;
}
ChatController.js:
...
var builder = ProtoBuf.loadProtoFile(require('path').resolve(sails.config.appPath, "assets/proto/Chat.proto")),
Message = builder.build("Chat").Message;
var encodeMessage = function (message) {
"use strict";
sails.log.info("WILL ENCODE", message);
var msg = new Message(message);
sails.log.info("ENCODED", msg);
return msg;
};
module.exports = {
addConv: function (req, res) {
var data_from_client = req.params.all();
if (req.isSocket && req.method === 'POST') {
// This is the new message
Chat.create(data_from_client).exec(function (err, data_from_client){
Chat.publishCreate({ id: (data_from_client.id),
// I encode only on sending from server
data : encodeMessage({
message: data_from_client.message,
user: data_from_client.user }).toBuffer()
});
});
}
else if (req.isSocket) {
Chat.watch(req.socket);
sails.log.info('USER SUBSCRIBED TO ' + req.socket.id);
}
}
};
前端 和 socketApp.js:
...
ProtoBuf.loadProtoFile("/proto/Chat.proto", function (err, builder) {
Chat = builder.build("Chat"),
Message = Chat.Message;
});
socketApp.controller('ChatController', ['$http', '$log', '$scope', function ($http, $log, $scope) {
var decodeMessage = function (message) {
console.log("WILL DECODE", message);
var msg = Message.decode(message); //Line 23 !Here goes the error!
console.log("DECODED", msg);
return msg;
};
...
io.socket.on('chat', function (obj, keys) {
console.log('chat', obj, keys); //Says that object is: {id: 41, data: ArrayBuffer}
if (obj.verb === 'created') {
console.log(decodeMessage(obj.data));
$scope.chatList.push(decodeMessage(obj.data));
$scope.$digest();
}
});
$scope.sendMsg = function () {
...
};
}]);
每次客户端从服务器获取编码消息时我都会遇到错误:
Uncaught TypeError: Illegal bufferByteBuffer.wrap @ ByteBufferAB.js:390
ProtoBuf.Reflect.MessagePrototype.build.Message.decode @ ProtoBuf.js:2904
decodeMessage @ socketApp.js:23
(anonymous function) @ socketApp.js:56
u.8.Emitter.emit @ sails.io.js:3
u.5.Socket.onevent @ sails.io.js:3
u.5.Socket.onpacket @ sails.io.js:3
u.7.module.exports @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.3.Manager.ondecoded @ sails.io.js:3
u.7.module.exports @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.43.Decoder.add @ sails.io.js:5
u.3.Manager.ondata @ sails.io.js:3
u.7.module.exports @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.12.Socket.onPacket @ sails.io.js:3
(anonymous function) @ sails.io.js:3
u.8.Emitter.emit @ sails.io.js:3
u.13.Transport.onPacket @ sails.io.js:3
u.13.Transport.onData @ sails.io.js:3
u.18.WS.addEventListeners.ws.onmessage @ sails.io.js:4
怎么了?我怎样才能使这项工作?
sails-hook-sockets on receiving data by socket and providing it to other middlewares uses lodash's _.extend
: See here: body : _.extend({}, options.incomingSailsIOMsg.params || {}, options.incomingSailsIOMsg.data || {}),
,我希望在其他几个地方。以某种方式扩展刹车 ArrayBuffer。
所以我发现的唯一方法是在 sails-hook-sockets 处理之前反序列化消息。所以我可以在服务的某个地方写:
ProtoDeserializationService:
ProtoBuf.loadProtoFile("/proto/Chat.proto", function (err, builder) {
Chat = builder.build("Chat"), Message = Chat.Message;;
sails.io.on('connect', function (socket) {
var _onevent = socket.onevent;
sails.log.silly("socket_protobuf: Overriding socket.io onevent method to support deserialization of incoming message");
/**
* Overriden socket.io onevent metod that receives packages
*
* If `packet.data.data` field contains fields `protobuf` and `model` then it should be deserialized according to Protocol Buffers message scheme with name stored in `model`.
*
* @param {Object} packet received data
*/
socket.onevent = function (packet) {
sails.log.silly("socket_protobuf: onevent");
var args = packet.data || [],
data = args[1].data || args[1],
protobuf = data.protobuf || null,
model = data.model|| null;
if (protobuf && model) {
_.extend(data, Message.decode(protobuf));
delete data.protobuf;
delete data.model;
}
_onevent.call(this, packet);
};
});
但我写了更通用的解决方案:hook to be able to serialize protocol buffer messages on both plain socket.io requests and sails.socket.io Pub/Sub。