Hey folks! 👋 Got kind of a gigantic question, so please bear with me
I'm trying to build a "better" client for phoenixframework.org. For those who know how phoenix works, skip the following section
The idea is that if you want access to multiple "events", like conversations on a chat server, you make only one socket connection and it multiplexes them. You do that by telling the server “hey I want to join this channel”.
So now you’re subscribed to that channel, you get events for it.
Most clients handle this process pretty horribly, like the most popular Swift client called Birdsong
import Birdsong
…
// In your view controller / client
let socket = Socket(url: NSURL(string: "http://localhost:4000/socket/websocket")!, params: ["key": "secret"])
…
socket.onConnect = {
let channel = self.socket.channel("rooms:some-topic", payload: ["user": "spartacus"])
channel.on("new:msg", callback: { message in
print("New message: \(message)")
})
channel.join()?.receive("ok", callback: { payload in
print("Successfully joined: \(channel.topic)")
})
channel.send("new:msg", payload: ["body": "Hello!"])
.receive("ok", callback: { response in
print("Sent a message!")
})
.receive("error", callback: { reason in
print("Message didn't send: \(reason)")
})
// Presence support.
channel.presence.onStateChange = { newState in
// newState = dict where key = unique ID, value = array of metas.
print("New presence state: \(newState)")
}
channel.presence.onJoin = { id, meta in
print("Join: user with id \(id) with meta entry: \(meta)")
}
channel.presence.onLeave = { id, meta in
print("Leave: user with id \(id) with meta entry: \(meta)")
}
}
socket.connect()
so now in various parts of your app you want to subscribe you basically have to do a
if socket.connected {
//do something
} else {
socket.connect(), then do same thing
}
Also, if you make anew Channel
object, and try to subscribe on a socket; It actually discards any previous subscriptions 🤬.
Which is really bad. Basically parts of your app would stop responding. The “official” JS SDK doesn’t handle this well either.
So what I want to do is
make a “lazy” client preferrably over Rx/just callbacks that lets you just say:
socket.subscribeToChannel
and it handles the gory details behind the scenes of subscribing to a channel
When you subscribe for the first time, it actually creates a subscription.
Any subsequent subscriptions get that “cached” channel object and immediately start getting events
and as soon as number of subscribers goes down to 0 it automatically unsubscribes