【问题标题】:Can the socket.io client emit events locally?socket.io 客户端可以在本地发出事件吗?
【发布时间】:2014-12-07 02:01:10
【问题描述】:

是否可以使用 socket.io 将事件分派给客户端而不发送给服务器?比如:

socket.emitLocally('some event', data);

这就是我要问的原因:

目前我的服务器向所有套接字发出事件。

io.sockets.emit()

虽然这很有效,但用户交互和服务器响应之间可能存在延迟。

这就是为什么我更喜欢在服务器端使用广播并在广播客户端中立即处理事情的原因。

socket.broadcast.emit()

客户端基于 angular.js,模块之间互不相识。我无法访问负责直接更新客户端的代码。我将不得不使用某种事件调度服务,将其注入相关模块。

因为这基本上是what I am doing with socket.io right now 我想知道我是否不能简单地使用他们的系统来做到这一点。

感谢您的任何意见或建议!

【问题讨论】:

  • 那么,您希望客户端向自己发送消息而不是向其他任何人发送消息?
  • @jfriend00 是的,但没有实际发送消息(到服务器并返回)。如果消息已发送到客户端,我只想触发将被调度的事件。这有意义吗? ;)
  • 好的,我想我遵循你的愿望,但我不知道 socket.io 中有任何功能可以做到这一点。

标签: javascript node.js angularjs socket.io


【解决方案1】:

这可以按照函数 Emitter.prototype.emit 上的 socket.io 客户端代码所示完成。

事件保存在socket._callbacks 上,前缀为$,因此例如"connected" 将在_callbacks 下作为"$connected"

您可以使用以下方法复制所述功能的行为:

// You can use internal (e.g. disconnected) or custom events (e.g. ChatMessage).
var event = "MyEvent";
// Set your args exactly as in your socket.io server emit.
// Note that they will be used on an apply so they must be within an array.
var args = [1, 2, 3];

if(socket._callbacks) { // If the socket has callbacks
    var callbacks = socket._callbacks['$' + event]; // Load the callback event
    if (callbacks) {
        callbacks = callbacks.slice(0);
        for (var i = 0, len = callbacks.length; i < len; ++i)
          callbacks[i].apply(socket, args);
    } // Otherwise no calls
}

在上面的示例中,“MyEvent”的回调将使用参数 1、2、3 调用。

关于如何在实际连接中使用它的进一步示例:

io.on('connection', function (socket) {
    socket.on("getSingleUpdate", function(id, data){
        alert("Event #"+id+" data "+data);
    });

    function emitLocalEvent(event/*, arg1, arg2, etc.*/) {
        if(socket._callbacks) { 
            var args = [].slice.call(arguments, 1),
                callbacks = socket._callbacks['$' + event];
            if (callbacks) {
                callbacks = callbacks.slice(0);
                for (var i = 0, len = callbacks.length; i < len; ++i)
                  callbacks[i].apply(socket, args);
            }
        }
    }

    // Emitting fake events
    emitLocalEvent("getSingleUpdate", 1, "Hello");
    emitLocalEvent("getSingleUpdate", 2, "World!");

    // You can even receive an array of events via socket.io...
    socket.on("getMultipleEvents", function(eventArray) {
        for(var i in eventArray)
            emitLocalEvent.apply(null, eventArray[i]);
    });
});

【讨论】:

    【解决方案2】:

    假设您在客户端使用捕获事件

    io.on("name",callback);
    

    你可以打电话

    callback();
    

    希望我能帮上忙! =)

    【讨论】:

    • 我的例子有点太简单了。你当然是对的,在一个简单的例子中,我可以打电话给听众。不过,我问这个问题的原因是,我使用 socket.io 作为集中式事件中心。所以我永远无法确定我的应用程序的哪些部分会监听它接收到的事件。在向服务器发送事件时调用所有侦听器可能会变得非常混乱,在某些情况下甚至可能无法实现。所以,不幸的是,这并不能解决我的问题。
    • TBH,我真的不明白您如何拥有一个使用io.on 从服务器接收消息的系统,但您不知道回调是什么。你能详细说明一下吗?
    • 我不知道使用io.emit时的回调是什么。但我确实知道如果一切顺利,我的客户会收到哪个事件。例如:一个 Angular 应用程序具有三个完全独立的模块:一个用于在每次添加消息时显示类似 Toast 的通知,一个用于在屏幕左侧列出聊天室并计算未读消息,另一个用于列出屏幕右侧所选聊天的消息。 (在下一条评论中继续......)
    • (...接上一条评论...)所有这些模块都对新消息的事件感兴趣。他们都听io.on("new message",fn) 修改他们在生命周期开始时下载的数据快照。 -- 对于发送新消息的客户端,我希望这些更改是即时的(在单击之后)。但是调用io.emit发送新消息的模块不可能知道其他模块的回调。
    • 请原谅我,但我仍然不明白你怎么可能不知道回调是什么。能否请您添加一个小代码示例?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 2020-02-17
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    相关资源
    最近更新 更多