def main(socket): while (True): input_length = _read_int(socket) data = socket.read(input_length) result = transform(data) resultBytes = result.encode() _write_int(len(resultBytes), socket) socket.write(resultBytes) socket.flush()
def PollSockets(self): events = self.poller.poll(0) while events: event = events.pop() fd, flag = event socket = self.fd_to_socket[fd] if socket == self.server_socket: connection, address = socket.accept() if len(self.sockets) == max_connections: print('signalk server: max connections reached!!!', len(self.sockets)) self.RemoveSocket(self.sockets[0]) # dump first socket?? socket = LineBufferedNonBlockingSocket(connection) self.sockets.append(socket) fd = socket.socket.fileno() # print('new client', address, fd) self.fd_to_socket[fd] = socket self.poller.register(fd, select.POLLIN) elif flag & (select.POLLHUP | select.POLLERR | select.POLLNVAL): self.RemoveSocket(socket) elif flag & select.POLLIN: if not socket.recv(): self.RemoveSocket(socket) while True: line = socket.readline() if not line: break try: self.HandleRequest(socket, line) except Exception as e: print('invalid request from socket', line, e) socket.send('invalid request: ' + line + '\n') # flush all sockets for socket in self.sockets: socket.flush()
def poll(self, timeout=0): # server is in subprocess if self.process != 'main process': if not self.process: self.init_process() return t0 = time.monotonic() if t0 >= self.values.persistent_timeout: self.values.store() dt = time.monotonic() - t0 if dt > .1: print('persistent store took too long!', time.monotonic() - t0) return if timeout: timeout *= 1000 # milliseconds timeout = .1 events = self.poller.poll(timeout) while events: event = events.pop() fd, flag = event connection = self.fd_to_connection[fd] if connection == self.server_socket: connection, address = connection.accept() if len(self.sockets) == max_connections: print('pypilot server: max connections reached!!!', len(self.sockets)) self.RemoveSocket(self.sockets[0]) # dump first socket?? socket = LineBufferedNonBlockingSocket(connection, address) print('server add socket', socket.address) self.sockets.append(socket) fd = socket.fileno() socket.cwatches = { 'values': True } # server always watches client values self.fd_to_connection[fd] = socket self.poller.register(fd, select.POLLIN) elif flag & (select.POLLHUP | select.POLLERR | select.POLLNVAL): if not connection in self.sockets: print('internal pipe closed, server exiting') exit(0) self.RemoveSocket(connection) elif flag & select.POLLIN: if fd in self.fd_to_pipe: if not connection.recvdata(): continue line = connection.readline( ) # shortcut since poll indicates data is ready while line: self.values.HandlePipeRequest(line, connection) line = connection.readline() continue if not connection.recvdata(): self.RemoveSocket(connection) continue while True: line = connection.readline() if not line: break try: self.values.HandleRequest(line, connection) except Exception as e: connection.write('error=invalid request: ' + line) try: print('invalid request from connection', e, line) except Exception as e2: print('invalid request has malformed string', e, e2) if not self.multiprocessing: # these pipes are not pollable as they are implemented as a simple buffer for pipe in self.pipes: while True: line = pipe.readline() if not line: break self.values.HandlePipeRequest(line, pipe) # send periodic watches self.values.send_watches() # send watches for connection in self.sockets + self.pipes: if connection.cwatches: connection.write('watch=' + pyjson.dumps(connection.cwatches) + '\n') connection.cwatches = {} # flush all sockets for socket in self.sockets: socket.flush() while True: for socket in self.sockets: if not socket.socket: print('server socket closed from flush!!') self.RemoveSocket(socket) break else: break for pipe in self.pipes: pipe.flush()