如何取消订阅socket.io订阅?

Bij*_*lle 57 javascript publish-subscribe socket.io

假设存在对套接字服务器进行订阅的对象,如下所示:

socket.on('news', obj.socketEvent)

这些对象的生命周期很短,并且经常被创建,从而生成许多订阅.这似乎是一个内存泄漏和容易出错的情况,直观地阻止这种情况:

socket.off('news', obj.socketEvent)

在删除对象之前,但唉,off套接字中没有方法.还有另一种方法吗?

编辑:找不到答案我正在指定一个空白方法来覆盖原始事件处理程序的包装器方法,下面是一个示例.

var _blank = function(){};

var cbProxy = function(){
    obj.socketEvent.apply(obj, arguments)
};
var cbProxyProxy = function(){
    cbProxy.apply ({}, arguments)
}
socket.on('news', cbProxyProxy);

// ...and to unsubscribe 
cbProxy = _blank;
Run Code Online (Sandbox Code Playgroud)

And*_*gee 75

从查看socket.io.js的源代码(无法在任何地方的文档中找到它),我发现了这两个函数:

removeListener = function(name, fn)
removeAllListeners = function(name)
Run Code Online (Sandbox Code Playgroud)

removeAllListeners在我的应用中成功使用了; 你应该可以从这些中选择:

socket.removeListener("news", cbProxy);
socket.removeAllListeners("news");
Run Code Online (Sandbox Code Playgroud)

另外,我认为你的解决方案cbProxy = _blank实际上不会起作用; 这只会影响cbProxy变量,而不会影响任何实际的socket.io事件.


小智 30

如果要创建仅在使用时"侦听"的侦听器socket.once('news',func).事件发生后,Socket.io会自动破坏侦听器 - 它被称为"volatile listener".


Pjo*_*otr 22

看看当前版本的Socket.io Client(1.4.8)的代码,似乎off,removeAllListeners,removeEventListener都指向同一个函数.

调用其中任何一个,提供事件名称和/或回调,都会产生所需的结果.根本没有提供任何东西似乎重置了一切.

请注意fn/callback参数.它必须与代码中使用的实例相同.

例:

var eventCallback = function(data) {
  // do something nice
};
socket.off('eventName', eventCallback);
Run Code Online (Sandbox Code Playgroud)

会按预期工作.

示例(也将起作用):

function eventCallback(data) {
  // do something nice
}
socket.off('eventName', eventCallback);
Run Code Online (Sandbox Code Playgroud)

请小心,您要删除的回调是您传入的回调(这可能带来很多混乱和挫折).这个例子实现了一个围绕初始回调的包装器,试图删除那个不起作用,因为添加的真正回调是一个未公开的闭包实例:http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/

以下是代码库中该特定行的链接:https://github.com/socketio/socket.io-client/blob/master/socket.io.js#L1597

  • 这个答案需要更多的赞成票,因为大多数其他答案都不完整和/或极其过时。 (2认同)

小智 5

Socket.io版本0.9.16实现removeListener但不实现off.

您可以使用removeListener而不是off取消订阅,或者只是off按如下方式实现:

  var socket = io.connect(url);
  socket.off = socket.removeListener;
Run Code Online (Sandbox Code Playgroud)

如果您使用Backbone listenTo事件订阅方法,则off在取消订阅事件时,您需要将上述实现为Backbone调用.