<commit_before>TwistedWebsocket
================

Websocket server protocol implementation based on Twisted.

Requirements
------------

-  Python 2.7+
-  Twisted

Installation
------------

::
    
    pip install TwistedWebsocket

Testing
-------

::
    
    python setup.py test

    
Built-in broadcast server
-------------------------

A server is already integrated into TwistedWebsocket package. Default listening port is 9999

::

    python -m TwistedWebsocket.server [PORT]


API
---

Frame manager

-  ``TwistedWebsocket.frame.Frame(buf)``: Create Frame instance
-  ``TwistedWebsocket.frame.Frame.message()``: Return decoded message from frame instance
-  ``TwistedWebsocket.frame.Frame.length()``: Return frame length from frame instance
-  ``TwistedWebsocket.frame.Frame.buildMessage(msg, mask=True)``: (@staticmethod) Create a websocket compatible frame. If mask == True, it will be a client->server frame.

Server Protocol

-  ``TwistedWebsocket.server.Protocol.onHandshake(header)``: Callback when HTTP-like client header is received
-  ``TwistedWebsocket.server.Protocol.onConnect()``: Callback when the client is connected
-  ``TwistedWebsocket.server.Protocol.onDisconnect()``: Callback when the client is disconnected
-  ``TwistedWebsocket.server.Protocol.onMessage(msg)``: Callback when the client receive a message
-  ``TwistedWebsocket.server.Protocol.sendMessage(msg)``: Send a message to the client
-  ``TwistedWebsocket.server.Protocol.users``: Dictionnary ( self == self.clients[self.id] ) off all the clients connected to the server
-  ``TwistedWebsocket.server.Protocol.id``: Client UUID4 id

Exceptions

-  ``TwistedWebsocket.exception.FrameError``
-  ``TwistedWebsocket.exception.ProtocolError``


Default Implementation
----------------------

Broadcast server example:

::

    from twisted.internet.protocol import Factory
    from twisted.internet import reactor
    from TwistedWebsocket.server import Protocol
    import re


    class WebSocketHandler(Protocol):

      def onHandshake(self, header):
        g = re.search('Origin\s*:\s*(\S+)', header)
        if not g: return
        print "\n[HANDSHAKE] %s origin : %s" % (self.id, g.group(1))

      def onConnect(self):
        print "\n[CONNEXION] %s connected" % self.id
        for _id, user in self.users.items():
          user.sendMessage("%s connected" % self.id)
          print "\n[FRAME] from %s to %s:\n%s connected" % (self.id, _id, self.id)

      def onDisconnect(self):
        print "\n[DISCONNEXION] %s disconnected" % self.id
        for _id, user in self.users.items():
          user.sendMessage("%s disconnected" % self.id)
          print "\n[FRAME] from %s to %s:\n%s disconnected" % (self.id, _id, self.id)

      def onMessage(self, msg):
        for _id, user in  self.users.items():
          user.sendMessage(msg)
          print "\n[FRAME] from %s to %s:\n%s" % (self.id, _id, msg)


    class WebSocketFactory(Factory):
      
      def __init__(self):
        self.users = {}
      
      def buildProtocol(self, addr):
        return WebSocketHandler(self.users)


    reactor.listenTCP(9999, WebSocketFactory())
    reactor.run()


TODO
----

-  Improve frame building
-  Add WSS example with self-signed certificates<commit_msg>Update REAME for ssl support.<commit_after>TwistedWebsocket
================

Websocket server protocol implementation based on Twisted.

Requirements
------------

-  Python 2.7+
-  Twisted

Installation
------------

::
    
    pip install TwistedWebsocket

Testing
-------

::
    
    python setup.py test

    
Built-in broadcast server
-------------------------

A server is already integrated into TwistedWebsocket package. Default listening port is 9999

::

    python -m TwistedWebsocket.server [PORT]


API
---

Frame manager

