Protocol server implementation details

CSS-WC

Overview

The CSS-WC server is based on a simple generic framework for building UDP servers

Classes

class dvbcss.protocol.server.wc.UdpRequestServer(socket, handler, maxMsgSize)[source]

Simple request handling server framework.

Pass it an open UDP socket object that blocks on receive, and it will call your handler, passing the socket, plus the received data.

This all happens in a separate thread.

Use start() and stop() methods to start and stop the handling thread.

Socket must have set blocking and a timeout.

Parameters:
  • socket (socket.socket) – Bound socket ready to receive (and send) UDP packets
  • handler – (object) Object providing a handle() method.
  • maxMsgSize (int) – The maximum message size (sets the UDP receive buffer size)

The handler object must have a method with the following signature:

handle(socket, received_data, src_addr)[source]
Parameters:
  • socket – The socket object for the connection on which the packet was received.
  • received_data (str) – The received UDP packet payload
  • src_addr – The source address. For an AF_INET connection this will be a tuple (str host, int port)
run()[source]

Internal method - the main runloop of the thread.

Runs in a loop calling the handle() method of the object assigned to the handler property whenever a UDP packet is received.

Does not return until the _pleaseStop attribute of the object has been set to True

start()[source]

Starts the wall clock server running. It runs in a thread in the background.

stop()[source]

Stops the wall clock server running. Does not return until the thread has terminated.

class dvbcss.protocol.server.wc.WallClockServerHandler(wallClock, precisionSecs=None, maxFreqErrorPpm=None, followup=False, **kwargs)[source]

Simple Wall Clock Server Handler function.

Provides a handle() method. Designed to be used with UdpRequestServer

Parameters:
  • wallClock (dvbcss.clock.ClockBase) – The clock to be used as the wall clock for protocol interactions
  • precisionSecs – (float) Optional. Override using the precision of the provided clock and instead use this value. It is the precision (in seconds) to be reported for the clock in protocol interactions
  • maxFreqErrorPpm – (float or None) Optional. Override using the getRootMaxFreqError() of the clock and instead use this value. It is the clock maximum frequency error in parts-per-million
  • followup (bool) – Set to True if the Wall Clock Server should send follow-up responses

CSS-CII and CSS-TS

Module: dvbcss.protocol.server

Overview

The CSS-CII and CSS-TS servers subclass the WebSocket server functionality for cherrypy implemented by ws4py in the cherrypyserver module.

CIIServer and TSServer both inherit from a common base implementation WSServerTool provided in the dvbcss.protocol.server module.

The Tool provides the hook into cherrypy for handling the connection request and upgrading it to a WebSocket connection, spawning an object representing the WebSocket connection and which implements the WebSocket protocols.

The base server object class is intended to manage all WebSocket connections for a particular server endpoint. It therefore provides its own customised WebScoket class that is bound to that particular server object instance.

The tool is enabled via an “on” configuration when setting up the mount point in cherrypy. The tool also expects to a “handler_cls” property set in the configuration at the mount point. This property points to a WebSocket class which can be instantiated to handle the connection.

Example usage: creating a server at “ws://<host>:80/endpoint” just using the base classes provided here:

import cherrypy
from ws4py.server.cherrypyserver import WebSocketPlugin
from dvbcss.protocol.server import WSServerBase, WSServerTool

# plug the tool into cherrypy as "my_server"
cherrypy.tools.my_server = WSServerTool()

WebSocketPlugin(cherrypy.engine).subscribe()

# create my server
myServer = WSServerBase()

# bind it to the URL path /endpoint in the cherrypy server
class Root(object):
    @cherrypy.expose
    def endpoint(self):
        pass

cfg = {"/endpoint": {'tools.my_server.on': True,
                'tools.my_server.handler_cls': myServer.handler
               }
      }

cherrypy.tree.mount(Root(), "/", config=cfg)

# activate cherrypy web server on port 80
cherrypy.config.update({"server.socket_port":80})
cherrypy.engine.start()

See documentation for WSServerBase for information on creating subclasses to implement specific endpoints.

Classes

class dvbcss.protocol.server.ConnectionIdGen[source]

Object for generating unique connection id strings.

classmethod next()[source]
Returns:new unique connection id string
class dvbcss.protocol.server.WSServerTool[source]

Subclass of the ws4py.server.cherrypyserver.WebSocketTool tool to do a simultaneous connections limit check and enabled/disabled check for the end point before the handler is invoked

cleanup_headers()[source]

Some clients aren’t that smart when it comes to headers lookup.

complete()[source]

Override of the base implementation of the code to install a callback to notify the websocket once the upgrade is complete.

Cherrypy’s normal “completion” callbacks fire /before/ cherrypy has flushed outgoing data to the socket connection, creating a race-condition between the flush happening and the websocket class starting to write outgoing messages.

This replacement handler is guaranteed to fire /after/ cherrypy has flushed and is no longer using the socket connection.

start_handler()[source]

Runs at the end of the request processing by calling the opened method of the handler.

upgrade(*args, **kwargs)[source]

