Introduction Link to heading

websocket is a cool protocol used for bi-directional communication like notifications or chat applications. From wiki, it says

WebSocket is a computer communications protocol, providing a simultaneous two-way communication channel over a single Transmission Control Protocol (TCP) connection.

WebSocket is distinct from HTTP used to serve most webpages. Although they are different, RFC 6455 states that WebSocket “is designed to work over HTTP ports 443 and 80 as well as to support HTTP proxies and intermediaries”, thus making it compatible with HTTP. To achieve compatibility, the WebSocket handshake uses the HTTP Upgrade header[3] to change from the HTTP protocol to the WebSocket protocol.

Client Link to heading

for the client(ie browser), socket is created with WebSocket and there where it’s connected.

  • call socket.send() to send something to server.
  • onmessage attribute is callback for messages sent from the server.
<!DOCTYPE html>
<html>
  <head>
    <title>Chat</title>
  </head>

  <body>
    <h1>WebSocket with FastAPI</h1>
    <form action="" onsubmit="sendMessage(event)">
      <input type="text" id="messageText" autocomplete="off" />
      <button>Send</button>
    </form>
    <ul id="messages"></ul>
    <script>
      var ws = new WebSocket(`ws://localhost:8000/communicate`);

      console.log("Connected");
      ws.onmessage = function (event) {
        var messages = document.getElementById("messages");
        var message = document.createElement("li");
        var content = document.createTextNode(event.data);
        message.appendChild(content);
        messages.appendChild(message);
      };

      console.log("Send Mesage");
      function sendMessage(event) {
        var input = document.getElementById("messageText");
        ws.send(input.value);
        input.value = "";
        event.preventDefault();
      }
    </script>
  </body>
</html>

Server Link to heading

For the server, this is example using fastapi WebSocket interface. There is utility connection manager to keep track of connections. receive_text and send_text are called to get messages from and send messages to client connected to the socket.

from fastapi import FastAPI, WebSocket, WebSocketDisconnect


class ConnectionManager:
    def __init__(self):
        self.active_connections = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    async def send_personal_message(self, message: str, websocket: WebSocket):
        await websocket.send_text(message)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)


app = FastAPI()

manager = ConnectionManager()


@app.websocket("/communicate")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        while True:
            data = await websocket.receive_text()
            await manager.send_personal_message(f"Received:{data}", websocket)
    except WebSocketDisconnect:
        manager.disconnect(websocket)
        await manager.send_personal_message("Bye!!!", websocket)