-  ``TwistedWebsocket.frame.Frame(buf)``: Create Frame instance
-  ``TwistedWebsocket.frame.Frame.message()``: Return decoded message from frame instance
-  ``TwistedWebsocket.frame.Frame.length()``: Return frame length from frame instance
-  ``TwistedWebsocket.frame.Frame.buildMessage(msg, mask=True)``: (@staticmethod) Create a websocket compatible frame. If mask == True, it will be a client->server frame.

Server Protocol

-  ``TwistedWebsocket.server.Protocol.onHandshake(header)``: Callback when HTTP-like client header is received
-  ``TwistedWebsocket.server.Protocol.onConnect()``: Callback when the client is connected
-  ``TwistedWebsocket.server.Protocol.onDisconnect()``: Callback when the client is disconnected
-  ``TwistedWebsocket.server.Protocol.onMessage(msg)``: Callback when the client receive a message
-  ``TwistedWebsocket.server.Protocol.sendMessage(msg)``: Send a message to the client
-  ``TwistedWebsocket.server.Protocol.users``: Dictionnary ( self == self.clients[self.id] ) off all the clients connected to the server
-  ``TwistedWebsocket.server.Protocol.id``: Client UUID4 id

Exceptions

-  ``TwistedWebsocket.exception.FrameError``
-  ``TwistedWebsocket.exception.ProtocolError``


Default Implementation
----------------------

Broadcast server example:

::

    from twisted.internet.protocol import Factory
    from twisted.internet import reactor
    from TwistedWebsocket.server import Protocol
    import re


    class WebSocketHandler(Protocol):

      def onHandshake(self, header):
        g = re.search('Origin\s*:\s*(\S+)', header)
        if not g: return
        print "\n[HANDSHAKE] %s origin : %s" % (self.id, g.group(1))

      def onConnect(self):
        print "\n[CONNEXION] %s connected" % self.id
        for _id, user in self.users.items():
          user.sendMessage("%s connected" % self.id)
          print "\n[FRAME] from %s to %s:\n%s connected" % (self.id, _id, self.id)

      def onDisconnect(self):
        print "\n[DISCONNEXION] %s disconnected" % self.id
        for _id, user in self.users.items():
          user.sendMessage("%s disconnected" % self.id)
          print "\n[FRAME] from %s to %s:\n%s disconnected" % (self.id, _id, self.id)

      def onMessage(self, msg):
        for _id, user in  self.users.items():
          user.sendMessage(msg)
          print "\n[FRAME] from %s to %s:\n%s" % (self.id, _id, msg)


    class WebSocketFactory(Factory):
      
      def __init__(self):
        self.users = {}
      
      def buildProtocol(self, addr):
        return WebSocketHandler(self.users)


    reactor.listenTCP(9999, WebSocketFactory())
    reactor.run()


WSS support:
------------

::

    from twisted.internet.protocol import Factory
    from twisted.internet import reactor, ssl
    from TwistedWebsocket.server import Protocol
    import re

    class WebSocketHandler(Protocol):
      ...

    class WebSocketFactory(Factory):
      ...

    with open("./keys/ssl.localhost.key") as keyFile:
        with open("./keys/ssl.localhost.cert") as certFile:
          cert = ssl.PrivateCertificate.loadPEM(keyFile.read() + certFile.read())

    reactor.listenSSL(PORT, WebSocketFactory(), cert.options())
    reactor.run()


Generate self-signed SSL certificates:

::

    $> openssl genrsa -out ./keys/ssl.localhost.key 2048
    $> openssl req -new -x509 -key ./keys/ssl.localhost.key -out ./keys/ssl.localhost.cert -days 3650 -subj /CN=ssl.localhost

TODO
----

-  Improve frame building
-  Add WSS example with self-signed certificates
{'fraction_non_alphanumeric': 0.14129692832764504, 'fraction_numerical': 0.00477815699658703, 'mean_word_length': 2.9967266775777412, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2032857', 'n_tokens_mistral': 2239, 'n_tokens_neox': 2198, 'n_words': 590}