28 Mayıs 2013 Salı

Websocket soyutlama mümkün mü?

Geçen yıl zaten çok az ilgilenebildiğim yazılım hobimi sadece Web geliştirme üzerine yoğunlaştırmaya karar vermiştim, önceki yıllarda Python ile masaüstü uygulamaları falan yapıyordum.

HTML5 Uygulamaları mobil cihazlarda falan her yerde çalışabiliyor, yani tek bir kod ile tarayıcı çalıştıran her türlü cihaza uygulama sunma imkanı var. Doğal kod çalıştırmanın avantajları elbette var ama bence Dünya yavaş yavaş HTML5 çevresinde dönmeye başlıyor, zamanla tarayıcılar donanım kaynaklarına  ulaşabilecek API'lere kavuşacak. Bunun son örneği Google'ın başını çektiği bir organizasyonun geliştirdiği WebRTC API.

HTML5'te neler yeni diye bakınca Websocket'i gördüm, bir W3C standardı. Klasik HTTPRequest işleminin aksine istemci ve sunucu arasında kalıcı bir bağlantı kuruluyor ve bağımsız olarak karşılıklı mesaj gönderilebiliyor. Bir nevi e-posta sistemi gibi. Bu, long polling gibi zorlama yöntemlerin yerine geçecek bir teknoloji. Bağlantı ws:// adresine basit bir HTTP 1.1 çağrısı ile başlıyor, sunucu bağlantıyı kabul ederse HTTP protokolü terk ediliyor ve sabit bir bağlantı açılıyor.

HTTPRequest ile RPC çağrıları yapmaya devam ederken Websocket ile sunucudaki olaylar anlık olarak istemciye iletilebiliyor. Bu konu oldukça ilgimi çektiğinden en azından basit bir chat uygulaması yaparak pratik yapmaya karar vermiştim. Ama bir sorun vardı hiç JS bilmiyordum, çünkü en sevmediğim dildir :)

JS Sorununu CoffeeScript ile aştım, Coffee ile gerçekten okunası kodlar yazılabiliyor. Diğer sorun da arayüz yazmak, tarayıcılar arası uyumsuzluklar vs. ile uğraşmak. Bunları da Dojo Framework ile hallettim, Dojo kütüphanesi tam teşekküllü bir araç takımı sunuyor, mobil cihazlar için kütüphaneleri de var, ayrıca  kodu doğal DOM nesnelerden de soyutluyor, declare, hitch gibi bazı fonksiyonları ve evented gibi sınıfları doğal JS'ten de uzaklaştırıyor, iyi yani. Tarayıcı uyumunu da dert etmiyorsun. En önemlisi iyi belgelenmiş.

Sunucu tarafında fazla zorlanmamak için zaten bildiğim Python kullanmak istedim, tabii ki Tornado Server. Basit, hızlı, belgesi bol, kütüphane olarak hemen her şey var. Tornado'yu Nginx'in arkasına aldım, çok gerekli miydi bilmiyorum açıkcası ama ileride bir şeyler yapıp deploy etmek istediğimde veya bir VPS kiralamaya kalkarsam diye Nginx'i tecrübe etmiş olayım dedim.

Dojo ve Tornado'da emekleme aşamasını geçmem bayağı zaman aldı, zira bazen 15-20 gün tek satır kod yazmadım ve her seferinde yav ne yazmıştım diyerek yeni baştan öğreniyormuşum gibi oldum. Neyse ki artık temel bazı kütüphaneler yazmaya başladım.

Sunucuda yazdığım chat/main.py uygulamasındaki nesneleri;

@rpchook
class login(object):


 def run(self, data):
  ...




@sockethook
class chat(object):


 
 def message(self, msg):
            ...

İstemcide;


login = new chat.main.login()
login.on("loaded", lang.hitch(this, this.loaded))
login.send(data)

chat = new chat.main.chat()
chat.on("message", lang.hitch(this, this.message))
chat.send(msg)

gibi kullanabilmek için bir şeyler yazdım, RPC tarafı kolaydı ama Socket konusu farklı, sunucuda her bir socket için bir loop çalışıyor, ben istemcide soyutlama yapmak istediğimden tek bir loop kullanacak bir tasarım yaptım, iyi mi kötü mü henüz bilmiyorum, kodlama bitip çalışan bir şeyler ortaya çıkarsa belli olacak. 

Eli yüzü düzgün bir şey olana kadar kod yayınlamayacağım. Kod vermeyeceksen ne diye bu kadar dil döktün demeyin, sıkıntıdan öylesine yazdım, zaten hiç bağlantı falan uğraşamayacağım, hızlı hızlı yazdım geçtim, adı üstünde günlük değil mi bu?