I use asyncore to implement a publication subscription. I understand that using twisted or ZMQ may be the best solution, however in this case it should be pure python. When waiting for connections, the CPU usage is ~ 1%, as soon as the client connects to the processor load, write up to 100%. It is not discarded even after disconnecting the client.
My server class:
class Host(asyncore.dispatcher): log = logging.getLogger('Host') def __init__(self, port=7655): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind(('0.0.0.0', port,)) self.listen(5) self.clients = [] def handle_accept(self): socket, addr = self.accept() self.log.info("Aceepted client at {0}:{1}".format(addr[0], addr[1])) self.clients.append(RemoteClient(self, socket, addr)) def broadcast(self, message): self.log.info("Broadcasting message: {0}".format(message)) for client in self.clients: client.message(message)
And my handler:
class RemoteClient(asyncore.dispatcher): log = logging.getLogger('Host') def __init__(self, host, socket, address): asyncore.dispatcher.__init__(self, socket) self.host = host self.outbox = collections.deque() def message(self, message): self.outbox.append(message) def handle_write(self): if not self.outbox: return message = self.outbox.popleft() if len(message) > MAX_MESSAGE_LENGTH: raise ValueError('Message too long') self.send(message) def handle_close(self): self.host.clients.remove(self) self.log.info("Client removed from list") self.close() def handle_error(self): self.log.error("Socket error")
I tried to look for a solution, but I can not understand what is happening. Any help appreciated!
source share