Skip to content
This repository was archived by the owner on Oct 13, 2021. It is now read-only.

The Websocket Service

C9 edited this page Jun 27, 2019 · 2 revisions

WSServer: an overview

Introduction

To facilitate communication between the client and the server, we decided to use the WebSocket protocol. Since the client is written using Electron, this is a fairly natural fit on that side, and Python has a fairly good websockets PyPI package.

This document describes the way the WebSocket service works, server-side.

Bridging the gap between two architectures

As the communication between the client and the server occurs using WebSockets, and the communication between services within the server occurs using Pyro services, we need to bridge the gap somehow.

Event loops

To this end, the WebSocket service merges two event loops. As the PyPI websockets library uses asyncio, we run an asyncio event loop which has a listening and sending task registered the normal way. Additionally, the Pyro daemon is queried for its file descriptors every time a Pyro event occurs, and these file descriptors are added to the asyncio event loop's file descriptor polling set. Whenever a Pyro event is received, a callback is called which runs the Pyro code.

Communication between the two sides

When a Pyro message is received, it is handled in the way messages are normally handled by classes that derive from Service (for the curious, yes, this means we run multiple asyncio event loops. If we had another week, we would probably rewrite that a bit).

The Pyro message handlers can schedule a coroutine in the WebSockets event loop which adds a message to the send queue. These messages are later handled (as described below) and passed to clients.

From the WebSocket side, the listening task simply waits for messages from clients, parses them and does some verification, wraps them (so that clients can't masquerade as internal services) and passes them on to the message bus, which is represented as a Pyro proxy that is available from the WebSocket side. The sending task waits for messages on the message queue, maps the recipient list in the message to a list of open sockets, and sends the message out to its clients.

Clone this wiki locally