Whatsapp Yapısı (Programlama)
-
XMPP protokolunu kullaniyorlar. https://en.wikipedia.org/wiki/XMPP
Buna bir goz at
https://prezi.com/kyedm23ogsmp/a-technical-structure-of-whatsapp/
-
dhmm , yok abi kendi socketleri var XMPP neden kullansınlar ?
Araştırmalarıma göre edindiğim sonuçlar
BtnMesajGonder.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(isConnectedInternet) { //Internet Bağlılığı kontrol ediliyor Database.AddMessage(SenderUserID,ReceiverUserID,MessageText,0); }else{ //Internet yok ise veri saklanıyor. //Veri socket'e bindirilmiyor. SendMessage(SendeUserID,ReceiverUserID,MEssageText); Database.AddMessage(SenderUserID,ReceiverUserID,MessageText,0); } } }); public class NetworkStateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if(intent.getExtras()!=null) { //Internet'in Değişme anı NetworkInfo MyConnection = (NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO); if(MyConnection.getState()==NetworkInfo.State.CONNECTED && MyConnection !=null) { ArrayList Messages =Database.GetInActiveMessages(); for(Message msg: Messages) { //Internet geldiği anda mesajları şutla SendMessage(msg.SenderUserID,msg.ReceiverUserID,msg.MessageText); } }else{ //Internet yok } } } }
Umarım yararlı olur sizin için...
Topladığım veriler bu şekilde oldu. Adamlar böyle bir mantık kurmuşlar Whatsapp da çalışan biri https://www.quora.com/How-does-messaging-work-in-WhatsApp böyle şeyler demiş....
-
NmC aslinda yazmis olayi ama gereksiz o kadar ivir zivir bilgi arasinda dogru cevap kaybolmus :) Bu tarz sistemlerde subscribe ve unsubscribe olayi var. Sistem login olduktan sonra belli hizmetlere (birden fazla varsa) kendini subscribe eder. Arkaplanda bir listener calisir. Server da bir degisiklik oldugunda server kendi dinleyicilerine bu mesaji yollar. Her client'in bir uniqueID si oldugu icin güvenlik acisindan bu mesaj tüm dinleyicilere degil de eslesen client'a yollanir. Mesaji parametre olarak alan client da size gösterir. Eger internet yoksa serverin iki de bir denemesi sacma olur. O sebeple, telefon internete baglandiginda sisteme tekrar kendini subscribe eder (re-subscribe gibi düsünebiliriz ya da bir ping atiyor da diyebiliriz). Bu sayede sistem gönderilmemis mesajlari kontrol eder ve tekrar ilgili client'a mesajlarini yollar.
Milyarlarca mesaj oldugunu dusunursek, bir arkadasin dedigi gibi sqlite kullanilmasi cok mantiksiz olur. Cünkü sqlite da bir rdbms dir. Bu yüzden bu tarz sistemler bu verilerini noSql cozumlerinde tutuyordur. CAP teorimine göre hangisi uygunsa, ona gore bir noSQL cozumu secmislerdir ya da kendilerinin gelistirdigi bir cozum vardir (facebook bildigim kadariylacassandra'yi kullaniyor).
-
muhtemel sqllite tarafında durum tutuyor gönderemediğini bağlantı gelince tekrar gönderiyor
-
unbalanced bunu yazdı
NmC aslinda yazmis olayi ama gereksiz o kadar ivir zivir bilgi arasinda dogru cevap kaybolmus :) Bu tarz sistemlerde subscribe ve unsubscribe olayi var. Sistem login olduktan sonra belli hizmetlere (birden fazla varsa) kendini subscribe eder. Arkaplanda bir listener calisir. Server da bir degisiklik oldugunda server kendi dinleyicilerine bu mesaji yollar. Her client'in bir uniqueID si oldugu icin güvenlik acisindan bu mesaj tüm dinleyicilere degil de eslesen client'a yollanir. Mesaji parametre olarak alan client da size gösterir. Eger internet yoksa serverin iki de bir denemesi sacma olur. O sebeple, telefon internete baglandiginda sisteme tekrar kendini subscribe eder (re-subscribe gibi düsünebiliriz ya da bir ping atiyor da diyebiliriz). Bu sayede sistem gönderilmemis mesajlari kontrol eder ve tekrar ilgili client'a mesajlarini yollar.
Milyarlarca mesaj oldugunu dusunursek, bir arkadasin dedigi gibi sqlite kullanilmasi cok mantiksiz olur. Cünkü sqlite da bir rdbms dir. Bu yüzden bu tarz sistemler bu verilerini noSql cozumlerinde tutuyordur. CAP teorimine göre hangisi uygunsa, ona gore bir noSQL cozumu secmislerdir ya da kendilerinin gelistirdigi bir cozum vardir (facebook bildigim kadariylacassandra'yi kullaniyor).
Aynen abi Client bağlandığı anda kendini kayıt ettiriyor server'a daha sonra sürekli olarak server'a ping atıyor. Bağlandıktan sonra. Server'da son ping atılan tarihi alıyor saklıyor. X Client Y Client'a X client ne zaman ping attı dediğinde son ping tarihini alıyor ve X client'a gönderiyor.
Ping pong olayı işte. Peer to peer zaten bağlantılar da.
SSH , hocam sorun da o ya zaten. Mesajın iletilip iletilmediğini kontrol etmek için bir algoritmaya ihtiyaç var. Yani Client Server'a mesajı gönderdi ama Server'a bu mesajın ulaşıp ulaşılmadığı da kontrol edilmeli.
Client da zaten internet yoksa server'a veri gönderemez. Sürekli bir biçimde de gönderilen verileri server'a bak sen bu paketi almış mıydın diye sorulmaz. Sonuçta çok fazla data var sorgulanacak her seferinde hepsini sorgulamaya ne gerek var...
Burdaki tek sıkıntı iletilmeyen paketleri tespit etmek . Tespit edildikten sonra zaten NmC hocamın da dediği gibi yayın alıcısı ile sistem'e emir verilebilir bağlantı geldiğinde veriyi şutla. gibi...
------------EDİT----------
Çözümü buldum hocalar. @Unbalanced ve @NmC hocamın dediği gibi yaptım.. Socket e bir timeout verdim 5 saniyelik bir timeout.. Ping süresini de 3 saniye yaptım.. onPing eventine yanıt olarak Pong eventine şu userid de gönderdim..
Server side tarafında pong olduğu durumda son pong süresini değişkene atadım..
Client tarafında internetin açılıp kapanma durumunda socket.disconnect socket.connect methodlarını calıstırdım...
Mesaj gönder buttonuna basıldığında if(socket.isConnected) altına eğer bağlantı varsa socketten veriyi gönder yoksa hafızaya al dedim (Sqlite)
Yayın alıcısı içerisine de yazdığım koda Sqllite de isConnected false sonucunda oluşan datayı socketten tekrar gönderdim...
Yayın alıcısı durumunu aktif hale getirdiğinde Sqllite sorgulanıyor. Eğer data varsa tekrar gönderiliyor..
Bu sayede veri kaybı olmadı telefonu açtım kapattım herşeyi denedim bir sorun teşkil etmedi..
Batarya konusunda ise de pek de birşey olacağını düşünmüyorum. Çünkü Ping ve pong olayları bataryayı su gibi içmiyor.
Bu yaptığımız olaya heartbeat deniyor. Heartbeat Interface cluster yapılarda cluster yapısının sağlığı için oluşturulan network sistemiymiş. Server Client'a 0.4 veya 0.5 sn de bir pingler ve eğer 10 (siz belirleyebiliyorsunuz) a sağlıklı bir cevap vermezse bağlantıyı diğer kanallara iletiyor. Bizde burda 10 ping sağlanmazsa bağlantıyı keserek bu client'in artık öldüğünü varsayıyoruz ve yeni bir bağlantı açmasını istiyoruz..
Bu durumda zaten Android tarfında intenretin kesildiğinden tekrar bir bağlantı gerçekleştiriyoruz.. Ek olarak Telefon açıldığı anda Internet bağlantısı sistem tarafından tetiklendiği için yazdığımız yayın alıcısı da tetikleniyor ve socket'e bağlantı gerçekleşiyor. Tam bu sırada da gönderilmeyen paketleri Şutluyoruz....
Bu sayede Kardeş internetin yoksa ben dosyalarını yedeklerim diyoruz..
Eski mesajları saklamak için de client'a bir sqlite yazabilirsiniz ki zaten bu kullanıcıya kalmış mesajları saklamak isterse kendi telefonundan ferakat edecek..
Server tarafında mongodb tercih edilebilir çünkü @unbalanced hocamın dediği gibi çok fazla mesaj var ve bunların cevap süreleri çok önemli olaylar çok kısa sürede gerçekleşiyor..
Bu yapıyı Github'a aktaracağım güzel bir uygulama ile.. Sağlıcakla. Uzun uğraş ve araştırma sonucu çözdük olayı :)
MhmdAlmz tarafından 10/Tem/17 14:23 tarihinde düzenlenmiştir