Create websocket service and client request using Python

1 What is WebSocket

This paragraph is from the rookie tutorial - WebSocket .
Like HTTP, WebSocket is also a communication protocol that allows the server to actively push data to the client.
In the WebSocket API , the browser and the server only need to complete one handshake, and a persistent connection can be created directly between the two, and two-way data transmission can be performed.

There are many websites that use Ajax polling to implement push technology . Polling is a specific time interval (such as every 1 second), the browser sends an HTTP request to the server, and then the server returns the latest data to the client's browser. This traditional mode brings obvious disadvantages, that is, the browser needs to continuously send requests to the server. However, the HTTP request may contain a long header, and the really valid data may be only a small part, which is obviously a waste of money. A lot of bandwidth and other resources.

The WebSocket protocol defined by HTML5 can better save server resources and bandwidth, and can communicate in more real-time.

2 C/S architecture of WebSocket

insert image description here
The server starts the service for receiving WebSocket requests, the client establishes a Websocket connection and sends a request (Message). After the server receives it, it can send messages to the client on demand according to the processing logic, such as sending active push.

3 Python websockets library

Python websockets is a library for building WebSocket servers and clients in Python. It is built on asyncio asynchronous IO and provides a coroutine-based API.
Please try to use Python≥3.6 version to run websockets.
Install websockets:

pip3 install websockets
  • 1

The main APIs used are:

websockets.connect()
websockets.send()
websockets.recv()
  • 1
  • 2
  • 3

4 Simple examples

server.py, used to build a websocket server, start on the local port 8765, and add the received message to theI got your message:Go back.

import asyncio
import websockets


async def echo(websocket, path):
    async for message in websocket:
        message = "I got your message: {}".format(message)
        await websocket.send(message)


asyncio.get_event_loop().run_until_complete(websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

client.pyEstablish a websocket connection with the specified url, send a message, then wait for a message to be received, and print the message.

import asyncio
import websockets


async def hello(uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send("Hello world!")
        recv_text = await websocket.recv()
        print(recv_text)


asyncio.get_event_loop().run_until_complete(
    hello('ws://localhost:8765'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Execute server.py first, and then execute client.py. The output of client.py is as follows:

I got your message: Hello world!
  • 1

5 Actively send a message

After the connection is established, the client can receive messages from the server at any time. The server can push the specified message to the client according to the logic.
There will be a little change in the server and client code. After the server returns the first message, it will start polling the time. When the number of seconds reaches 0, it will actively return a message to the client.
server.py:

import asyncio
import websockets
import time


async def echo(websocket, path):
    async for message in websocket:
        message = "I got your message: {}".format(message)
        await websocket.send(message)

        while True:
            t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            if str(t).endswith("0"):
                await websocket.send(t)
                break


asyncio.get_event_loop().run_until_complete(
    websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

client.py:

import asyncio
import websockets


async def hello(uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send("Hello world!")
        print("< Hello world!")
        while True:
            recv_text = await websocket.recv()
            print("> {}".format(recv_text))


asyncio.get_event_loop().run_until_complete(
    hello('ws://localhost:8765'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Execute server.py first, and then execute client.py. The output of client.py is as follows:

< Hello world!
> I got your message: Hello world!
> 2020-05-29 15:11:50
  • 1
  • 2
  • 3

The last message is actively sent by the server to the client.

6 Use on the browser

How to send websocket requests on the front end?
Look at this code, first establish a connection, then send Hello world to the server, and then display all the received messages in turn.

<!DOCTYPE HTML> 
< html > 
< head > 
    < meta  charset = " utf-8 " > 
    < title > websocket communication client </ title > 
    < script  src = " jquery-3.5.0.min.js " ></ script > 
    < script  type = " text/javascript " > function WebSocketTest ( ) { if ( "WebSocket" in window ) { // open a web socket var ws = new WebSocket ( "ws://127.0.0.1:8765 " ) ; // Callback function 
                ws after connection is established . onopen = function ( ) { // Web Socket is connected, use send() method to send data 
                    ws .
          
               
                
                  
                    
                    send("Hello world!");
                    $("#main").append("<p>" + "<=" + "Hello world!" + "</p>")
                };

                // callback function after server message is received 
                ws . onmessage  =  function  ( evt )  { 
                    var received_msg = evt . data ; 
                    if  ( received_msg . indexOf ( "sorry" )  ==  - 1 )  { 
                        $ ( "#main" ) . append ( "<p>"  +  "=>"  + received_msg +  "</p>" ) 
                    } 
                } ; 
                // callback function after the connection is closed
                ws .onclose =  function ( )  { // close websocket alert ( "The connection is closed..." ) ; } ; } else { // Browser does not support WebSocket alert ( "Your browser does not support WebSocket!" ) ; } }   
                    
                    
                
              
                
                
            
        
    </ script > 
</ head > 
< body  onload = " WebSocketTest() " > 
< div  id = " main " > 
</div>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

The effect is roughly like this:
insert image description here
you can grab the websocket package at the beginning:
insert image description here
you can clearly see each message here.

Related: Create websocket service and client request using Python