class StompRequestHandler(BaseRequestHandler, StompConnection): """ Class that will be instantiated to handle STOMP connections. This class will be instantiated once per connection to the server. In a multi-threaded context, that means that instances of this class are scoped to a single thread. It should be noted that while the L{coilmq.engine.StompEngine} instance will be thread-local, the storage containers configured into the engine are not thread-local (and hence must be thread-safe). @ivar buffer: A StompBuffer instance which buffers received data (to ensure we deal with complete STOMP messages. @type buffer: C{stompclient.util.FrameBuffer} @ivar engine: The STOMP protocol engine. @type engine: L{coilmq.engine.StompEngine} @ivar debug: Whether to enable extra-verbose debug logging. (Will be logged at debug level.) @type debug: C{bool} """ def setup(self): if self.server.timeout is not None: self.request.settimeout(self.server.timeout) self.debug = False self.log = logging.getLogger('%s.%s' % (self.__module__, self.__class__.__name__)) self.buffer = FrameBuffer() self.engine = StompEngine(connection=self, authenticator=self.server.authenticator, queue_manager=self.server.queue_manager, topic_manager=self.server.topic_manager) def handle(self): """ Handle a new socket connection. """ # self.request is the TCP socket connected to the client try: while not self.server._shutdown_request_event.is_set(): try: data = self.request.recv(8192) if not data: break if self.debug: self.log.debug("RECV: %r" % data) self.buffer.append(data) for frame in self.buffer: self.log.debug("Processing frame: %s" % frame) self.engine.process_frame(frame) if not self.engine.connected: raise ClientDisconnected() except socket.timeout: pass except ClientDisconnected: self.log.debug("Client disconnected, discontinuing read loop.") except Exception, e: self.log.error("Error receiving data (unbinding): %s" % e) self.engine.unbind() raise
class StompProtocol(Protocol, StompConnection): """ Subclass of C{twisted.internet.protocol.Protocol} for handling STOMP communications. An instance of this class will be created for each connecting client. @ivar buffer: A StompBuffer instance which buffers received data (to ensure we deal with complete STOMP messages. @type buffer: C{stomper.stompbuffer.StompBuffer} @ivar engine: The STOMP protocol engine. @type engine: L{coilmq.engine.StompEngine} """ def __init__(self, queue_manager, topic_manager): self.log = logging.getLogger( '%s.%s' % (self.__class__.__module__, self.__class__.__name__)) self.log.debug("Initializing StompProtocol.") self.buffer = StompFrameBuffer() self.engine = StompEngine( connection=self, authenticator=None, # FIXME: Add the authenticator queue_manager=queue_manager, topic_manager=topic_manager) def connectionLost(self, reason): Protocol.connectionLost(self, reason) self.log.debug("Connection lost.") self.engine.unbind() def connectionMade(self): self.log.debug("Connection made.") def dataReceived(self, data): """ Twisted calls this method when data is received. Note: The data may not be not be a complete frame or may be more than one frame. """ self.log.debug("Data received: %s" % data) self.buffer.append(data) # print '%r' % self.buffer for frame in self.buffer: self.log.debug("Processing frame: %s" % frame) self.engine.process_frame(frame) def send_frame(self, frame): """ Sends a frame to connected socket client. (Sorry, Twisted, our code is PEP-8.) @param frame: The frame to send. @type frame: L{coilmq.frame.StompFrame} """ self.transport.write(frame.pack())
class StompProtocol(Protocol, StompConnection): """ Subclass of C{twisted.internet.protocol.Protocol} for handling STOMP communications. An instance of this class will be created for each connecting client. @ivar buffer: A StompBuffer instance which buffers received data (to ensure we deal with complete STOMP messages. @type buffer: C{stomper.stompbuffer.StompBuffer} @ivar engine: The STOMP protocol engine. @type engine: L{coilmq.engine.StompEngine} """ def __init__(self, queue_manager, topic_manager): self.log = logging.getLogger('%s.%s' % (self.__class__.__module__, self.__class__.__name__)) self.log.debug("Initializing StompProtocol.") self.buffer = StompFrameBuffer() self.engine = StompEngine(connection=self, authenticator=None, # FIXME: Add the authenticator queue_manager=queue_manager, topic_manager=topic_manager) def connectionLost(self, reason): Protocol.connectionLost(self, reason) self.log.debug("Connection lost.") self.engine.unbind() def connectionMade(self): self.log.debug("Connection made.") def dataReceived(self, data): """ Twisted calls this method when data is received. Note: The data may not be not be a complete frame or may be more than one frame. """ self.log.debug("Data received: %s" % data) self.buffer.append(data) # print '%r' % self.buffer for frame in self.buffer: self.log.debug("Processing frame: %s" % frame) self.engine.process_frame(frame) def send_frame(self, frame): """ Sends a frame to connected socket client. (Sorry, Twisted, our code is PEP-8.) @param frame: The frame to send. @type frame: L{coilmq.frame.StompFrame} """ self.transport.write(frame.pack())