将 Ably Realtime 用于基于 Web 的预订系统。
尽管一切正常,但我一直在 js 控制台中遇到一些错误。
基本上,有一个日期选择器,当访问者选择一个日期时,我将一个全局变量设置day
为日期(类似于2018-05-25
)和 call 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);
}
}
}
};