I am using asyncore to implement a publish subscribe. I understand using twisted or ZMQ may be a better solution, however in this case it needs to be pure python. When waiting for connections the CPU usage is ~1%, as soon as a client connects the CPU usage jumps write up to 100%. It does not drop back down even after the client disconnects.
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 have tried hunting for a solution but can't seem to work out what is going on. Any help appreciated!