<s> import logging <EOL> import socket <EOL> import ssl <EOL> import time <EOL> import threading <EOL> import types <EOL> try : <EOL> from OpenSSL . SSL import Error as pyOpenSSLError <EOL> except ImportError : <EOL> class pyOpenSSLError ( Exception ) : <EOL> pass <EOL> from ws4py import WS_KEY , WS_VERSION <EOL> from ws4py . exc import HandshakeError , StreamClosed <EOL> from ws4py . streaming import Stream <EOL> from ws4py . messaging import Message , PingControlMessage , PongControlMessage <EOL> from ws4py . compat import basestring , unicode <EOL> DEFAULT_READING_SIZE = <NUM_LIT:2> <EOL> logger = logging . getLogger ( '<STR_LIT>' ) <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> class Heartbeat ( threading . Thread ) : <EOL> def __init__ ( self , websocket , frequency = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> threading . Thread . __init__ ( self ) <EOL> self . websocket = websocket <EOL> self . frequency = frequency <EOL> def __enter__ ( self ) : <EOL> if self . frequency : <EOL> self . start ( ) <EOL> return self <EOL> def __exit__ ( self , exc_type , exc_value , exc_tb ) : <EOL> self . stop ( ) <EOL> def stop ( self ) : <EOL> self . running = False <EOL> def run ( self ) : <EOL> self . running = True <EOL> while self . running : <EOL> time . sleep ( self . frequency ) <EOL> if self . websocket . terminated : <EOL> break <EOL> try : <EOL> self . websocket . send ( PongControlMessage ( data = '<STR_LIT>' ) ) <EOL> except socket . error : <EOL> logger . info ( "<STR_LIT>" ) <EOL> self . websocket . server_terminated = True <EOL> self . websocket . close_connection ( ) <EOL> break <EOL> class WebSocket ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , sock , protocols = None , extensions = None , environ = None , heartbeat_freq = None ) : <EOL> """<STR_LIT>""" <EOL> self . stream = Stream ( always_mask = False ) <EOL> """<STR_LIT>""" <EOL> self . protocols = protocols <EOL> """<STR_LIT>""" <EOL> self . extensions = extensions <EOL> """<STR_LIT>""" <EOL> self . sock = sock <EOL> """<STR_LIT>""" <EOL> self . _is_secure = hasattr ( sock , '<STR_LIT>' ) or hasattr ( sock , '<STR_LIT>' ) <EOL> """<STR_LIT>""" <EOL> self . client_terminated = False <EOL> """<STR_LIT>""" <EOL> self . server_terminated = False <EOL> """<STR_LIT>""" <EOL> self . reading_buffer_size = DEFAULT_READING_SIZE <EOL> """<STR_LIT>""" <EOL> self . environ = environ <EOL> """<STR_LIT>""" <EOL> self . heartbeat_freq = heartbeat_freq <EOL> """<STR_LIT>""" <EOL> self . _local_address = None <EOL> self . _peer_address = None <EOL> @ property <EOL> def local_address ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _local_address : <EOL> self . _local_address = self . sock . getsockname ( ) <EOL> if len ( self . _local_address ) == <NUM_LIT:4> : <EOL> self . _local_address = self . _local_address [ : <NUM_LIT:2> ] <EOL> return self . _local_address <EOL> @ property <EOL> def peer_address ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _peer_address : <EOL> self . _peer_address = self . sock . getpeername ( ) <EOL> if len ( self . _peer_address ) == <NUM_LIT:4> : <EOL> self . _peer_address = self . _peer_address [ : <NUM_LIT:2> ] <EOL> return self . _peer_address <EOL> def opened ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def close ( self , code = <NUM_LIT:1000> , reason = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if not self . server_terminated : <EOL> self . server_terminated = True <EOL> self . _write ( self . stream . close ( code = code , reason = reason ) . single ( mask = self . stream . always_mask ) ) <EOL> def closed ( self , code , reason = None ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> @ property <EOL> def terminated ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . client_terminated is True and self . server_terminated is True <EOL> @ property <EOL> def connection ( self ) : <EOL> return self . sock <EOL> def close_connection ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . sock : <EOL> try : <EOL> self . sock . shutdown ( socket . SHUT_RDWR ) <EOL> self . sock . close ( ) <EOL> except : <EOL> pass <EOL> finally : <EOL> self . sock = None <EOL> def ping ( self , message ) : <EOL> """<STR_LIT>""" <EOL> self . send ( PingControlMessage ( message ) ) <EOL> def ponged ( self , pong ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def received_message ( self , message ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def unhandled_error ( self , error ) : <EOL> """<STR_LIT>""" <EOL> logger . exception ( "<STR_LIT>" ) <EOL> def _write ( self , b ) : <EOL> """<STR_LIT>""" <EOL> if self . terminated or self . sock is None : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> self . sock . sendall ( b ) <EOL> def send ( self , payload , binary = False ) : <EOL> """<STR_LIT>""" <EOL> message_sender = self . stream . binary_message if binary else self . stream . text_message <EOL> if isinstance ( payload , basestring ) or isinstance ( payload , bytearray ) : <EOL> m = message_sender ( payload ) . single ( mask = self . stream . always_mask ) <EOL> self . _write ( m ) <EOL> elif isinstance ( payload , Message ) : <EOL> data = payload . single ( mask = self . stream . always_mask ) <EOL> self . _write ( data ) <EOL> elif type ( payload ) == types . GeneratorType : <EOL> bytes = next ( payload ) <EOL> first = True <EOL> for chunk in payload : <EOL> self . _write ( message_sender ( bytes ) . fragment ( first = first , mask = self . stream . always_mask ) ) <EOL> bytes = chunk <EOL> first = False <EOL> self . _write ( message_sender ( bytes ) . fragment ( last = True , mask = self . stream . always_mask ) ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % type ( payload ) ) <EOL> def _get_from_pending ( self ) : <EOL> """<STR_LIT>""" <EOL> data = b"<STR_LIT>" <EOL> pending = self . sock . pending ( ) <EOL> while pending : <EOL> data += self . sock . recv ( pending ) <EOL> pending = self . sock . pending ( ) <EOL> return data <EOL> def once ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . terminated : <EOL> logger . debug ( "<STR_LIT>" ) <EOL> return False <EOL> try : <EOL> b = self . sock . recv ( self . reading_buffer_size ) <EOL> if self . _is_secure : <EOL> b += self . _get_from_pending ( ) <EOL> except ( socket . error , OSError , pyOpenSSLError ) as e : <EOL> self . unhandled_error ( e ) <EOL> return False <EOL> else : <EOL> if not self . process ( b ) : <EOL> return False <EOL> return True <EOL> def terminate ( self ) : <EOL> """<STR_LIT>""" <EOL> s = self . stream <EOL> self . client_terminated = self . server_terminated = True <EOL> try : <EOL> if s . closing is None : <EOL> self . closed ( <NUM_LIT> , "<STR_LIT>" ) <EOL> else : <EOL> self . closed ( s . closing . code , s . closing . reason ) <EOL> finally : <EOL> self . close_connection ( ) <EOL> s . _cleanup ( ) <EOL> self . stream = None <EOL> self . environ = None <EOL> def process ( self , bytes ) : <EOL> """<STR_LIT>""" <EOL> s = self . stream <EOL> if not bytes and self . reading_buffer_size > <NUM_LIT:0> : <EOL> return False <EOL> self . reading_buffer_size = s . parser . send ( bytes ) or DEFAULT_READING_SIZE <EOL> if s . closing is not None : <EOL> logger . debug ( "<STR_LIT>" % ( s . closing . code , s . closing . reason ) ) <EOL> if not self . server_terminated : <EOL> self . close ( s . closing . code , s . closing . reason ) <EOL> else : <EOL> self . client_terminated = True <EOL> return False <EOL> if s . errors : <EOL> for error in s . errors : <EOL> logger . debug ( "<STR_LIT>" % ( error . code , error . reason ) ) <EOL> self . close ( error . code , error . reason ) <EOL> s . errors = [ ] <EOL> return False <EOL> if s . has_message : <EOL> self . received_message ( s . message ) <EOL> if s . message is not None : <EOL> s . message . data = None <EOL> s . message = None <EOL> return True <EOL> if s . pings : <EOL> for ping in s . pings : <EOL> self . _write ( s . pong ( ping . data ) ) <EOL> s . pings = [ ] <EOL> if s . pongs : <EOL> for pong in s . pongs : <EOL> self . ponged ( pong ) <EOL> s . pongs = [ ] <EOL> return True <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> self . sock . setblocking ( True ) <EOL> with Heartbeat ( self , frequency = self . heartbeat_freq ) : <EOL> s = self . stream <EOL> try : <EOL> self . opened ( ) <EOL> while not self . terminated : <EOL> if not self . once ( ) : <EOL> break <EOL> finally : <EOL> self . terminate ( ) <EOL> class EchoWebSocket ( WebSocket ) : <EOL> def received_message ( self , message ) : <EOL> """<STR_LIT>""" <EOL> self . send ( message . data , message . is_binary ) </s>
