ConnectionManager.onChannelMessage() 收到的消息具有不同的 connectionSerial,但与之前的消息 ID 相同;丢弃
ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding
将 Ably Realtime 用于基于 Web 的预订系统。
我在 js 控制台中不断收到一些错误,尽管一切正常。
基本上,有一个日期选择器,当访问者选择一个日期时,我将全局变量 day
设置为日期(类似于 2018-05-25
)并调用 VisitorMessages.start()
,为他们订阅消息并让他们出现在频道 visitor:2018-05-25
上,并从所有其他频道取消订阅他们。
我还有一个 visitor:all
频道,每个人都可以在该频道上收到消息,不需要在场。
这是我正在做的(请原谅 CoffeeScript):
VisitorMessages =
realtime: null
connected_first_time: false
start: ->
unless @realtime
@realtime = new Ably.Realtime
authUrl: '/auth'
recover: (lastConnectionDetails, cb) ->
cb(true)
return
@unsubscribe()
dayChannel = @realtime.channels.get("visitor:#{day}")
allChannel = @realtime.channels.get("visitor:all")
allChannel.subscribe (m) ->
switch m.name
when " . . . "
# . . .
dayChannel.subscribe (m) ->
switch m.name
when " . . . "
# . . .
dayChannel.presence.subscribe 'enter', (member) -> VisitorMessages.setNumOnline(dayChannel)
dayChannel.presence.subscribe 'leave', (member) -> VisitorMessages.setNumOnline(dayChannel)
dayChannel.presence.enter()
VisitorMessages.setNumOnline(dayChannel)
@realtime.connection.on 'connected', ->
VisitorMessages.refreshData() # not showing this function here
VisitorMessages.connected_first_time = true # the refreshData() function returns if this is false
dayChannel = VisitorMessages.realtime.channels.get("visitor:#{day}")
dayChannel.attach()
dayChannel.presence.enter()
VisitorMessages.setNumOnline(dayChannel)
allChannel = VisitorMessages.realtime.channels.get("visitor:all")
allChannel.attach()
setNumOnline: (channel) ->
channel.presence.get (err, members) ->
# I use ractive.js to manipulate the DOM
ractive.set('number_online', members.length)
unsubscribe: ->
for channelName of VisitorMessages.realtime.channels.all
unless channelName == 'visitor:all'
channel = VisitorMessages.realtime.channels.get(channelName)
channel.presence.leave()
channel.presence.unsubscribe()
channel.unsubscribe()
channel.detach()
VisitorMessages.realtime.channels.release(channelName)
在 js 控制台中,访问者得到了一堆这些:
Ably: ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding
有时这样:
Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]
并且,当切换到不同的日期(设置日期并调用 VisitorMessages.start()
时,他们会得到:
Channels.onChannelMessage(): received event for non-existent channel: visitor:2018-05-26
我知道这可能是因为我在切换日期时明确释放频道,但当我不这样做时,VisitorMessages.realtime.channels.all
将包含我曾经加入的所有频道,而且我仍在接收未订阅频道的消息。
所以,这里发生了很多不同的事情,但是有人可以看出我的方法中的一些大局缺陷,或者帮助我理解为什么会发生这些错误吗?同样,一切正常,但有些地方不对!
谢谢!
以上代码编译成javascript:
var VisitorMessages;
VisitorMessages = {
realtime: null,
connected_first_time: false,
start: function() {
var allChannel, dayChannel;
if (!this.realtime) {
this.realtime = new Ably.Realtime({
authUrl: '/auth',
recover: function(lastConnectionDetails, cb) {
cb(true);
}
});
}
this.unsubscribe();
dayChannel = this.realtime.channels.get("visitor:" + day);
allChannel = this.realtime.channels.get("visitor:all");
allChannel.subscribe(function(m) {
switch (m.name) {
case " . . . ":
// . . .
}
});
dayChannel.subscribe(function(m) {
switch (m.name) {
case " . . . ":
// . . .
}
});
dayChannel.presence.subscribe('enter', function(member) {
VisitorMessages.setNumOnline(dayChannel);
});
dayChannel.presence.subscribe('leave', function(member) {
VisitorMessages.setNumOnline(dayChannel);
});
dayChannel.presence.enter();
VisitorMessages.setNumOnline(dayChannel);
return this.realtime.connection.on('connected', function() {
VisitorMessages.refreshData();
VisitorMessages.connected_first_time = true;
dayChannel = VisitorMessages.realtime.channels.get("visitor:" + day);
dayChannel.attach();
dayChannel.presence.enter();
VisitorMessages.setNumOnline(dayChannel);
allChannel = VisitorMessages.realtime.channels.get("visitor:all");
allChannel.attach();
});
},
setNumOnline: function(channel) {
channel.presence.get(function(err, members) {
ractive.set('number_online', members.length);
});
},
unsubscribe: function() {
var channel, channelName, results;
for (channelName in VisitorMessages.realtime.channels.all) {
if (channelName !== 'visitor:all') {
channel = VisitorMessages.realtime.channels.get(channelName);
channel.presence.leave();
channel.presence.unsubscribe();
channel.unsubscribe();
channel.detach();
VisitorMessages.realtime.channels.release(channelName);
}
}
}
};
我是 Ably 的一名工程师。
没有特别的大图,只是这里发生了一堆不同的事情。
Ably: ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding
这意味着客户端库已收到消息的多个副本,并自动对它们进行重复数据删除。众所周知,这偶尔会在客户端库执行实时 comet->websocket 升级后发生。如果它一直发生,则可能是其他原因 - 联系我们,我们将尝试实时调试它。
Channels.onChannelMessage(): received event for non-existent channel: visitor:2018-05-26
正如您正确指出的那样,那是因为您要发布频道。 channels.release()
是一个很少使用的功能,它仅在客户端连接和断开如此多的通道以致 channels.all
共同开始占用大量内存时真正有用,因此 release() 删除它们以便它们可以收集的垃圾。这不是 99% 的人需要做或知道的事情——我认为它甚至没有包含在我们的 api 文档中。它绝对不应该在尚未分离的通道上使用,这将导致未定义的行为。
当您在代码中调用它时,通道确实尚未分离,即使您已调用 detach()
。根据 the api docs for channel#detach(),这是一个异步操作——它请求与 Ably 分离,同时将通道置于 detaching
状态。如果有必要释放一个通道(客户端几乎从来没有),应该在 detach()
(或 once('detached')
监听器)的回调中完成。
when I wasn't doing that, VisitorMessages.realtime.channels.all would contain all of the channels that I had ever joined
是的,但没关系,在那个对象中并不意味着它们已附加。您可以通过过滤 state
为 'attached'
.
的条目来仅显示附加的条目
and I was still receiving messages for unsubscribed channels.
取消订阅是一个本地操作(它只是同步删除你添加的监听器);如果你想阻止 lib 从服务器接收消息,你需要从通道中分离——参见 channels/messages docs
(如果你的意思是你的消息监听器在你调用 unsubscribe() 之后仍然被调用,或者 lib 仍然在处于 detached
状态的通道上接收消息,那么这两种情况都不可能 - - 要么你的取消订阅代码坏了(恐怕我不太了解 coffeescript),要么被调用的监听器不是你认为的频道,或者 ably-js 中有一个错误。设置 log: {level: 4}
在 lib 构造函数中将启用调试日志记录,这可以帮助您查看 lib 正在做什么;如果您需要帮助分析日志,请告诉我们)。
Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]
通常,这意味着频道在暂停后尝试自动重新连接和重新进入(例如,因为您与互联网断开连接超过 2 分钟),但无法,例如因为客户端现在使用的令牌无权访问该频道。
但在你的情况下,我猜这是来自你手动释放的频道的噪音()d,然后被留在了边缘,因为服务器永远不会告诉他们他们已经 detached
.
(我实际上刚刚提出了一项功能建议,要求在 channels.release() 上设置一个警卫,以阻止您对处于活动状态的频道执行此操作 -- https://github.com/ably/docs/issues/437)。
将 Ably Realtime 用于基于 Web 的预订系统。
我在 js 控制台中不断收到一些错误,尽管一切正常。
基本上,有一个日期选择器,当访问者选择一个日期时,我将全局变量 day
设置为日期(类似于 2018-05-25
)并调用 VisitorMessages.start()
,为他们订阅消息并让他们出现在频道 visitor:2018-05-25
上,并从所有其他频道取消订阅他们。
我还有一个 visitor:all
频道,每个人都可以在该频道上收到消息,不需要在场。
这是我正在做的(请原谅 CoffeeScript):
VisitorMessages =
realtime: null
connected_first_time: false
start: ->
unless @realtime
@realtime = new Ably.Realtime
authUrl: '/auth'
recover: (lastConnectionDetails, cb) ->
cb(true)
return
@unsubscribe()
dayChannel = @realtime.channels.get("visitor:#{day}")
allChannel = @realtime.channels.get("visitor:all")
allChannel.subscribe (m) ->
switch m.name
when " . . . "
# . . .
dayChannel.subscribe (m) ->
switch m.name
when " . . . "
# . . .
dayChannel.presence.subscribe 'enter', (member) -> VisitorMessages.setNumOnline(dayChannel)
dayChannel.presence.subscribe 'leave', (member) -> VisitorMessages.setNumOnline(dayChannel)
dayChannel.presence.enter()
VisitorMessages.setNumOnline(dayChannel)
@realtime.connection.on 'connected', ->
VisitorMessages.refreshData() # not showing this function here
VisitorMessages.connected_first_time = true # the refreshData() function returns if this is false
dayChannel = VisitorMessages.realtime.channels.get("visitor:#{day}")
dayChannel.attach()
dayChannel.presence.enter()
VisitorMessages.setNumOnline(dayChannel)
allChannel = VisitorMessages.realtime.channels.get("visitor:all")
allChannel.attach()
setNumOnline: (channel) ->
channel.presence.get (err, members) ->
# I use ractive.js to manipulate the DOM
ractive.set('number_online', members.length)
unsubscribe: ->
for channelName of VisitorMessages.realtime.channels.all
unless channelName == 'visitor:all'
channel = VisitorMessages.realtime.channels.get(channelName)
channel.presence.leave()
channel.presence.unsubscribe()
channel.unsubscribe()
channel.detach()
VisitorMessages.realtime.channels.release(channelName)
在 js 控制台中,访问者得到了一堆这些:
Ably: ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding
有时这样:
Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]
并且,当切换到不同的日期(设置日期并调用 VisitorMessages.start()
时,他们会得到:
Channels.onChannelMessage(): received event for non-existent channel: visitor:2018-05-26
我知道这可能是因为我在切换日期时明确释放频道,但当我不这样做时,VisitorMessages.realtime.channels.all
将包含我曾经加入的所有频道,而且我仍在接收未订阅频道的消息。
所以,这里发生了很多不同的事情,但是有人可以看出我的方法中的一些大局缺陷,或者帮助我理解为什么会发生这些错误吗?同样,一切正常,但有些地方不对!
谢谢!
以上代码编译成javascript:
var VisitorMessages;
VisitorMessages = {
realtime: null,
connected_first_time: false,
start: function() {
var allChannel, dayChannel;
if (!this.realtime) {
this.realtime = new Ably.Realtime({
authUrl: '/auth',
recover: function(lastConnectionDetails, cb) {
cb(true);
}
});
}
this.unsubscribe();
dayChannel = this.realtime.channels.get("visitor:" + day);
allChannel = this.realtime.channels.get("visitor:all");
allChannel.subscribe(function(m) {
switch (m.name) {
case " . . . ":
// . . .
}
});
dayChannel.subscribe(function(m) {
switch (m.name) {
case " . . . ":
// . . .
}
});
dayChannel.presence.subscribe('enter', function(member) {
VisitorMessages.setNumOnline(dayChannel);
});
dayChannel.presence.subscribe('leave', function(member) {
VisitorMessages.setNumOnline(dayChannel);
});
dayChannel.presence.enter();
VisitorMessages.setNumOnline(dayChannel);
return this.realtime.connection.on('connected', function() {
VisitorMessages.refreshData();
VisitorMessages.connected_first_time = true;
dayChannel = VisitorMessages.realtime.channels.get("visitor:" + day);
dayChannel.attach();
dayChannel.presence.enter();
VisitorMessages.setNumOnline(dayChannel);
allChannel = VisitorMessages.realtime.channels.get("visitor:all");
allChannel.attach();
});
},
setNumOnline: function(channel) {
channel.presence.get(function(err, members) {
ractive.set('number_online', members.length);
});
},
unsubscribe: function() {
var channel, channelName, results;
for (channelName in VisitorMessages.realtime.channels.all) {
if (channelName !== 'visitor:all') {
channel = VisitorMessages.realtime.channels.get(channelName);
channel.presence.leave();
channel.presence.unsubscribe();
channel.unsubscribe();
channel.detach();
VisitorMessages.realtime.channels.release(channelName);
}
}
}
};
我是 Ably 的一名工程师。
没有特别的大图,只是这里发生了一堆不同的事情。
Ably: ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding
这意味着客户端库已收到消息的多个副本,并自动对它们进行重复数据删除。众所周知,这偶尔会在客户端库执行实时 comet->websocket 升级后发生。如果它一直发生,则可能是其他原因 - 联系我们,我们将尝试实时调试它。
Channels.onChannelMessage(): received event for non-existent channel: visitor:2018-05-26
正如您正确指出的那样,那是因为您要发布频道。 channels.release()
是一个很少使用的功能,它仅在客户端连接和断开如此多的通道以致 channels.all
共同开始占用大量内存时真正有用,因此 release() 删除它们以便它们可以收集的垃圾。这不是 99% 的人需要做或知道的事情——我认为它甚至没有包含在我们的 api 文档中。它绝对不应该在尚未分离的通道上使用,这将导致未定义的行为。
当您在代码中调用它时,通道确实尚未分离,即使您已调用 detach()
。根据 the api docs for channel#detach(),这是一个异步操作——它请求与 Ably 分离,同时将通道置于 detaching
状态。如果有必要释放一个通道(客户端几乎从来没有),应该在 detach()
(或 once('detached')
监听器)的回调中完成。
when I wasn't doing that, VisitorMessages.realtime.channels.all would contain all of the channels that I had ever joined
是的,但没关系,在那个对象中并不意味着它们已附加。您可以通过过滤 state
为 'attached'
.
and I was still receiving messages for unsubscribed channels.
取消订阅是一个本地操作(它只是同步删除你添加的监听器);如果你想阻止 lib 从服务器接收消息,你需要从通道中分离——参见 channels/messages docs
(如果你的意思是你的消息监听器在你调用 unsubscribe() 之后仍然被调用,或者 lib 仍然在处于 detached
状态的通道上接收消息,那么这两种情况都不可能 - - 要么你的取消订阅代码坏了(恐怕我不太了解 coffeescript),要么被调用的监听器不是你认为的频道,或者 ably-js 中有一个错误。设置 log: {level: 4}
在 lib 构造函数中将启用调试日志记录,这可以帮助您查看 lib 正在做什么;如果您需要帮助分析日志,请告诉我们)。
Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]
通常,这意味着频道在暂停后尝试自动重新连接和重新进入(例如,因为您与互联网断开连接超过 2 分钟),但无法,例如因为客户端现在使用的令牌无权访问该频道。
但在你的情况下,我猜这是来自你手动释放的频道的噪音()d,然后被留在了边缘,因为服务器永远不会告诉他们他们已经 detached
.
(我实际上刚刚提出了一项功能建议,要求在 channels.release() 上设置一个警卫,以阻止您对处于活动状态的频道执行此操作 -- https://github.com/ably/docs/issues/437)。