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)