def run(self): """ Manager's mainloop executed from within a thread. Constantly poll for read events and, when available, call related websockets' `once` method to read and process the incoming data. If the :meth:`once() <ws4py.websocket.WebSocket.once>` method returns a `False` value, its :meth:`terminate() <ws4py.websocket.WebSocket.terminate>` method is also applied to properly close the websocket and its socket is unregistered from the poller. Note that websocket shouldn't take long to process their data or they will block the remaining websockets with data to be handled. As for what long means, it's up to your requirements. """ self.running = True while self.running: with self.lock: polled = self.poller.poll() if not self.running: break # This fixes an error in the ws4py package - not yet in the upstream # package. --Kitware # # workaround wss + cherrypy bug import itertools for ws in self.websockets.itervalues(): if hasattr(ws.sock, 'pending') and ws.sock.pending() != 0: polled = itertools.chain(polled, [ws.sock.fileno()]) for fd in polled: if not self.running: break ws = self.websockets.get(fd) if ws and not ws.terminated: if not ws.once(): with self.lock: fd = ws.sock.fileno() self.websockets.pop(fd, None) self.poller.unregister(fd) if not ws.terminated: logger.info("Terminating websocket %s" % format_addresses(ws)) ws.terminate()
def remove(self, websocket): """ Remove the given ``websocket`` from the manager. This does not call its :meth:`closed() <ws4py.websocket.WebSocket.closed>` method as it's out-of-band by your application or from within the manager's run loop. """ logger.info("Removing websocket %s" % format_addresses(websocket)) with self.lock: fd = websocket.sock.fileno() self.websockets.pop(fd, None) self.poller.unregister(fd)
def add(self, websocket): """ Manage a new websocket. First calls its :meth:`opened() <ws4py.websocket.WebSocket.opened>` method and register its socket against the poller for reading events. """ logger.info("Managing websocket %s" % format_addresses(websocket)) websocket.opened() with self.lock: fd = websocket.sock.fileno() self.websockets[fd] = websocket self.poller.register(fd)
def run(self): """ Manager's mainloop executed from within a thread. Constantly poll for read events and, when available, call related websockets' `once` method to read and process the incoming data. If the :meth:`once() <ws4py.websocket.WebSocket.once>` method returns a `False` value, its :meth:`terminate() <ws4py.websocket.WebSocket.terminate>` method is also applied to properly close the websocket and its socket is unregistered from the poller. Note that websocket shouldn't take long to process their data or they will block the remaining websockets with data to be handled. As for what long means, it's up to your requirements. """ self.running = True while self.running: with self.lock: polled = self.poller.poll() if not self.running: break for fd in polled: if not self.running: break ws = self.websockets.get(fd) if ws and not ws.terminated: if not ws.once(): with self.lock: fd = ws.sock.fileno() self.websockets.pop(fd, None) self.poller.unregister(fd) if not ws.terminated: logger.info("Terminating websocket %s" % format_addresses(ws)) ws.terminate()