Using Ably Realtime for a web based reservation system.
I'm getting a few errors in the js console consistently, though everything is working properly.
Basically, there is a date selector and when a visitor selects a date, I set a global variable day
to the date (something like 2018-05-25
) and call VisitorMessages.start()
, which subscribes them to messages and makes them present on the channel visitor:2018-05-25
, and unsubscribes them from all other channels.
I also have a visitor:all
channel that everyone gets messages on and where presence is not needed.
Here's what I'm doing (please excuse the 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)
In the js console, the visitor gets a bunch of these:
Ably: ConnectionManager.onChannelMessage() received message with different connectionSerial, but same message id as a previous; discarding
Sometimes this:
Ably: RealtimePresence._ensureMyMembersPresent(): Presence auto-re-enter failed: [c: Unable to enter presence channel (incompatible state); code=90001]
And, when switching to a different date (which sets the day and calls VisitorMessages.start()
, they get this:
Channels.onChannelMessage(): received event for non-existent channel: visitor:2018-05-26
I know that this is probably because I am explicitly releasing the channel when switching days, but when I wasn't doing that, VisitorMessages.realtime.channels.all
would contain all of the channels that I had ever joined, and I was still receiving messages for unsubscribed channels.
So, there are a lot of different things going on here, but can someone see some big picture flaw in my approach or help me to understand why these errors are happening? Again, everything works fine, but something is not right!
Thanks!
Here's the above code compiled into 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);
}
}
}
};