Home » Python

Basic concepts of WebSocket server in Python

Python WebSocket server: Here, we are going to learn about the basic concepts of WebSocket server in Python like what is WebSocket server, where and when to use it, python WebSocket libraries, etc.
Submitted by Sapna Deraje Radhakrishna, on September 20, 2019

What is a WebSocket server?

In simple words, a WebSocket server is an application listening on any TCP port server that follows a protocol call WS (or WSS).

Often, a reverse proxy such as an HTTP server is used to detect Websocket handshakes, process them, and send those clients to the WebSocket server. The WebSocket protocol was designed to work well with existing web infrastructure. As part of this design principle, the WebSocket connection starts as an HTTP connection, with full backward compatibility with the pre-WebSocket world. The protocol shift from HTTP to WebSocket is referred to as handshake.

The client sends an Upgrade header:

    --- request header ---
    GET / HTTP/1.1
    Upgrade: websocket
    Connection: Upgrade
    Host: localhost:4040
    Origin: http://localhost:4040
    Sec-WebSocket-Key: q0+vBfXgMvGGywjDaHZWiw==
    Sec-WebSocket-Version: 13

If the server understands, the WebSocket protocol, it agrees to the protocol switch through the upgrade header.

    -----------------------
    --- response header ---
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: /YqMq5iNGOMjtELPGCZsnozMSlw=
    Date: Sun, 15 Sep 2019 23:34:04 GMT
    Server: Python/3.7 websockets/8.0.2
    -----------------------

At this point, the HTTP connection breaks down and is replaced by a WebSocket connection over the underlying TCP/IP connection. The WebSocket, similar to HTTP, uses HTTP (80) and HTTPS (443) by default.

Where and When to use WebSockets?

  1. Real-time applications – when the UI needs to be updated without the client request for data. Here WebSockets are faster than using the traditional AJAX polling, which uses HTTP
  2. Gaming Applications
  3. Chat Applications

When not to use WebSockets?

Real-time updates are not required. The WebSockets, since keeps the connection alive until one of the components closes the connection. Instead, RESTful services are sufficient to get the data from the server.

Using python libraries to implement a WebSocket server

Python provides many libraries to implement the WebSocket server. Following are the few of many available in the market. These libraries can be easily installed through Pypi within the virtual environment or in Anaconda environment.

Example code for implementing the WebSocket server

1) Using WebSockets library (ws_server.py)

import asyncio
import websockets
import time
import json

async def say_hello(websocket, path):
    while True:
        await websocket.send("hello world")
        time.sleep(10)

# the server starts up in localhost and port 4040
start_server = websockets.serve(say_hello,'localhost',4040)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

2) Using tornado library (tornado_ws_server.py)

'''
    This module hosts a websocket server using tornado
    libraries
'''
import tornado.web
import tornado.httpserver
import tornado.ioloop
import tornado.websocket as ws
from tornado.options import define, options
import time

define('port', default=4041, help='port to listen on')


class web_socket_handler(ws.WebSocketHandler):
    '''
    This class handles the websocket channel
    '''
    @classmethod
    def route_urls(cls):
        return [(r'/',cls, {}),]
    
    def simple_init(self):
        self.last = time.time()
        self.stop = False

    
    def open(self):
        '''
            client opens a connection
        '''
        self.simple_init()
        print("New client connected")
        self.write_message("You are connected")

        
    def on_message(self, message):
        '''
            Message received on the handler
        '''
        print("received message {}".format(message))
        self.write_message("You said {}".format(message))
        self.last = time.time()
    
    def on_close(self):
        '''
            Channel is closed
        '''
        print("connection is closed")

    
    def check_origin(self, origin):
        return True


def initiate_server():
    #create a tornado application and provide the urls
    app = tornado.web.Application(web_socket_handler.route_urls())
    
    #setup the server
    server = tornado.httpserver.HTTPServer(app)
    server.listen(options.port)
    
    #start io/event loop
    tornado.ioloop.IOLoop.instance().start()


if __name__ == '__main__':
    initiate_server()

Setup the environment to implement a WebSocket server

  • Create a virtual environment
    -bash-4.2$ python3 -m venv venv
  • Source (or activate) the virtual environment
    -bash-4.2$ source venv/bin/activate
  • Install the required library using pip
  • 	(venv) -bash-4.2$ pip3 install websockets
    Collecting websockets
      Downloading https://files.pythonhosted.org/packages/f0/4b/ad228451b1c071c5c52616b7d4298ebcfcac5ae8515ede959db19e4cd56d/websockets-8.0.2-cp36-cp36m-manylinux1_x86_64.whl (72kB)
        100% |████████████████████████████████| 81kB 2.1MB/s
    Installing collected packages: websockets
    Successfully installed websockets-8.0.2
     (venv) -bash-4.2$
    	
    (venv) -bash-4.2$ pip3 install tornado
    Collecting tornado
      Using cached https://files.pythonhosted.org/packages/30/78/2d2823598496127b21423baffaa186b668f73cd91887fcef78b6eade136b/tornado-6.0.3.tar.gz
    Installing collected packages: tornado
      Running setup.py install for tornado ... done
    Successfully installed tornado-6.0.3
     (venv) -bash-4.2$
    
    Execute the sample websocket server
    	Python3 tornado_ws_server.py
    		Or 
    	Python3 ws_server.py
    

Wireshark traces of the client server interaction

web socket in Python

References:



Comments and Discussions!

Load comments ↻





Copyright © 2024 www.includehelp.com. All rights reserved.