Ninja Bot uses the Socket.io library to support realtime duplex communication with the backend API server for features such as entity requests/updates and high-volume log viewing.

Rationale

In order to implement major portions of the architus app, there exists a need for a secure communication channel between the server and client that supports server pushes and differing levels of permission.

Use Cases

Socket.io is used as a duplex communication engine, enabling us to support lower latency request => response patterns as well as server-initiated events, useful for updating spectating clients that an action ocurred in the current guild that requires an update on the UI.

Authenticating

Uses JWT for authentication, similar to the REST API. JWT secret is shared between the socket.io server nodes and the API nodes to let the socket.io server verify the validity of JWT tokens as they come in, as needed. This means that the auth token needs to be included in the payload of every request.

Patterns

  1. Request-response
  2. Discord entity pools (members, emojis, channels, and roles)
    1. Request all emojis, channels, roles, online members
    2. Request single entity
    3. Request member search
      1. 3 steps:
        1. initial view of all displayed entities
        2. interact with relevant UI => request remainder of pool
        3. on search member
  3. Server-push messages
  4. Live updates requiring data refresh (i.e. new auto-response token)
  5. Live log entry view

Implementation Details

  1. Single room per user
  2. Use JWT to encode permissions for instant authentication
  3. Use redux middleware in frontend to provide symmetry to traditional RESTful response handling
  4. Payloads are strings (JSON-serialized)
  5. Default unauthenticated room
  6. Authenticated room
  7. Websocket server manages what messages are received as server pushes and relevant req/res authorization based on JWT and other context

Filtering/scalability

MQ Topics

Have MQ filter as many unneeded events out as possible (faster than WS server):

MQ topics

Have websocket servers subscribe to as many topics as they currently need (based on current connections/authenticated rooms and the guilds they need visibility to)

<guild_id>
<guild_id>_logs

Message Types (Socket.io Events)

Unauthenticated Room Events

Result

Authenticated Room Events

<SID>_auth - Server manages what events are sent to this room

"payload": {
  "guild_id": "guild_id"
  "include_logs": true
}

Server Push