3838PAYLOAD_LEN_EXT16 = 0x7e
3939PAYLOAD_LEN_EXT64 = 0x7f
4040
41- OPCODE_TEXT = 0x01
42- CLOSE_CONN = 0x8
43-
41+ OPCODE_CONTINUATION = 0x0
42+ OPCODE_TEXT = 0x1
43+ OPCODE_BINARY = 0x2
44+ OPCODE_CLOSE_CONN = 0x8
45+ OPCODE_PING = 0x9
46+ OPCODE_PONG = 0xA
4447
4548# ------------------------------ Logging -------------------------------
4649logger = logging .getLogger (__name__ )
@@ -102,6 +105,12 @@ def __init__(self, port, host='127.0.0.1'):
102105 def _message_received_ (self , handler , msg ):
103106 self .message_received (self .handler_to_client (handler ), self , msg )
104107
108+ def _ping_received_ (self , handler , msg ):
109+ handler .send_pong (msg )
110+
111+ def _pong_received_ (self , handler , msg ):
112+ pass
113+
105114 def _new_client_ (self , handler ):
106115 self .id_counter += 1
107116 client = {
@@ -174,12 +183,28 @@ def read_next_message(self):
174183 logger .info ("Client closed connection." )
175184 self .keep_alive = 0
176185 return
177- if opcode == CLOSE_CONN :
186+ if opcode == OPCODE_CLOSE_CONN :
178187 logger .info ("Client asked to close connection." )
179188 self .keep_alive = 0
180189 return
181190 if not masked :
182- logger .info ("Client must always be masked." )
191+ logger .warn ("Client must always be masked." )
192+ self .keep_alive = 0
193+ return
194+ if opcode == OPCODE_CONTINUATION :
195+ logger .warn ("Continuation frames are not supported." )
196+ return
197+ elif opcode == OPCODE_BINARY :
198+ logger .warn ("Binary frames are not supported." )
199+ return
200+ elif opcode == OPCODE_TEXT :
201+ opcode_handler = self .server ._message_received_
202+ elif opcode == OPCODE_PING :
203+ opcode_handler = self .server ._ping_received_
204+ elif opcode == OPCODE_PONG :
205+ opcode_handler = self .server ._pong_received_
206+ else :
207+ logger .warn ("Unknown opcode %#x." + opcode )
183208 self .keep_alive = 0
184209 return
185210
@@ -193,12 +218,15 @@ def read_next_message(self):
193218 for char in self .read_bytes (payload_length ):
194219 char ^= masks [len (decoded ) % 4 ]
195220 decoded += chr (char )
196- self . server . _message_received_ (self , decoded )
221+ opcode_handler (self , decoded )
197222
198223 def send_message (self , message ):
199224 self .send_text (message )
200225
201- def send_text (self , message ):
226+ def send_pong (self , message ):
227+ self .send_text (message , OPCODE_PONG )
228+
229+ def send_text (self , message , opcode = OPCODE_TEXT ):
202230 '''
203231 NOTES
204232 Fragmented(=continuation) messages are not being used since their usage
@@ -223,18 +251,18 @@ def send_text(self, message):
223251
224252 # Normal payload
225253 if payload_length <= 125 :
226- header .append (FIN | OPCODE_TEXT )
254+ header .append (FIN | opcode )
227255 header .append (payload_length )
228256
229257 # Extended payload
230258 elif payload_length >= 126 and payload_length <= 65535 :
231- header .append (FIN | OPCODE_TEXT )
259+ header .append (FIN | opcode )
232260 header .append (PAYLOAD_LEN_EXT16 )
233261 header .extend (struct .pack (">H" , payload_length ))
234262
235263 # Huge extended payload
236264 elif payload_length < 18446744073709551616 :
237- header .append (FIN | OPCODE_TEXT )
265+ header .append (FIN | opcode )
238266 header .append (PAYLOAD_LEN_EXT64 )
239267 header .extend (struct .pack (">Q" , payload_length ))
240268
0 commit comments