Mongrel2 Transceiver

1 Overview

Mongrel2 Transceiver was built to solve 3 major hassles that come with trying to handle ZMQ and WebSockets.

  1. Handling WebSockets properly
  2. Dynamically adding more connections to a running handlers
  3. 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:

  1. Automatically cleans up ZMQ context on __exit__
  2. 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
  3. Sets up a REP (bind) socket which is used internally by the Connector class
  4. 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).

Optional Arguments
ArgValueDefaultDescription
ping_timeout# in seconds30How often should the poller wake up to send out WebSocket pings
log_levelone of the standard python logging levelslogging.ERRORSets 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:

  1. When entering the with statement it will create a PUSH and SUB socket
  2. At the first call to the client method it will:
    1. Use the Connector class to set up connections on each handler IP
    2. Verify that the connection is working (to avoid slow subscriber issue)
    3. 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.

Optional Arguments
ArgValueDefaultDescription
ipIP addressfirst address for eth0 interfaceAddress to reach this Server
push_portPort #9999Push socket port number
sub_portPort #9998Sub 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.

Date: 2015-02-28 18:38:51 MST

Author: Matthew Brisebois

Org version 7.8.03 with Emacs version 24

Validate XHTML 1.0