- Lichess, dünya çapında milyonlarca oyuncusu olan ücretsiz ve açık kaynaklı bir satranç platformudur
- İstemci ile sunucu arasındaki iletişimi izlemek için Chrome DevTools’un Network sekmesi kullanılır
WebSocket bağlantısı
- İlk dikkat çeken ağ davranışı, aşağıdakine benzer bir URL’ye yapılan WebSocket bağlantısıdır:
wss://socket2.lichess.org/play/H5uHz0egyvIA/v6?sri=bt6QzcyOiZg5&v=0
wssprotokolü, TLS kullanan şifreli bir WebSocket bağlantısını ifade eder- WebSocket, tam çift yönlü iletişime izin vererek tekrarlayan HTTP istekleri olmadan istemci ile sunucu arasında gerçek zamanlı güncellemeleri mümkün kılar
Yerel oyuncunun sırası
- Bir hamle yaptığınızda veri paketleri alışverişi olur:
// 22:51:35.280'de gönderildi
{
"t": "move",
"d": {
"u": "d2d4",
"l": 32,
"a": 1
}
}
- Sunucudan alınan mesaj:
// 22:51:35.312'de alındı
{
"t": "ack",
"d": 1
}
- Bu, sunucunun hamlemizi aldığını bildirir
// 22:51:35.312'de alındı
{
"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
}
}
}
- Bu mesaj, yaptığımız hamle ve güncellenmiş oyun durumu hakkında ayrıntılı bilgi sağlar
Rakibin sırası
- Rakip hamle yaptığında sunucudan benzer bir paket alınır:
// 22:51:43.489'da alındı
{
"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"
// Ek olası hamleler
},
"clock": {
"white": 300,
"black": 300
}
}
}
destsparametresi, mevcut konumdaki tüm kullanılabilir hamleleri listeler
Lichess mimarisi
- Lichess’in gerçek zamanlı oyun sistemi esas olarak iki ana servisten oluşur (ikisi de Scala ile yazılmıştır):
lila: oyun mantığı, durum, kullanıcı etkileşimleri vb. temel işlevleri yöneten çekirdek servislila-ws: istemci ilelilaarasında köprü görevi gören, WebSocket işlemede uzmanlaşmış servis
Mimariye genel bakış
lila <-> redis <-> lila-ws <-> websocket <-> client
lila, Redis üzerindenlila-wsile iletişim kurar;lila-wsise istemcilerle olan WebSocket bağlantılarını yönetir
Redis Pub/Sub ile iletişim
- Hamle olayları Redis Pub/Sub kanalında yayımlanır ve
lilabu kanala abone olarak hamleleri işler - Redis Pub/Sub, at-most-once teslimat sunar. Mesaj kaybı mümkün olsa da bellek kullanımı azalır
MongoDB ile nihai veri kalıcılığı
lila, oyun durumunu MongoDB’de saklar ancak her tekil hamleyi anında kaydetmez- Bunun yerine hamleleri tamponlayıp periyodik olarak kaydederek veritabanı yükünü azaltır
- Önemli bir olay meydana geldiğinde oyun durumu flush edilir
Devam eden bir oyuna katılma
- Oyuncu bağlandığında
vparametresini sağlayarak sistemin bildiği en güncel oyun sürümünü belirtir lila-ws, devam eden oyunlardaki tüm olayları izlemek ve yönetmek içinConcurrentHashMapkullanır
Sonuç
Lichess’teki hamle süreci kısaca şöyledir:
- İstemci,
lila-wsile bir WebSocket bağlantısı kurar - Oyuncu hamle yaptığında istemci,
lila-ws’ye bir hamle olayı gönderir lila-ws, hamlenin alındığını doğrulayan birackyanıtı verir- Hamle olayı Redis Pub/Sub kanalında yayımlanır ve
lilatarafından işlenir lila, hamleyi alır, oyun durumunu günceller ve sonunda MongoDB’ye kaydeder. Güncellenmiş oyun durumu ardındanlila-wsüzerinden tekrar istemciye gönderilir- İstemci, yeni hamleyi ve oyun durumu değişikliklerini yansıtan güncellenmiş oyun durumunu alır
GN⁺ görüşü
- Bu yazı, popüler açık kaynaklı satranç platformu lichess.org’da gerçek zamanlı oyunu mümkün kılan arka uç mimarisine ve sürece ayrıntılı bir bakış sunuyor
- Gerçek zamanlı web uygulamaları geliştirirken dikkate alınması gereken başlıca teknik unsurları tanıtıyor; örneğin WebSocket ile gerçek zamanlı iletişim, Redis Pub/Sub ile ölçeklenebilir mesaj iletimi ve MongoDB ile nihai veri saklama
- Lichess’in mimarisi gerçek zamanlı çok oyunculu oyunlar için çok uygun olsa da sohbet, işbirliği araçları ve sosyal medya akışları gibi diğer tür gerçek zamanlı web uygulamalarına da benzer desenler ve teknolojiler uygulanabilir
- Gerçek zamanlı özellikler kullanıcı deneyimini ve etkileşimi geliştirebilir, ancak ölçeklenebilirlik, güvenilirlik ve veri tutarlılığı gibi kendine özgü teknik zorluklar da doğurur. Bu yazı, bu zorlukları çözmek için stratejiler sunuyor
- Benzer teknoloji yığınını kullanan açık kaynak projeler arasında Socket.IO (Node.js tabanlı gerçek zamanlı uygulama çerçevesi) ve RethinkDB (gerçek zamanlı web uygulamaları için optimize edilmiş NoSQL veritabanı) bulunuyor
- Bu yazıdaki analiz, Lichess’in kaynak kodunun doğrudan incelenmesine dayanmıyor; bu nedenle gerçek uygulamada farklılıklar olabilir. Ancak açıklanan temel kavramlar ve mimari desenler yine de geçerliliğini koruyor
- Gerçek zamanlı sistemler tasarlanırken at-most-once (mesaj kaybı olasılığı) ile at-least-once (mesaj tekrarı olasılığı) teslimat arasında hangisinin daha uygun olduğunu dikkatle değerlendirmek gerekir. Bu, uygulamanın gereksinimlerine ve ödünleşimlerine bağlıdır
1 yorum
Hacker News görüşü
Chess.com’un zaman yapısıyla ilgili şikayetler var. Sunucu zamanı takip ediyor gibi görünüyor; bu da iletim süresini ve gecikmeyi yok sayıyor olabilir. Özellikle mobil istemcide süreli oyun oynarken rahatsız edici
Lichess, StackOverflow yaklaşımını seçmiş ve güçlü sunucular kullanıyor
Hamlelerin sunucu tarafında hesaplanması tutarlılığı garanti eder ve işlem gücü ya da enerjisi sınırlı istemcilerde performansı optimize eder
Redis pub/sub kanalında mesaj kaybının nasıl ele alındığı yeterince açıklanmamış
"l" parametresi, sunucunun gözlemlediği gecikmeyi gösteriyor olabilir
Sunucunun tüm geçerli sonraki hamleleri listeleyip göndermesi şaşırtıcı
WebSocket sunucusunun nasıl korunduğuna dair sorular var
Protokolün neden ack gerektirdiği merak ediliyor
FEN yalnızca tahta durumunu kodlar, oyun durumunu içermez