Exemple #1
0
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
Exemple #2
0
 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)
Exemple #3
0
 def __init__(self, addr, connect=True):
     """
     @param addr: The (host,port) tuple for connection.
     @type addr: C{tuple}
     
     @param connect: Whether to connect socket to specified addr.
     @type connect: C{bool}
     """
     self.log = logging.getLogger('%s.%s' % (self.__module__, self.__class__.__name__))
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self.addr = addr
     self.received_frames = Queue()
     self.read_stopped = threading.Event()
     self.buffer = FrameBuffer()
     if connect:
         self._connect()
Exemple #4
0
class TestStompClient(object):
    """
    A stomp client for use in testing.
    
    This client spawns a listener thread and pushes anything that comes in onto the 
    read_frames queue.
    
    @ivar received_frames: A queue of Frame instances that have been received.
    @type received_frames: C{Queue.Queue} containing any received C{stompclient.frame.Frame}
    """
    def __init__(self, addr, connect=True):
        """
        @param addr: The (host,port) tuple for connection.
        @type addr: C{tuple}
        
        @param connect: Whether to connect socket to specified addr.
        @type connect: C{bool}
        """
        self.log = logging.getLogger('%s.%s' % (self.__module__, self.__class__.__name__))
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.addr = addr
        self.received_frames = Queue()
        self.read_stopped = threading.Event()
        self.buffer = FrameBuffer()
        if connect:
            self._connect()
    
    def connect(self, headers=None):
        if headers is None:
            headers = {}
        self.send_frame(Frame('CONNECT', headers=headers))
        
    def send(self, destination, message, set_content_length=True, extra_headers=None):
        if extra_headers is None:
            extra_headers = {}
        headers = extra_headers
        headers['destination'] = destination
        if set_content_length: headers['content-length'] = len(message)
        self.send_frame(Frame('SEND', headers=headers, body=message))
    
    def subscribe(self, destination):
        self.send_frame(Frame('SUBSCRIBE', headers={'destination': destination}))
        
    def send_frame(self, frame):
        """
        Sends a stomp frame.
        @param frame: The stomp frame to send.
        @type frame: L{stompclient.frame.Frame}
        """
        if not self.connected:
            raise RuntimeError("Not connected")
        self.sock.send(frame.pack())
    
    def _connect(self):
        self.sock.connect(self.addr)
        self.connected = True
        self.read_stopped.clear()
        t = threading.Thread(target=self._read_loop, name="client-receiver-%s" % hex(id(self)))
        t.start()
    
    def _read_loop(self):
        while self.connected:
            r, w, e = select.select([self.sock], [], [], 0.1)
            if r:
                data = self.sock.recv(1024)
                self.log.debug("Data received: %r" % data)
                self.buffer.append(data)
                for frame in self.buffer:
                    self.log.debug("Processing frame: %s" % frame)
                    self.received_frames.put(frame)
        self.read_stopped.set()
        # print "Read loop has been quit! for %s" % id(self)
    
    def disconnect(self):
        self.send_frame(Frame('DISCONNECT'))
        self.sock.close();
        
    def close(self):
        if not self.connected:
            raise RuntimeError("Not connected")
        self.connected = False
        self.read_stopped.wait()
        self.sock.close()