首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sails.js socket.io protobuf.js编码消息导致错误:浏览器解码上的“非法缓冲区”

Sails.js socket.io protobuf.js编码消息导致错误:浏览器解码上的“非法缓冲区”
EN

Stack Overflow用户
提问于 2015-10-09 13:40:50
回答 1查看 922关注 0票数 2

我正在向示例中添加protobuf消息请求。

为此,我有:

Chat.proto

代码语言:javascript
复制
package Chat;

message Message{
    required string user = 1;
    optional string message = 2;
    optional string id = 3;

}

ChatController.js:

代码语言:javascript
复制
...
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:

代码语言:javascript
复制
...
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 () {
        ...
    };
}]);

每次客户端从服务器获得编码消息时,我都会得到一个错误:

代码语言:javascript
复制
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

怎么了?我怎么才能把这事做好?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-09 08:09:16

在通过套接字接收数据并将其提供给其他中间件时,帆.钩座使用_.extend:请参阅这里body : _.extend({}, options.incomingSailsIOMsg.params || {}, options.incomingSailsIOMsg.data || {}),,我希望在其他地方也是如此。以某种方式延长刹车ArrayBuffer。

因此,我发现的唯一方法是在sails-hook-sockets处理消息之前反序列化消息。这样我就可以在服务中写到:

ProtoDeserializationService

代码语言:javascript
复制
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);
        };
    });

但我已经编写了更通用的解决方案:一个能够在普通的socket.io请求和sails.socket.io 酒吧/Sub上序列化协议缓冲区消息的sails.socket.io。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33039819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档