Mongrel2 Transceiver
Table of Contents
1 Overview
Mongrel2 Transceiver was built to solve 3 major hassles that come with trying to handle ZMQ and WebSockets.
- Handling WebSockets properly
- Dynamically adding more connections to a running handlers
- Reliably destroying ZMQ Contexts
Transceiver solves all these issues with an intuitive and simplistic syntax.
WARNING: Mongrel2 Transceiver was primarily designed to work with Docker containers. Therefore the default options for all the classes are not expecting to have issues binding to the default ports. It is your job to configure custom ports if you will be running in a single network environment. Every class has options for overriding the default ports and have been tested in a single network environment.
1.1 Installation
pip install mongrel2-transceiver
1.2 Diagram
,---, | | | M | SUB (bind) | G |o < - - - - - - - - - - , < - - - - - - - - - - - - - - - - - - - - - - - - - -, | 2 | , , | | , , | S | , , .--------, | V |o - - - - - , , PUB (conn) , PUB (conn) { } | R | PUSH , ,-------o------API-------------, PUB (bind) SUB (conn) ---o-----Node-------------, |'--------'| | | (bind) - > o-, '-------< + .send(msg) o - - - - - - - - - - > o-, '-------< + .send(msg) | < - - - | | '---' PULL' | transceiver | | | | transceiver | | | DB | (conn) '-------------> + .recv() o - - - - - - - - - - > o-'-------------> + .recv() | - - - > | | '-----o------------------------' PUSH (bind) PULL '-----o------------------------' '-________-' ^ REP (bind) (conn) REP (bind) '_ _ _ _ _ _ _ _ _ _ _ v REQ (conn) ,-----------o----------, | | o tests o PUSH | | SUB (bind)'----------------------' (conn)
2 Transceiver
The Transceiver class is for Mongrel2 handlers. The main features of the Transceiver class are:
- Automatically cleans up ZMQ context on
__exit__
- Automatically handles WebSocket connections by:
- Accepting WebSocket handshakes
- Sending a ping opcode to all active connections every 30 seconds
- Removing connections that send a close opcode or fail to send a pong opcode
- Sets up a REP (bind) socket which is used internally by the Connector class
- Easily adds new connections to it's incoming poller
2.1 Usage
The only required options for the Transceiver to work is the Mongrel2 server's sender ID, Push
Address and Sub Address (respectively given as pull_addr
and pub_addr
tuples).
Arg | Value | Default | Description |
---|---|---|---|
ping_timeout | # in seconds | 30 | How often should the poller wake up to send out WebSocket pings |
log_level | one of the standard python logging levels | logging.ERROR | Sets the log level of the Transceiver logger |
from mongrel2_transceiver import Transceiver mg2_ip = "<mongrel2 IP>" with Transceiver( sender = 'rune', pull_addr = (mg2_ip, 9999), pub_addr = (mg2_ip, 9998) ) as trans: for sid,conn,req in trans.recv(): try: if req is not None: headers = req.headers method = headers.get('METHOD') query = headers.get('QUERY', {})
3 Server, Connector & Client
The Server class is built to work with the Transceiver class. It's main features are:
- When entering the
with
statement it will create a PUSH and SUB socket - At the first call to the
client
method it will:- Use the Connector class to set up connections on each handler IP
- Verify that the connection is working (to avoid slow subscriber issue)
- Returns the Client class
By the time you receive the Client class you can be absolutely certain that the connection is valid and working.
3.1 Usage
The only required options for the Server to work are to be given a sender ID (should be unique) and a list of handler IPs to connect to.
Arg | Value | Default | Description |
---|---|---|---|
ip | IP address | first address for eth0 interface | Address to reach this Server |
push_port | Port # | 9999 | Push socket port number |
sub_port | Port # | 9998 | Sub socket port number |
from mongrel2_transceiver import Server handler_ip = "<handler IP>" with Server( sender = "python_server", connect = [ handler_ip ] ) as server: client = server.client() client.send('/') resp = client.recv()
3.2 .client(protocol)
.client( "mongrel2" | "http" | "websocket" ) defaults to "mongrel2"
The Client class supports the 3 Mongrel2 protocols: Mongrel2, HTTP or WebSocket. Mongrel2 is built in a way that the server decodes HTTP and WebSocket but the handler encodes the response. So all three protocols will send a Mongrel2 encoded request but the expected response will be interpreted as Mongrel2, HTTP or WebSocket.