- Lichess adalah platform catur open source gratis dengan jutaan pemain di seluruh dunia
- Menggunakan tab Network di Chrome DevTools untuk memantau komunikasi antara klien dan server
Koneksi WebSocket
- Aktivitas jaringan pertama yang patut diperhatikan adalah koneksi WebSocket ke URL yang mirip seperti berikut:
wss://socket2.lichess.org/play/H5uHz0egyvIA/v6?sri=bt6QzcyOiZg5&v=0
- Protokol
wssmenunjukkan koneksi WebSocket terenkripsi yang menggunakan TLS - WebSocket memungkinkan komunikasi full-duplex sehingga pembaruan real-time antara klien dan server dapat dilakukan tanpa permintaan HTTP berulang
Giliran pemain lokal
- Saat sebuah aksi dilakukan, paket data dipertukarkan:
// Dikirim pada 22:51:35.280
{
"t": "move",
"d": {
"u": "d2d4",
"l": 32,
"a": 1
}
}
- Pesan yang diterima dari server:
// Diterima pada 22:51:35.312
{
"t": "ack",
"d": 1
}
- Ini memberi tahu bahwa server telah menerima aksi kita
// Diterima pada 22:51:35.312
{
"t": "move",
"v": 1,
"d": {
"uci": "d2d4",
"san": "d4",
"fen": "rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR",
"ply": 1,
"clock": {
"white": 300,
"black": 300
}
}
}
- Pesan ini memberikan informasi rinci tentang aksi yang kita lakukan dan status permainan yang telah diperbarui
Giliran lawan
- Saat lawan bergerak, paket serupa diterima dari server:
// Diterima pada 22:51:43.489
{
"t": "move",
"v": 2,
"d": {
"uci": "d7d5",
"san": "d5",
"fen": "rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR",
"ply": 2,
"dests": {
"c2": "c3c4",
"g2": "g3g4"
// Langkah tambahan yang mungkin
},
"clock": {
"white": 300,
"black": 300
}
}
}
- Parameter
destsmencantumkan semua langkah yang tersedia dari posisi saat ini
Arsitektur Lichess
- Sistem permainan real-time Lichess terutama terdiri dari dua layanan utama (keduanya ditulis dalam Scala):
lila: layanan inti yang mengelola logika permainan, status, interaksi pengguna, dan fungsi inti lainnyalila-ws: layanan khusus penanganan WebSocket yang berperan sebagai jembatan antara klien danlila
Gambaran umum arsitektur
lila <-> redis <-> lila-ws <-> websocket <-> client
lilaberkomunikasi denganlila-wsmelalui Redis, danlila-wsmengelola koneksi WebSocket dengan klien
Komunikasi menggunakan Redis Pub/Sub
- Event langkah dipublikasikan ke channel Redis Pub/Sub, yang kemudian dilanggan oleh
lilauntuk memproses langkah tersebut - Redis Pub/Sub menyediakan pengiriman at-most-once. Kehilangan pesan dimungkinkan, tetapi penggunaan memori berkurang
Persistensi data akhir dengan MongoDB
lilamenyimpan status permainan ke MongoDB, tetapi tidak langsung menyimpan setiap langkah tunggal- Sebagai gantinya, langkah-langkah dibuffer dan disimpan secara berkala untuk mengurangi beban DB
- Saat event penting terjadi, status permainan akan di-flush
Bergabung ke permainan yang sedang berlangsung
- Saat pemain terhubung, mereka memberikan parameter
vuntuk memberi tahu sistem tentang versi terbaru permainan yang mereka ketahui lila-wsmenggunakanConcurrentHashMapuntuk melacak dan mengelola semua event dari permainan yang sedang berlangsung
Penutup
Proses langkah di Lichess dapat diringkas sebagai berikut:
- Klien membuat koneksi WebSocket ke
lila-ws - Saat pemain melakukan langkah, klien mengirim event langkah ke
lila-ws lila-wsmengirim responsackuntuk mengonfirmasi penerimaan langkah- Event langkah dipublikasikan ke channel Redis Pub/Sub dan diproses oleh
lila lilamenerima langkah, memperbarui status permainan, lalu pada akhirnya menyimpannya ke MongoDB. Status permainan yang telah diperbarui dikirim kembali ke klien melaluilila-ws- Klien menerima status permainan yang telah diperbarui yang mencerminkan langkah baru dan perubahan status permainan
Pendapat GN⁺
- Tulisan ini membahas secara rinci arsitektur backend dan proses yang memungkinkan gameplay real-time di lichess.org, platform catur open source yang populer
- Tulisan ini memperkenalkan elemen teknis utama yang perlu dipertimbangkan saat membangun aplikasi web real-time, misalnya komunikasi real-time dengan WebSocket, pengiriman pesan yang skalabel melalui Redis Pub/Sub, dan penyimpanan data akhir dengan MongoDB
- Arsitektur Lichess sangat cocok untuk game multipemain real-time, tetapi pola dan teknologi serupa juga dapat diterapkan pada jenis aplikasi web real-time lain seperti chat, alat kolaborasi, dan feed media sosial
- Fitur real-time dapat meningkatkan pengalaman dan interaksi pengguna, tetapi juga menimbulkan tantangan teknis tersendiri seperti skalabilitas, keandalan, dan konsistensi data. Tulisan ini menawarkan strategi untuk mengatasi tantangan tersebut
- Proyek open source dengan stack teknologi serupa antara lain Socket.IO (framework aplikasi real-time berbasis Node.js) dan RethinkDB (database NoSQL yang dioptimalkan untuk aplikasi web real-time)
- Analisis dalam tulisan ini tidak didasarkan pada peninjauan langsung terhadap source code Lichess, sehingga implementasi nyatanya mungkin berbeda. Namun, konsep dasar dan pola arsitektur yang dijelaskan tetap relevan
- Saat merancang sistem real-time, perlu dipertimbangkan dengan saksama apakah pengiriman at-most-once (kemungkinan kehilangan pesan) atau at-least-once (kemungkinan duplikasi pesan) lebih tepat. Ini bergantung pada kebutuhan dan trade-off aplikasi
1 komentar
Opini Hacker News
Ada keluhan tentang struktur waktu di Chess.com. Tampaknya server melacak waktu sehingga mengabaikan waktu pengiriman dan latensi. Ini terasa sangat tidak nyaman saat memainkan game berbatas waktu di klien mobile
Lichess memilih pendekatan StackOverflow dan menggunakan server yang kuat
Menghitung langkah di sisi server menjamin konsistensi dan mengoptimalkan performa klien yang memiliki daya pemrosesan atau energi terbatas
Kurang ada penjelasan tentang bagaimana kehilangan pesan ditangani di kanal Redis pub/sub
Parameter "l" mungkin menunjukkan latensi yang diamati server
Menarik bahwa server mencantumkan dan mengirim semua langkah legal berikutnya
Ada pertanyaan tentang cara melindungi server WebSocket
Ada yang bertanya-tanya mengapa protokol memerlukan ack
FEN hanya mengodekan status papan, tidak mencakup status game