Pernahkah kamu membuka aplikasi chat, dashboard saham, atau game online dan melihat data diperbarui seketika tanpa perlu me-refresh halaman? Di balik pengalaman itu ada teknologi bernama WebSocket. Berbeda dengan HTTP biasa yang bersifat request–response satu arah (kamu sudah mengenal konsep ini di pengertian REST API), WebSocket membuka kanal komunikasi dua arah yang persisten antara browser dan server. Dalam tutorial ini, kita akan membangun aplikasi real-time dari nol menggunakan FastAPI dan Python, mulai dari server echo sederhana hingga aplikasi chat multi-klien yang bisa langsung kamu coba.
Kenapa WebSocket dan Bukan HTTP Polling?
Untuk memahami kenapa WebSocket begitu penting, bayangkan kamu membuat fitur notifikasi live. Dengan HTTP biasa, klien harus terus-menerus bertanya ke server (teknik ini disebut polling), yang boros bandwidth dan menambah latensi. WebSocket justru membuka satu koneksi TCP yang tetap hidup: begitu ada data baru, server langsung mengirimkannya ke klien tanpa diminta. Karena FastAPI dibangun di atas asyncio, banyak koneksi WebSocket bisa ditangani secara efisien dalam satu proses — konsep yang sudah kita bahas di artikel menguasai async/await dan asyncio.
Prasyarat dan Instalasi
Pastikan Python 3.8+ sudah terpasang di komputermu. Kita akan memakai FastAPI sebagai framework web dan Uvicorn sebagai server ASGI. Jika kamu baru pertama kali mengenal FastAPI, sempatkan membaca tutorial membuat REST API dengan FastAPI terlebih dahulu agar lebih nyaman dengan pola kodenya.
pip install "fastapi[standard]"
Paket fastapi[standard] sudah menyertakan Uvicorn dan library websockets, jadi kamu tidak perlu menginstal dependensi tambahan.
Langkah 1: Membuat Server WebSocket Echo
Buat file bernama main.py dan tulis kode berikut. Ini adalah server WebSocket paling sederhana: ia menerima koneksi, lalu mengirim balik (echo) setiap pesan yang diterima.
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
Langkah 2: Menjalankan Server
Jalankan server dengan Uvicorn:
uvicorn main:app --reload
Server kini berjalan di http://localhost:8000, dan endpoint WebSocket tersedia di ws://localhost:8000/ws. Perhatikan bahwa skema URL-nya adalah ws://, bukan http://.
Langkah 3: Menguji dengan Klien Python
Untuk memastikan server bekerja, tulis klien kecil menggunakan library websockets (sudah ikut terpasang lewat fastapi[standard]):
import asyncio
import websockets
async def main():
async with websockets.connect("ws://localhost:8000/ws") as ws:
await ws.send("Halo, BengkelKode!")
balasan = await ws.recv()
print(balasan)
asyncio.run(main())
Tips: Karena websocket_endpoint adalah coroutine async, proses menerima dan mengirim pesan tidak memblokir event loop. Satu proses Uvicorn bisa melayani ribuan koneksi WebSocket sekaligus — inilah kekuatan asyncio di balik layar.
Langkah 4: Membangun Aplikasi Chat Multi-Klien
Server echo belum terlalu berguna. Mari kita tingkatkan menjadi aplikasi chat: setiap pesan dari satu klien akan disiarkan (broadcast) ke semua klien yang terhubung. Kuncinya adalah sebuah ConnectionManager yang menyimpan daftar koneksi aktif.
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
app = FastAPI()
class ConnectionManager:
def __init__(self):
self.active_connections: list[WebSocket] = []
async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)
def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)
async def broadcast(self, message: str):
for connection in self.active_connections:
await connection.send_text(message)
manager = ConnectionManager()
@app.websocket("/ws/chat")
async def chat_endpoint(websocket: WebSocket):
await manager.connect(websocket)
try:
while True:
data = await websocket.receive_text()
await manager.broadcast(f"Pesan: {data}")
except WebSocketDisconnect:
manager.disconnect(websocket)
Langkah 5: Klien Browser dengan JavaScript
Simpan file HTML berikut lalu buka langsung di browser. Browser sudah punya API WebSocket bawaan, jadi tidak perlu library tambahan. Buka dua tab sekaligus untuk melihat pesan terkirim real-time di antara keduanya.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Chat WebSocket</title>
</head>
<body>
<h1>Chat Room</h1>
<div id="messages"></div>
<input id="message" type="text" placeholder="Tulis pesan...">
<button onclick="sendMessage()">Kirim</button>
<script>
const ws = new WebSocket("ws://localhost:8000/ws/chat");
ws.onmessage = (event) => {
const div = document.createElement("div");
div.textContent = event.data;
document.getElementById("messages").appendChild(div);
};
function sendMessage() {
const input = document.getElementById("message");
ws.send(input.value);
input.value = "";
}
</script>
</body>
</html>
Menangani Koneksi yang Putus dan Error
Dalam kode di atas, kita menangkap WebSocketDisconnect agar koneksi yang ditutup dihapus dari daftar aktif. Tanpa ini, broadcast akan mencoba mengirim ke koneksi yang sudah mati dan memunculkan error. Selalu tangani kasus ini pada aplikasi produksi.
Catatan Penting untuk Production
Ketika naik ke produksi, ada beberapa hal yang perlu diperhatikan. Secara bawaan, Uvicorn yang dijalankan dengan beberapa worker akan membuat ConnectionManager terpisah di tiap proses, sehingga klien di worker berbeda tidak bisa saling terhubung. Solusinya adalah memakai message broker seperti Redis (pub/sub) untuk menyinkronkan pesan antar-worker.
Peringatan: Jangan menjalankan server WebSocket dengan banyak worker tanpa broker seperti Redis. Klien yang tersebar di worker berbeda akan kehilangan pesan satu sama lain. Mulailah dengan satu worker saat development, lalu tambahkan Redis pub/sub ketika skala aplikasimu bertambah.
Kesimpulan
Kamu baru saja membangun aplikasi real-time dengan WebSocket di Python menggunakan FastAPI — dari server echo, klien penguji, hingga chat multi-klien lengkap dengan klien browser. Konsep ini menjadi fondasi untuk notifikasi live, dashboard real-time, game multiplayer, dan kolaborasi daring. Langkah selanjutnya yang seru: gabungkan WebSocket dengan autentikasi, atau kirim data terstruktur dengan JSON. Selamat berkarya! 🚀