from twisted.internet import protocol
from twisted.python import log
from fixbot import buffer
from fixbot.module import ModuleInfo, Event
CLIENT_COMMANDS = [
"module_init",
"module_event",
]
SERVER_COMMANDS = [
"module_ok",
]
class ServerProtocol (buffer.StreamProtocol, protocol.Protocol) :
RECV_COMMANDS = CLIENT_COMMANDS
SEND_COMMANDS = SERVER_COMMANDS
VALID_STATES = [
"wait_init",
"wait_event"
]
# proto state
state = None
# module info
module = None
def _assert (self, condition, msg) :
if not condition :
self.transport.loseConnection()
log.err("assert failed in APIProtocol for %s: %s" % (self.module, msg))
def connectionMade (self) :
log.msg("Client connected")
def connectionLost (self, reason) :
log.msg("Connection lost: %s" % reason)
if self.module :
self.factory.nexus.unregisterModule(self.module, reason.getErrorMessage())
def on_module_init (self, i) :
self._assert(not self.module, "module_init with non-None self.module")
peer_secret = i.readVarLen('B')
self._assert(peer_secret == self.factory.secret, "Mismatching API secrets!")
m = ModuleInfo()
m.name = i.readVarLen('B')
m.addr = self.transport.getPeer()
log.msg("Got mod_init for %r" % m)
self.factory.nexus.registerModule(m, self)
self.module = m
o = self.startCommand('module_ok')
self.send(o)
def on_module_event (self, i) :
self._assert(self.module, "module_event with None self.module!")
event_type = i.readVarLen('B')
event_msg = i.readVarLen('H')
e = Event(self.module, event_type, event_msg)
self.factory.nexus.handleEvent(e)
def logPrefix (self) :
if self.module :
return str(self.module)
else :
return super(ServerProtocol, self).logPrefix()
class ClientProtocol (buffer.StreamProtocol, protocol.Protocol) :
RECV_COMMANDS = SERVER_COMMANDS
SEND_COMMANDS = CLIENT_COMMANDS
def connectionMade (self) :
log.msg("Connected to API server, sending module init message")
o = self.startCommand('module_init')
o.writeVarLen('B', self.factory.secret)
o.writeVarLen('B', self.factory.name)
self.send(o)
def sendEvent (self, event) :
o = self.startCommand('module_event')
o.writeVarLen('B', event.type)
o.writeVarLen('H', event.msg[:2**16])
self.send(o)
def on_module_ok (self, i) :
log.msg("Registration OK")
self.factory._onRegistered(self)
def logPrefix (self) :
return "module %s client" % (self.factory.name)