Override of base implementation of the code to handle a connection “upgrade” (part of the WebSocket handshake).

The “handler_cls” for this tool is passed as an argument and it implements methods to check whether:

  1. The end point is enabled. If not then a 403 “Forbidden” response is returned.
  2. A connection can be allocated (the connection limit is not yet reached). If not then a 503 “Service Unavailable” response is returned.

If neither of these tests fail, then the superclass upgrade operation is allowed to proceed.

class dvbcss.protocol.server.WSServerBase(maxConnectionsAllowed=-1, enabled=True)[source]

Base class for WebSocket server endpoint implementation.

Parameters:
  • maxConnectionsAllowed (int) – -1 to allow unlimited connections, otherwise sets the maximum number of concurrent connections from clients.
  • enabled (bool) – Whether this server starts off enabled or disabled.

When the server is “disabled” it will refuse attempts to connect by sending the HTTP status response 403 “Forbidden”.

When the server has reached its connection limit, it will refuse attempts to connect by sending the HTTP status response 503 “Service unavailable”.

Protocol specific implementations inherit from this base class and override stub methods and class attributes. When subclassing you will want to override:

The WebSocket connection object representing each connection is used as a handle for the connection.

This class stores per connection connection data. What that data is is entirely up to the subclass. The getDefaultConnectionData() method provides the initial data for a connection when it is opened. The _connections instance variable then keeps a mapping from websocket connections to that data.

handler[source]

Handler class for new connections. Should be provided as a configuration argument to cherrypy.

_connections[source]

dict mapping WebSocket objects to connection data. Connection data is for use by subclasses to store data specific to each individual connection.

_addConnection(webSock)[source]

Internal method. Called to notify this class of a newly connected websocket.

Parameters:webSock – (WebSocket) The newly connected Websocket.
_makeHandlerClass(connectionIdPrefix)[source]
Parameters:connectionIdPrefix – (str) Human-readable prefix to be put on connection-ids
Returns:WebSocketHandler class, which is a subclass of ws4py.websocket.WebSocket that is unique to this server instance.
_receivedMessage(webSock, message)[source]

Internal method. Called to notify this class of a websocket message arrival.

Parameters:
  • webSock – (WebSocket) The WebSocket connection on which the message arrived.
  • msg – (Message) WebSocket message that has been received. Will be either a Text or a Binary message.
_removeConnection(webSock)[source]

Internal method. Called to notify this class of a websocket disconnection.

Parameters:webSock – (WebSocket) The now disconnected Websocket.
connectionIdPrefix = 'serverbase'[source]

prefix to be used for connection ids

enabled[source]

(read/write bool) Whether this server endpoint is enabled (True) or disabled (False).

Set this property enable or disable the endpoint.

When disabled, existing connections are closed with WebSocket closure reason code 1001 and new attempts to connect will be refused with HTTP response status code 403 “Forbidden”.

getConnections()[source]
Returns dict:mapping a WebSocket object to connection related data for all connections to this server. This is a snapshot of the connections at the moment the call is made. The dictionary is not updated later if new clients connect or existing ones disconnect.
getDefaultConnectionData()[source]

This function is called to create new server-specific connection data when a new client connects. This is stored against the websocket connection and can be retrieved using the getConnections() method.

Override with your own function that returns data to be stored against new connections :returns: empty dict, but can return anything you like.

loggingName = 'dvb-css.protocol.server.WSServerBase'[source]

name used for logging messages

onClientConnect(webSock)[source]

This method is called when a new client connects.

This is a stub for this method. Sub-classes should implement it.

:param webSock:(WebSocket) The object representing the WebSocket connection of the newly connected client

onClientDisconnect(webSock, connectionData)[source]

This method is called after a client is disconnected.

This is a stub for this method. Sub-classes should implement it.

Parameters:
  • webSock – (WebSocket) The object representing the WebSocket connection of the now-disconnected client
  • connectionData – (dict) of connection data relating to this connection.
onClientMessage(webSock, msg)[source]

This method is called when a message is received from a client.

This is a stub for this method. Sub-classes should implement it.

Parameters:
  • webSock – (WebSocket) The object representing the WebSocket connection from which the message has been received.
  • msg – (Message) WebSocket message that has been received. Will be either a Text or a Binary message.
class .WebSocketHandler(WebSocket)[source]

This class is created and returned by the WSServerBase._makeHandlerClass() method and each class returned is bound to the instance of WSServerBase that created it.

It is intended to be provided to cherrypy as the “handler_cls” configuration parameter for the WebSocket tool. It is instantiated for every connection made.

These are subclasses of the ws4py WebSocket class and represent an individual WebSocket connection.

Instances of this class call through to WSServerBase._addConnection() and WSServerBase._removeConnection() and WSServerBase._receivedMessage() to inform the parent server of the WebSocket opening, closing and receiving messages.

classmethod isEnabled(cls)[source]
Returns:True if the server endpoint is enabled, otherwise False.
classmethod canAllocateConnection(cls)[source]
Returns:True only if the connection limit of the parent server has not yet been reached. Otherwise False.
id(self)[source]
Returns:A human readable connection ID