Idiomatic place to provide websocket infrastructure

I am currently playing with ember-cli and crossbar.io, which uses the WAMP protocol to enable bi-directional communication between js <--> backend. The Javascript logic is built on top of AutobahnJS. I wonder where you would suggest to put logic that

  • opens and closes a websocket connection.
  • registers and then broadcasts onopen, onclose events.
  • provides the connection variable to any controller that needs it.

In another thread I read about a proposal for a service role, which meant to be a singleton to handle shared cross-application concerns. Is this usable by now and would it be the right place?

1 Like

Great question.

TL;DR I Don’t know, but I’ve got some developed opinions.

I’ve got a (currently private) ember-addon that provides WebSocket integration using socket.io, and since we use it in a mobile app with a focus on performance and FPS the Websocket infrastructure is run in a WebWorker. This introduces it’s own questions of abstraction and idiomatic code structure.

My addon introduces two “new” concepts, Pushers, and Workers. I suspect that Pushers may eventually become an extension of a proposed Services api, but until that becomes better formulated and lands I’ve left it as it’s own thing. In addition to these two concepts, I utilize initializers and a single controller.

Pushers

A pusher extends …/utils/pusher.js, the methods it defines within it’s socketEvents hash are turned into handlers for socket events (method name being the name of the event).

Workers

Workers extend /app/utils/worker.js and are moved from /app/workers to /dist/workers directly when compiling assets. The caveat here is that you cannot import any modules that are going to require the DOM, this pretty much rules out running Ember/Ember-Data in a worker (for the moment, the version running on Node right now might make this feasible soon, which I’m looking forward to to fully move my adapter/serializer/store logic into a worker).

Socket Controller

/controllers/socket-client.js

This is an abstraction that controls the WebSocket instance (in this case socket.io) and takes care of setting up and tearing down listeners, etc. It wraps all socket events expecting a return in promises, and if your app requires auth before certain events can work, it will wait to send those requests until a pending auth request has resolved. I inject and add listeners to this controller itself instead of to the socket.io instance. I’ve found this much more stable, especially in mobile environments where the app is being closed and opened often.

An initializer injects this singleton socket-client controller into the store, pushers, routes, controllers, and components (I debated on components initially, but I have some components that act like widgets and need to make their own requests).

@sthzg did you have any luck getting autobahn.js imlemented with ember-cli? Any sample source code I could look at?

Thanks!