anycable/anycable-client

Improve re-using channels

palkan opened this issue · 1 comments

There is common pattern to subscribe to the same channel from multiple independent components. For example:

// component-one.js
import cable from 'cable'
import { ChatChannel } from 'channels/chat'

// Build an instance of a ChatChannel class.
const channel = new ChatChannel({ roomId: '42' })

// Subscribe to the server channel via the client.
await cable.subscribe(channel)

channel.on('message', msg => console.log("component one received message", `${msg.name}: ${msg.text}`))

// component-two.js
import cable from 'cable'
import { ChatChannel } from 'channels/chat'

// Build an instance of a ChatChannel class.
const channel = new ChatChannel({ roomId: '42' })

// Subscribe to the server channel via the client.
await cable.subscribe(channel)

channel.on('message', msg => console.log("component two received message", `${msg.name}: ${msg.text}`))

We cannot build multiple instances with the equal identifiers—that would result in a server side error during the subscription.
If we extract a ChatChannel instance into its own module (easy), we still have a problem with calling potentially calling cable.subscribe(channel) multiple times.

The short term proposal is to make cable.subscribe(channel) idempotent (similarly to cable.connect()).

The long term proposal is to provide an additional abstraction to memoize channel instances, so we can do the following:

const channel = cable.fetchChannel(ChatChannel, { roomId: '42' })

Added new PR#13 to fix parallel connection of different channels