55import struct
66from base64 import b64encode
77from hashlib import sha1
8+ import logging
89
910if sys .version_info [0 ] < 3 :
1011 from SocketServer import ThreadingMixIn , TCPServer , StreamRequestHandler
4142CLOSE_CONN = 0x8
4243
4344
45+ # ------------------------------ Logging -------------------------------
46+ logger = logging .getLogger (__name__ )
4447
4548# -------------------------------- API ---------------------------------
4649
4750class API ():
4851 def run_forever (self ):
4952 try :
50- print ("Listening on port %d for clients.." % self .port )
53+ logger . info ("Listening on port %d for clients.." % self .port )
5154 self .serve_forever ()
5255 except KeyboardInterrupt :
5356 self .server_close ()
54- print ("Server terminated." )
57+ logger . info ("Server terminated." )
5558 except Exception as e :
56- print ("ERROR: WebSocketsServer: " + str (e ))
59+ logger . error ("ERROR: WebSocketsServer: " + str (e ), exc_info = True )
5760 exit (1 )
5861 def new_client (self , client , server ):
5962 pass
@@ -114,14 +117,14 @@ def _client_left_(self, handler):
114117 self .client_left (client , self )
115118 if client in self .clients :
116119 self .clients .remove (client )
117-
120+
118121 def _unicast_ (self , to_client , msg ):
119122 to_client ['handler' ].send_message (msg )
120123
121124 def _multicast_ (self , msg ):
122125 for client in self .clients :
123126 self ._unicast_ (client , msg )
124-
127+
125128 def handler_to_client (self , handler ):
126129 for client in self .clients :
127130 if client ['handler' ] == handler :
@@ -168,15 +171,15 @@ def read_next_message(self):
168171 payload_length = b2 & PAYLOAD_LEN
169172
170173 if not b1 :
171- print ("Client closed connection." )
174+ logger . info ("Client closed connection." )
172175 self .keep_alive = 0
173176 return
174177 if opcode == CLOSE_CONN :
175- print ("Client asked to close connection." )
178+ logger . info ("Client asked to close connection." )
176179 self .keep_alive = 0
177180 return
178181 if not masked :
179- print ("Client must always be masked." )
182+ logger . info ("Client must always be masked." )
180183 self .keep_alive = 0
181184 return
182185
@@ -201,17 +204,17 @@ def send_text(self, message):
201204 Fragmented(=continuation) messages are not being used since their usage
202205 is needed in very limited cases - when we don't know the payload length.
203206 '''
204-
207+
205208 # Validate message
206209 if isinstance (message , bytes ):
207210 message = try_decode_UTF8 (message ) # this is slower but assures we have UTF-8
208211 if not message :
209- print ("Can\' t send message, message is not valid UTF-8" )
212+ logger . warning ("Can\' t send message, message is not valid UTF-8" )
210213 return False
211214 elif isinstance (message , str ) or isinstance (message , unicode ):
212215 pass
213216 else :
214- print ('Can\' t send message, message has to be a string or bytes. Given type is %s' % type (message ))
217+ logger . warning ('Can\' t send message, message has to be a string or bytes. Given type is %s' % type (message ))
215218 return False
216219
217220 header = bytearray ()
@@ -234,7 +237,7 @@ def send_text(self, message):
234237 header .append (FIN | OPCODE_TEXT )
235238 header .append (PAYLOAD_LEN_EXT64 )
236239 header .extend (struct .pack (">Q" , payload_length ))
237-
240+
238241 else :
239242 raise Exception ("Message is too big. Consider breaking it into chunks." )
240243 return
@@ -251,22 +254,22 @@ def handshake(self):
251254 if key :
252255 key = key .group (1 )
253256 else :
254- print ("Client tried to connect but was missing a key" )
257+ logging . warning ("Client tried to connect but was missing a key" )
255258 self .keep_alive = False
256259 return
257260 response = self .make_handshake_response (key )
258261 self .handshake_done = self .request .send (response .encode ())
259262 self .valid_client = True
260263 self .server ._new_client_ (self )
261-
264+
262265 def make_handshake_response (self , key ):
263266 return \
264267 'HTTP/1.1 101 Switching Protocols\r \n ' \
265268 'Upgrade: websocket\r \n ' \
266269 'Connection: Upgrade\r \n ' \
267270 'Sec-WebSocket-Accept: %s\r \n ' \
268271 '\r \n ' % self .calculate_response_key (key )
269-
272+
270273 def calculate_response_key (self , key ):
271274 GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
272275 hash = sha1 (key .encode () + GUID .encode ())
@@ -282,7 +285,7 @@ def encode_to_UTF8(data):
282285 try :
283286 return data .encode ('UTF-8' )
284287 except UnicodeEncodeError as e :
285- print ("Could not encode data to UTF-8 -- %s" % e )
288+ logging . error ("Could not encode data to UTF-8 -- %s" % e )
286289 return False
287290 except Exception as e :
288291 raise (e )
@@ -297,7 +300,7 @@ def try_decode_UTF8(data):
297300 return False
298301 except Exception as e :
299302 raise (e )
300-
303+
301304
302305
303306# This is only for testing purposes
0 commit comments