| 120 | |
| 121 | |
| 122 | class WebSocketsHandler(socketserver.StreamRequestHandler): |
| 123 | |
| 124 | magic = b'258EAFA5-E914-47DA-95CA-C5AB0DC85B11' |
| 125 | |
| 126 | def __init__(self, headers, request, client_address, server, *args, **kwargs): |
| 127 | self.headers = headers |
| 128 | self.server = server |
| 129 | self.handshake_done = False |
| 130 | self._log = logging.getLogger('remi.server.ws') |
| 131 | #self._log.setLevel(logging.DEBUG) |
| 132 | socketserver.StreamRequestHandler.__init__(self, request, client_address, server, *args, **kwargs) |
| 133 | |
| 134 | def setup(self): |
| 135 | socketserver.StreamRequestHandler.setup(self) |
| 136 | self._log.info('connection established: %r' % (self.client_address,)) |
| 137 | self.handshake_done = False |
| 138 | |
| 139 | def handle(self): |
| 140 | global clients |
| 141 | self._log.debug('handle') |
| 142 | # on some systems like ROS, the default socket timeout |
| 143 | # is less than expected, we force it to infinite (None) as default socket value |
| 144 | self.request.settimeout(None) |
| 145 | if self.handshake(): |
| 146 | while True: |
| 147 | if not self.read_next_message(): |
| 148 | clients[self.session].websockets.discard(self) |
| 149 | self.handshake_done = False |
| 150 | self._log.debug('ws ending websocket service') |
| 151 | break |
| 152 | |
| 153 | @staticmethod |
| 154 | def bytetonum(b): |
| 155 | if pyLessThan3: |
| 156 | b = ord(b) |
| 157 | return b |
| 158 | |
| 159 | def read_next_message(self): |
| 160 | # noinspection PyBroadException |
| 161 | try: |
| 162 | decoded = '' |
| 163 | fin = 0 |
| 164 | while fin == 0: |
| 165 | head = None |
| 166 | try: |
| 167 | head = self.rfile.read(2) |
| 168 | except ValueError: |
| 169 | # socket was closed, just return without errors |
| 170 | return False |
| 171 | if head is None: |
| 172 | return False |
| 173 | if len(head) < 2: |
| 174 | return False |
| 175 | opcode = head[0] & 0b1111 |
| 176 | fin = head[0] >> 7 & 1 |
| 177 | is_masked = head[1] >> 7 & 1 |
| 178 | length = self.bytetonum(head[1]) & 127 |
| 179 | |