def handle_stream(self, stream, address): new_conn = TCPConnection(stream, address, self.io_loop) new_channel = RpcChannel(new_conn) new_stub = IServerService_Stub(new_channel) new_entity = self._entity_factory(new_conn, new_stub) new_service = ServerService(new_entity) new_channel.set_rpc_service(new_service) self._connections[address] = new_conn self._entities[address] = new_entity new_conn.set_close_callback(lambda _addr=address, _entity=new_entity: self._handle_connection_close(_addr, _entity)) new_entity.on_connect() new_conn.start()
class TCPClient(object): def __init__(self, host, port, entity_factory, io_loop=None): self.host = host self.port = port self.conn = None self.entity_factory = entity_factory self._close_callback = None self._connect_callback = None if io_loop is None: self.io_loop = tornado.ioloop.IOLoop.instance() else: self.io_loop = io_loop def connect(self, callback=None): sock_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) stream = tornado.iostream.IOStream(sock_fd) self.conn = TCPConnection(stream, (self.host, self.port), self.io_loop) channel = RpcChannel(self.conn) stub = IServerService_Stub(channel) entity = self.entity_factory(self.conn, stub) self._entity = entity service = ServerService(entity) channel.set_rpc_service(service) self._connect_callback = callback self.conn.set_close_callback( lambda _entity=entity: self._on_connect_close(_entity)) stream.connect((self.host, self.port), lambda _entity=entity: self._on_connect(_entity)) def get_entity(self): return self._entity def set_close_callback(self, callback): self._close_callback = callback def _on_connect(self, entity): entity and entity.on_connect() if self._connect_callback: callback = self._connect_callback callback() self._connect_callback = None self.conn and self.conn.start() def _on_connect_close(self, entity): entity and entity.on_connect_close() if self._close_callback is not None: callback = self._close_callback callback() self._close_callback = None self._connect_callback = None self.conn = None
def test_tcp_connection(self): conn = TCPConnection() conn.start() # initial state is established self.assertEqual(conn.tcp_established, conn.current_state) event_next_state_list = [ (Event.close, conn.tcp_established), # close before open: ignored (Event.acknowledge, conn.tcp_established), # acknowledge before open: ignored (Event.open, conn.tcp_listen), # open connection (Event.acknowledge, conn.tcp_listen), # send ack (Event.open, conn.tcp_listen), # open in listen state: ignored (Event.acknowledge, conn.tcp_listen), # send ack (Event.close, conn.tcp_closed), # close connection (Event.acknowledge, conn.tcp_closed), # acknowledge after close: ignored (Event.open, conn.tcp_closed), # open after close: ignored ] for event, result_state in event_next_state_list: conn.handle_event(event) self.assertEqual(result_state, conn.current_state)