adonisjs / rfcs

💬 Sharing big changes with community to add them to the AdonisJs eco-system
52 stars 6 forks source link

Websockets based on Asyngular #22

Closed Ruby184 closed 3 years ago

Ruby184 commented 4 years ago

Brief history

AdonisJS websockets in version 4.1 have a few bugs and are missing some of production important features like multi server support. Developing the whole package on its own is really time consuming and hard to maintain. Better approach would be just to take production battle-tested library and wrap in Adonis-like interface.

Why we are considering Asyngular?

Asyngular is highly scalable realtime framework optimized for async/await. It is a successor to the SocketCluster library with a few improvements. The main reasons why we are considering to build websockets on top of Asyngular includes:

Scalability

With little effort scales both vertically (across multiple CPU cores on a machine/host) and horizontally (across multiple hosts) just by adding agc-worker and agc-broker instances as needed. You can find more information in AGC Guide.

No need to write own client libraries

We can use existing Asyngular client library for Javascript / NodeJS. What is more it has compatibility with existing SocketCluster clients for example for Java (Android), Swift (iOS), Python, C, C++, C#, Go and Ruby.

Proposal

Asyngular API is different from what we are used to when using Adonis. Our goal is to wrap it in Adonis like interface as much as possible. The main goals:

  1. Emitting events is not bound to channels instead we have a concept of RPC. Expose RPC similar to routes like:
Ws.procedure('some/procedure/:param', 'WsController.proc').middleware(['auth'])
  1. We can transmit and publish data to different channels. So for processing data published to channel we can use registered handler.
Ws.channel('chat', 'ChatChannel.handler')
  1. Asyngular has concept of middlewares grouped into 4 lines (HANDSHAKE, INBOUND_RAW, INBOUND, OUTBOUND). Each group can handle specific actions. More about Asyngular middlewares you can read in Middleware and authorization ducumentation. The goal is to add middlewares in Adonis style.
export default class CustomMiddleware {
  public async handle (ctx: HttpContextContract, next: () => Promise<void>) {
    // for HTTP
  }
  public async wsHandle (ctx: WsContextContract, next: () => Promise<void>) {
    // for WebSocket
  }
}

Relevant links

Feel free to comment and discuss your expectations from new websockets implementation for AdonisJS 5.