Eşzamansız web veya web soketleri nedir. JavaScript kullanarak tarayıcıdan TCP Soketine bağlanma

  • 18.06.2019

WebSocket nedir. Hangisi daha iyi - Websockets veya AJAX?

5 (% 100) 3 oy

WebSocket (Web soketi) TCP bağlantısı üzerinden tam çift yönlü bir iletişim protokolüdür. Yani, bu protokolü kullanarak aynı anda bir mesaj gönderip alabilirsiniz. Tarayıcı ve sunucu arasında gerçek zamanlı olarak mesaj alışverişi yapmanızı sağlar.

Web soketleri uzun süredir ortalıkta deneysel değiltarayıcı oyunlarında, interaktif sistemlerde, ödeme sistemlerinde kullanılır. Web Yuvaları zaten modern web'in bir parçası!

Tarayıcı bir web sunucusudur. Nasıl çalışır ve neyin değiştirilmesi gerekir?

Tarayıcının sunucuda meydana gelen olaylara tepki vermesini sağlamak, web geliştiricileri için her zaman zor olmuştur. HTTP protokolünün bazı dezavantajları vardır ve muhtemelen tüm geliştiriciler tarafından eleştirilmiştir. Böyle bir dezavantaj, sunucuya sürekli bağlantı sorunudur. HTTP protokolünün uygulanması bu tür bir etkileşime izin vermedi. Örneğin, sunucudan tarayıcıya veri almak istiyorsak, sunucuya başka bir istekte bulunmamız gerekir ve bu, sayfayı yeniden yüklemeyi içerir. Yani, siteyi bir tarayıcıda açıp sayfayı yüklediysek, görüntülediysek ve bu zamana kadar bu sayfa sunucuda değiştiyse, değişikliği almak için sayfayı yeniden yüklememiz gerekir.

HTTP protokolünü kullanarak zaman uyumsuzluğa ihtiyacımız olan epeyce görev var. Yani, sunucuda bir değişiklik varsa, bu değişiklikleri tarayıcıda yeniden başlatmadan almanız gerekir. Bu tür bir örnek, insanların iletişim kurduğu bir sohbettir ve biri diğerine mesaj gönderdiğinde, mesaj, sayfayı yeniden yüklemeden alıcıya anında görünür. Önceden, bu tür bir uygulamayı oluşturmak kolay değildi, sunucu itme eylemlerini taklit eden farklı yorumlama dereceleri vardı. Böyle bir örnek, saniyede bir yeniden yüklenen ve sunucuya istek gönderen, istemci tarafından barındırılan çerçevelerdir.

Bu yaklaşımın birçok dezavantajı vardır - sunucuya çok fazla sayıda istek üretilir, uygulamaların doğru yapısını düzenlemek zordur. Benim en büyük sorunum sunucu olayına tepkinin öykünmesini yapıyor olmamız. Her zaman müşteri (tarayıcı) verileri uzun bir gecikmeyle alır.

Şimdi konuşalım AJAX... Nesne ne zaman XMLHTTPRequest tarayıcılarda göründü, işler biraz gelişti. Bu durumda, şemaya göre sunucu ile etkileşim kurabiliriz Uzun yoklama... Aşağıdaki nokta, bu şemanın özünü açıklamaktadır:

  • İstemci (tarayıcı) sunucuya bir istek gönderir,
  • Bağlantı kapatılmamış ve müşteri bir olayın gerçekleşmesini bekliyor,
  • Bir olay meydana geldiğinde müşteri talebine bir yanıt alır,
  • Müşteri hemen yeni bir istek gönderir.

Bu yaklaşımla, sunucuya asenkron talepler alıyoruz ve yanıtlar geri arama işlevleri kullanılarak işleniyor. Ancak bu yaklaşımın bazı dezavantajları da vardır. Bu yaklaşımın ana dezavantajı, sunucu ve sunucu olaylarının burada iletişimi başlatmamasıdır.

Çok uzun zaman önce, yukarıda listelediğimiz dezavantajlara sahip olmayan yeni bir protokol ortaya çıktı. Yeni WebSockets teknolojisi, bir TCP bağlantısı üzerinden tam çift yönlü iletişim protokolünün bir uygulamasıdır.

Neden WebSockets? WS protokolünün artıları ve eksileri

Web Soketleri teknolojisini kullanarak WWW dünyasındaki tanıdık etkileşim sistemini unutmamız gerekiyor. Standart HTTP protokol modelini - "istek / istek için yanıt" - sağlamlaştırmamız gerekir. Web Soketleri teknolojisi çerçevesinde tarayıcı ve sunucu her an veri gönderip alabilir, yani eşit katılımcılar haline gelirler.

WebSocket, tek bir istemci-sunucu bağlantısı kurar. WebSockets ile çalışmak için, her iki tarafın (istemci ve sunucu) bu teknolojiyi desteklemesi gerekir. Tüm yeni tarayıcılar WS protokolünü destekler ve sunucu tarafı geliştirici tarafından uygulanır. Sunucu ve istemci "savaşmaya" hazır olduğunda, sunucu ve istemci Web Soketleri üzerinden metinden metne mesajlar gönderebilir. Veri iletimi ve alımı anında gerçekleşir, bu teknoloji çift yönlü iletişim kanalları oluşturur.

İstemci ve sunucuya olan bağlantı kapalı olmadığı için (her zaman açık tutulur), bu gereksiz verilerin (HTTP başlıkları) iletimini engeller. WebSockets standardında, açık bağlantıların sayısı ve isteklerin sırası konusunda herhangi bir sınırlama yoktur.

Bu derste, sunucuya gelen asenkron istekler için hangi yöntemlerin mevcut olduğunu, WebSocket'in ne olduğunu ve AJAX ve HTML çerçevelerine göre ne gibi avantajları olduğunu öğrendik. Bir sonraki derste Node.js üzerinde WebSocket ile çalışmaya başlayacağız, bu teknolojiyi eylemde daha detaylı ele alacağız ve WebSockets ve Node.js üzerinde bir sohbet yazacağız. Node.js eğiticilerinin tam listesini bulun.

Birkaç hafta önce, Google Chromium geliştiricileri WebSocket teknolojisi desteği hakkında haberler yayınladılar. Bilişim burjuva haberlerinde, haberler patlayan bir bomba etkisi yarattı. Aynı gün, çeşitli çok ünlü BT uzmanları yeni ürünü denedi ve bloglarında övgüler bıraktı. Anında çeşitli sunucuların / kitaplıkların / çerçevelerin geliştiricileri ( Apache, EventMachine, Twisted, MochiWeb vb.) WebSockets desteğinin kısa süre içinde ürünlerinde uygulanacağını duyurdu.
Teknolojinin bize vaat ettiği kadar ilginç olan nedir? Bence, WebSocket başlangıcından bu yana HTTP protokolünün en radikal uzantısıdır. Bu bir numara değil, bu hTTP paradigma kayması... Başlangıçta eşzamanlı bir istek yanıt protokolü olur tamamen asenkron ve simetrik... Artık bir istemci ve sabit rollere sahip bir sunucu yok, ancak veri alışverişinde iki eşit katılımcı var. Herkes kendi başına ve bir başkasına veri göndermeleri gerektiğinde çalışır. Gönderdim - ve devam ettim, beklemeye gerek yok. Diğer taraf istediği zaman cevap verecektir - belki hemen değil, ya da hiç değil. Protokol size veri alışverişi için tam özgürlük verir, nasıl kullanacağınıza siz karar verirsiniz.

Geliştirme yapıyorsanız web soketlerinin kullanışlı olacağına inanıyorum:
- Döviz kuru ve kanal talep eden yoğun veri alışverişi olan web uygulamaları;
- standartları takip eden uygulamalar;
- "uzun süreli" web uygulamaları;
- sayfada birçok farklı asenkron blok içeren karmaşık uygulamalar;
- alanlar arası uygulamalar.

O nasıl çalışır?

Çok basit! Sayfanız, sunucuya bir web soketi açmak istediğine karar verdiğinde, özel bir javascript nesnesi oluşturur:

  1. < script >
  2. ws \u003d yeni WebSocket ("ws: //site.com/demo");
  3. // ve yeni nesnede üç geri çağrıyı askıya alır:
  4. // bağlantı kurulduğunda ilki çağrılacak:
  5. ws.onopen \u003d function () (alert ("Bağlantı açıldı ..."));
  6. // saniye - bağlandığında kapalı
  7. ws.onclose \u003d function () (alert ("Bağlantı kapatıldı ..."));
  8. // ve son olarak üçüncüsü - tarayıcı bir web soketi aracılığıyla her veri aldığında
  9. ws.onmessage \u003d function (evt) ($ ("# msg") .append ("

    "+ evt.data +"

    " ); };
* Bu kaynak kod, Kaynak Kodu İşaretleyici ile vurgulanmıştır.
Ve ağda ne olur?
Her şey normal bir HTTP isteği gibi başlar. Tarayıcı, TCP aracılığıyla sunucu bağlantı noktası 80'e bağlanır ve biraz sıra dışı bir GET isteği verir:
GET / demo HTTP / 1.1
Yükseltme: WebSocket
Bağlantı: Yükselt
Barındırıcı: site.com
Menşei: http://site.com


Sunucu WebSockets'i destekliyorsa, şu şekilde yanıt verir:
HTTP / 1.1 101 Web Soketi Protokol El Sıkışması
Yükseltme: WebSocket
Bağlantı: Yükselt
WebSocket-Origin: http://site.com
WebSocket-Konum: ws: //site.com/demo

Tarayıcı bundan memnunsa, o zaman basitçe TCP bağlantısı açık... İşte bu - el sıkışma tamamlandı, veri alışverişi kanalı hazır.
Taraflardan biri bazı bilgileri diğerine aktarmak istediğinde, aşağıdaki formda bir veri çerçevesi gönderir:

0x00,<строка в кодировке UTF-8>, 0xFF

Yani, sadece bir metin satırı, önüne sıfır bayt 0x00 ve sonunda 0xFF eklenmiş bir bayt dizisidir. İşte bu kadar - üstbilgi yok, meta veri yok! Tam olarak ne gönderilecek, geliştiriciler bunu tamamen sizin takdirinize bıraktı: XML istiyorsunuz, JSON istiyorsunuz, ama en azından Puşkin'in şiirleri.
Tarayıcı her seferinde böyle bir mesaj aldığında, mesajınızın geri aranmasını "çekecektir".

Böyle bir protokolün verimliliğinin% 95'e çıkma eğiliminde olduğunu anlamak kolaydır. Bu, her numara için birkaç kilobayt başlık göndermeniz gereken klasik bir AJAX isteği değildir. Küçük veri bloklarını sık sık değiş tokuş ederseniz, fark özellikle belirgindir. İşlem hızı aynı zamanda saf bir TCP soketinin hızına da meyillidir - sonuçta her şey hazır - bağlantı açık - sadece bayt gönder.

Lirik kazı:
Ve beni çok mutlu eden bir şey daha var - UTF-8, izin verilen tek kodlama olarak seçildi! Zaten çekingen bir şekilde bir süre sonra ağın koltuk değneklerinden birinden uzaklaşacağımızı umuyorum.

Resim gönderebilir miyim
WebSockets'i kullanarak ikili verileri de aktarabilirsiniz. Onlar için aşağıdaki gibi başka bir veri çerçevesi kullanılır:
0x80,<длина - один или несколько байт>, <тело сообщения>

Bir veya daha fazla bayt ne anlama geliyor? Geliştiriciler, iletilen mesajın uzunluğu üzerinde kısıtlamalar oluşturmamak ve aynı zamanda baytları mantıksız bir şekilde boşa harcamamak için mesaj gövdesinin uzunluğunu belirlemenin çok akıllıca bir yolunu kullandılar. Uzunluk göstergesindeki her bayt kısımlar halinde değerlendirilir: en önemli bit, bu baytın son mu (0) mı yoksa ondan sonra başkaları mı (1) olduğunu gösterir ve en az anlamlı 7 bit gerçek verileri içerir. Bunu şu şekilde işleyebilirsiniz: 0x80 ikili veri çerçevesinin işaretini alır almaz, bir sonraki baytı alır ve ayrı bir "kumbaraya" koyarsınız, sonraki bayta bakarsınız - eğer en önemli bit kümesine sahipse, onu "kumbara" ya aktarın ve en anlamlı 0 bitine sahip bir baytla karşılaşana kadar bu şekilde devam edin. Bu, bunun uzunluk göstergesindeki son bayt olduğu anlamına gelir - onu "kumbaraya" da aktarın. Şimdi "kumbara" daki tüm baytlardan en önemli bitleri kaldırın ve geri kalanı birbirine yapıştırın. Bu, mesaj gövdesinin uzunluğu olacaktır. En önemli bit olmadan 7 bitlik sayılar olarak da yorumlanabilir.

Örneğin, web tasarımının en önemli resmi - 43 baytlık şeffaf tek pikselli bir GIF şu şekilde aktarılabilir:

0x80, 0x2B,<тело сообщения>

160 baytlık bir nesne 2 bayt uzunluğunda kodlanmıştır:
0x80, 0x81, 0x20,<байты объекта>

Çok zarif, değil mi?

Bize ne veriyor?

Hız ve verimlilik
İletimin yüksek hızı ve verimliliği, bazen tek bir TCP paketine bile sığacak şekilde iletilen verilerin küçük boyutu ile sağlanır - burada, tabii ki, bunların tümü iş mantığınıza bağlıdır. (TSB veri çerçevesine de eklenebilir, ancak bu aktarım 1 TCP paketinden biraz fazlasını gerektirir. :))
Ayrıca, bağlantının zaten hazır olduğunu unutmayın - kurulması, el sıkışmaları, müzakereleri için zaman ve trafik harcamaya gerek yoktur.
Standart
WebSockets piyasaya sürüldüğünde, Kuyrukluyıldız tarihini ve üzerine sarılmış olan tüm pribludları - Bayuex, LongPolling, MultiPart vb. Bunların hepsi yararlı teknolojilerdir, ancak çoğu zaman, standartlara değil, bilgisayar korsanlarına göre çalışırlar. Buradan periyodik sorunlar ortaya çıkıyor: vekil cevabı "çiğnedi" ve ancak birkaç cevap topladıktan sonra verdi. Proxy'leri "yumruklamak" için genellikle iki kilobaytlık bir "dalgıç" kullanılırdı - ör. iletilen veri miktarı boşluklarla (veya diğer önemsiz karakterlerle) 2K'ya kadar arttı ve birçok proxy gecikmeden anında iletildi. Zaman zaman, antivirüsler tam cevabı alma, kontrol etme ve ancak o zaman alıcıya iletme isteklerini dile getirdiler. Tabii ki, bugün tüm bu sorunlar aşağı yukarı çözülmüştür - aksi takdirde bu kadar çok sayıda web uygulaması olmazdı. Bununla birlikte, bu yöndeki gelişme, yeni sorunların ortaya çıkmasıyla ilişkilidir - tam da bu, standardı atlama girişimidir.

Bence, bir süre sonra geriye sadece 2 teknoloji kalacaktır: saf AJAX ve WebSockets. İlki, bir veya daha fazla sayfa güncellemesi için iyidir - gerçekten, bunun için güçlü bir web soket makinesini ateşlemek pek mantıklı değildir. Ve şu anda kuyruklu yıldız ve meslektaşları tarafından yapılan diğer her şey web soketlerine taşınacak. daha kolay ve daha verimli olacak. Örneğin, istiyorsun forex piyasasındaki canlı fiyatları izleyin... Lütfen: bir soket açın - sunucu size tüm güncellemeleri gönderecektir. Göreviniz yalnızca mesaj olayında doğru geri aramayı kapatmak ve ekrandaki numaraları değiştirmektir. Bir şey satın almaya, sunucuya eşzamansız bir mesaj göndermeye ve paralel olarak numara almaya devam etmeye karar verdiniz. Zarif mi? Bununla karşılaştırıldığında, aktif olmayan bir kanalı bile periyodik olarak yeniden başlatma ihtiyacı olan LongPolling (böylece proxy'si veya başka biri onu çarpmasın) kirli bir hack gibi görünüyor.

Kanal ömrü
HTTP'den farklı olarak, web yuvalarının boşta kalma süresi sınırı yoktur. Bu, artık bağlantıyı periyodik olarak yenilemenize gerek olmadığı anlamına gelir. herhangi bir vekilin onu "çarpma" hakkı yoktur. Bu, bağlantının etkin olmayan bir biçimde askıda kalabileceği ve kaynak gerektirmediği anlamına gelir. Tabii ki, sunucunun TCP soketlerini tıkayacağını iddia edebilirsiniz. Bunu yapmak için iyi bir çoklayıcı kullanmak yeterlidir ve normal bir sunucu kolayca bir milyona kadar açık bağlantıyı çekebilir.
Karmaşık web uygulamaları
Bildiğiniz gibi, HTTP, bir sunucuya eşzamanlı açık oturum sayısı için bir sınır sağlar. Bu nedenle, sayfada birçok farklı eşzamansız bloğunuz varsa, yalnızca bir sunucu değil, aynı zamanda bir istemci çoklayıcı da yapmanız gerekir - bu, Bayeux Protokolünün geldiği yerdir.
Neyse ki, bu sınırlama web yuvaları için geçerli değildir. İhtiyaç duyduğunuz kadar açın. Ve ne kadar kullanılacağına - bir (ve her şeyi içinden çoğullayarak) veya tersi - her blok için kendi bağlantısını - siz karar verin. Geliştirme kolaylığı, sunucu ve istemci yükünü göz önünde bulundurun.
Alanlar arası uygulamalar
Ve bir AJAX geliştiricisinin bir başka "önyüklemesinde rock" - etki alanları arası uygulamalarla ilgili sorunlar. Evet ve onlar için de pek çok hile icat edildi. Onları bir kalemle sallayalım ve cimri bir yırtığı silelim. WebSockets'in böyle bir sınırlaması yoktur. Kısıtlamalar "aynı kaynaktan" ilkesine değil, "izin verilen kaynak" ilkesine dayalıdır ve istemcide değil, sunucuda tanımlanır. Bence özenli insanlar yeni Origin unvanını çoktan fark ettiler. Bu sayede bilgi, web soketinize bağlanmak istedikleri yerden iletilir. Bu adres size uymuyorsa, bağlanmayı reddedersiniz.
Herşey! Alanlar arası boğaz ağrısının sonu!
Ellerinle dokunabilir misin?
Yapabilmek!

GÜNCELLEME: Açık kaynak web soketi uygulamalarından biri www.mibbit.com adresindeki sohbettir (bloglarında bir not).
WebSocket sunucusunun PHP uygulaması, eşzamansız çerçeveye bir modül tarafından da temsil edilir

22.9. Web Soketleri

Bölüm 18, JavaScript istemci tarafı komut dosyalarının ağ üzerinden sunucularla nasıl iletişim kurabildiğini gösterir. Bu bölümdeki tüm örnekler HTTP protokolünü kullanır, bu da bunların hepsinin HTTP protokolünün orijinal doğasıyla sınırlı olduğu anlamına gelir: bu durum bilgisi olmayan protokol, istemci isteklerinden ve sunucu yanıtlarından oluşur. HTTP protokolü aslında oldukça özel bir ağ protokolüdür. İnternet üzerinden (veya yerel alan ağları üzerinden) daha çok yönlü ağ oluşturma, genellikle uzun ömürlü bağlantılar kullanılarak uygulanır ve TCP soketleri üzerinden çift yönlü mesajlaşma sunar. Düşük seviyeli TCP soketlerine JavaScript istemcisi komut dosyası erişimi sağlamak oldukça güvensizdir, ancak WebSocket API spesifikasyonu güvenli bir alternatif tanımlar: istemci komut dosyalarının Web Soket Protokolünü destekleyen sunuculara çift yönlü bağlantılar kurmasına izin verir. Bu, bazı ağ sorunlarının çözümünü büyük ölçüde basitleştirir.

Web Soketleri API'sinin kullanımı şaşırtıcı derecede kolaydır. Öncelikle yapıcıyı kullanarak bir soket oluşturmanız gerekir WebSocket ():
var soket \u003d yeni WebSocket ("ws: //ws.example.com: 1234 / kaynak");

Web soket protokolü

JavaScript'te web soketlerini kullanmak için, burada açıklanan websockets istemci API'sine aşina olmanız yeterlidir. Websocket etkinleştirilmiş sunucular oluşturmak için eşdeğer bir sunucu API'si yoktur; bu bölümde, Düğüm yorumlayıcısını (bölüm 12.2) ve üçüncü taraf sunucu tarafı web soketi destek kitaplığını kullanmaya dayalı basit bir sunucu örneği sunulacaktır. İstemci ve sunucu, Web Soketi protokolü tarafından tanımlanan kuralları izleyerek uzun ömürlü TCP soketleri üzerinden iletişim kurar. Burada protokolün özelliklerini ele almayacağız, ancak Web Soket protokolünün, Web sunucularının aynı port üzerinden HTTP ve Web Soketi bağlantılarını kolayca idare edebilmesi için çok dikkatli bir şekilde tasarlandığına dikkat edilmelidir.

Web soketleri, tarayıcı satıcıları arasında yaygın bir destek kazanmıştır. Web Soketleri protokolünün erken bir yayın öncesi sürümünde büyük bir güvenlik açığı vardı, bu nedenle bu yazının yazıldığı sırada bazı tarayıcılar, protokolün güvenli bir sürümünü standartlaştırmadan önce Web Yuvaları desteğini devre dışı bıraktı. Örneğin, Firefox 4'te about: config sayfasını açıp “network.websocket” değişkenini ayarlayarak websocket desteğini açıkça etkinleştirmeniz gerekebilir. override-security-block "değerini true.

*********************************************

Oluşturucu argümanı WebSocket () ws: // protokolünü (veya güvenli bağlantı durumunda https: //'ye benzer şekilde wss: // -) kullanan URL'dir. URL, bağlanılacak ana bilgisayar adını belirtir ve ayrıca bağlantı noktasını (varsayılan olarak, web yuvaları HTTP ve HTTPS protokolleriyle aynı bağlantı noktasını kullanır) ve yolu veya kaynağı belirtir.

Bir soket oluşturduktan sonra, olay işleyicileri genellikle ona kaydedilir:

socket.onopen \u003d işlev (e) (/ * Bağlantı kuruldu. * /);
socket.onclose \u003d function (e) (/ * Bağlantı kapatıldı. * /);
socket.onerror \u003d function (e) (/ * Bir şeyler ters gitti! * /);
socket.onmessage \u003d işlev (e) (
var mesaj \u003d e.data; / * Sunucu mesajı gönderdi. * /
};

Bir soket aracılığıyla sunucuya veri göndermek için yöntemi çağırın gönder () priz:

socket.send ("Merhaba, sunucu!");

Web Sockets API’nin mevcut sürümü yalnızca metin mesajlarını destekler ve bunları UTF-8 kodlu dizeler olarak gönderir. Ancak, Web Soket Protokolü belirtiminin mevcut sürümü ikili mesajlar için destek içerir ve API'nin gelecekteki sürümleri, sunucuyla ikili verilerin alışverişini destekleyebilir.

Sunucu ile iletişim sona erdikten sonra, betik yöntemini çağırarak web soketini kapatabilir kapat () .

Web soketleri çift yönlüdür ve tek bir web soketi bağlantısı, istemci ve sunucu tarafından herhangi bir zamanda birbirlerine mesaj göndermek için kullanılabilir. Bu etkileşim istek ve yanıt şeklinde olmak zorunda değildir. Her Web Soketi tabanlı hizmet, istemci ve sunucu arasında veri aktarımı için kendi "alt protokolünü" tanımlayacaktır. Bu "alt protokoller" zaman içinde gelişebilir ve alt protokolün birden çok sürümünü destekleyen istemcileri ve sunucuları uygulamanız gerekebilir. Neyse ki, Web Soketi protokolü, hem istemci hem de sunucu tarafından desteklenen bir alt protokol seçimini görüşmek için bir mekanizma içerir. İnşaatçı WebSocket () bir dizi dizgiyi iletebilirsiniz. Sunucu bunu, istemci tarafından desteklenen alt protokollerin bir listesi olarak alacaktır. Sunucu, desteklediği bir alt protokol seçecek ve istemciye geri gönderecektir. Bağlantı kurulduktan sonra, müşteri özelliği kontrol ederek hangi alt protokolün kullanılabileceğini belirleyebilir. protokol nesne WebSocket .

Bölüm 18.3, nesne API'sini açıklar EventSource ve uygulamasını bir sohbet istemcisi ve sunucusu uygulama örneği üzerinde gösterir. Web soketleri, bu tür uygulamaların uygulanmasını daha da kolaylaştırır. Örnek 22-16, çok basit bir sohbet istemcisini gösterir: Örnek 18-15'e benzer, ancak mesajları almak için bir EventSource nesnesi yerine çift yönlü mesajlaşma için Web soketlerini ve gönderme için XMLHttpRequest'i kullanır.

Örnek 22.16. Web yuvalarına dayalı sohbet istemcisi




https://github.com/miksago/node-websocket-server/... İletişim kurarken
* "/" kaynağına sohbet istemcisinin HTML dosyasını döndürür. Herhangi birine yapılan itirazlara yanıt olarak
* 404 kodu başka bir kaynağa döndürülür.Mesajlar protokol aracılığıyla alınır
* web soketleri ve basitçe tüm aktif bağlantılara gönderilir.
*/
var http \u003d required ("http"); // Düğümde HTTP sunucusu kullan
var ws \u003d required ("websocket-server"); // Harici kitaplığı kullan
// Sohbet istemcisi uygulamasıyla kaynak dosyayı okuyun. Aşağıda kullanılmış,
var clientui \u003d gerekli ("fs"). readFileSync ("wschatclient.html");
// Bir HTTP sunucusu oluşturun
var httpserver \u003d new http.Server ();
// HTTP sunucusu yeni bir istek aldığında, bu işlev çağrılacak
httpserver.on ("istek", işlev (istek, yanıt) (
// "/" kaynağı istenirse, sohbet istemcisi uygulamasını gönderin,
if (request.иrl \u003d\u003d\u003d "/") (// Sohbet istemcisinin uygulanması istenir
response.writeHead (200, ("" İçerik Türü ":" metin / html "));
response.write (clientui); response.end ();
}
else (// Diğer herhangi bir isteğe yanıt olarak 404 "Bulunamadı" kodunu gönderin
response.writeHead (404);
response.end ();
}
});
// HTTP sunucusunu web soketi tabanlı bir sunucuya sarın
var wsserver \u003d ws.createServer ((sunucu: httpserver));
// Yeni bağlantı istekleri alındığında bu işlevi çağırın
wsserver.on ("bağlantı", işlev (soket) (
socket.send ("Sohbete hoş geldiniz."); // Yeni müşteriye hoş geldiniz
socket.on ("mesaj", function (msg) (// İstemciden mesaj alın
wsserver.broadcast (msg); // Ve onları herkese gönder
});
});
// Sunucuyu 8000 numaralı bağlantı noktasından başlatın. Sunucuyu web soketlerine göre başlatın
// ayrıca HTTP sunucusunu da başlatır. Kullanmak için bağlanın
// adrese göre

(Web Soketleri), gerçek zamanlı mesajlaşma için bir istemci (tarayıcı) ile bir sunucu arasında etkileşimli bir bağlantı oluşturmanıza olanak sağlayan gelişmiş bir teknolojidir. HTTP'den farklı olarak web soketleri, bu teknolojiyi tamamen benzersiz kılan iki yönlü veri akışına izin verir. Bu teknolojinin nasıl çalıştığını ve HTTP'den nasıl farklı olduğunu görelim.

HTTP nasıl çalışır?

HTTP mesajlaşma şeması

Tarayıcınızda her gün bu protokolle karşılaştığınız için muhtemelen HTTP'nin (veya HTTPS'nin) ne olduğunu biliyorsunuzdur. Tarayıcı sürekli olarak sunucuya yeni mesajlar olup olmadığını sorar ve bunları alır.

Ayrıca, HTTP'nin her biri farklı bir amaca sahip olan POST, GET veya PUT gibi farklı türde isteklere izin verdiğini de biliyor olabilirsiniz.

Web soketleri nasıl çalışır?

Web yuvalarını kullanırken mesajlaşma şeması

Web yuvalarının yanıt vermek için tekrarlanan isteklerinize ihtiyacı yoktur. Bir isteği yürütmek ve yanıt beklemek yeterlidir. Hazır olduğunuzda size mesajlar gönderecek olan sunucuyu dinleyebilirsiniz.

Geliştirme yapıyorsanız Websockets kullanılabilir:

  • gerçek zamanlı uygulamalar;
  • sohbet uygulamaları;
  • IoT uygulamaları;
  • çok oyunculu oyunlar.

Web yuvalarını kullanmaktan ne zaman kaçınmalısınız?

Neredeyse hiç. Tek dezavantaj, bazı tarayıcılarla uyumsuzluktur, ancak tarayıcıların% 95'i web soketlerini desteklemektedir.

Bazı durumlarda web soketlerine ihtiyacınız olmayabilir. Basit bir CMS oluşturuyorsanız, muhtemelen gerçek zamanlı işlevselliğe ihtiyacınız olmayacak. Ayrıca, GET, POST, DELETE ve PUT gibi HTTP istekleri yeterli olduğundan, REST API'de websockets kullanmayın.

Pratik örnekler

Aşağıdaki örnekler, istemci için JavaScript ve sunucu için Node.js kullanır. Örnekler çok basittir ve pratikte yararlı olma ihtimali düşüktür, ancak özü anlamanıza izin vereceklerdir.

Web Soketleri

Bir web soketiyle bir sohbet örneği

Const WebSocket \u003d gerekli ("ws"); // yeni bir websocket sunucusu oluştur con wss \u003d new WebSocket.Server ((port: 8080)); // clientValidator işlevi true döndürdüğünde istemcilere gönderilir. bu wss. wss.broadcast \u003d function (data, clientValidator \u003d () \u003d\u003e true) (this.clients.forEach (client \u003d\u003e (if (clientValidator (client))) (client.send (data);));) wss.on ("bağlantı", ws \u003d\u003e (// olay, istemci bir ws.on ("mesaj", mesaj \u003d\u003e (// wss.broadcast yazarı (mesaj, istemci \u003d\u003e istemci!) dışındaki herkese bir mesaj gönderdiğinde tetiklenecektir! \u003d\u003d ws);));));

Web yuvalarının nasıl çalıştığına dair bir örnek:

Web Soketleri İşleminin Gösterilmesi

HTTP Eşdeğeri

HTTP'nin kanalı sürekli olarak yeni mesajlar için kontrol etmesi gerektiğinden, istemcinin sunucuyu belirli bir frekansta yeni mesajlar için kontrol ettiği bir yaklaşım olan kirli bir kontrol kullanabilirsiniz (örneğin, her 200 ms'de bir).

Web Soketleri (WebSockets), "Eşzamansız JavaScript ve XML" (AJAX) 'ın ortaya çıkışından bu yana muhtemelen web teknolojisindeki en ilginç yeniliktir. HTML5'in piyasaya sürülmesiyle popüler hale geldiler ve birçok web çerçevesi tarafından destekleniyorlar.

Ancak, kararlı ve tutarlı bir web soket spesifikasyonu oluşturmak uzun zaman aldı.

Köprü Metni Aktarım Protokolü (HTTP) modeli, İnternet popüler hale gelmeden çok önce tasarlandı ve basit teknik özelliklere ve tasarıma dayanıyor. Geleneksel HTTP modelinde, istemci uygulama sunucusuna bir bağlantı açar, GET, POST, PUT veya DELETE türünde bir HTTP isteği gönderir ve HTTP sunucusu uygun yanıtı döndürür.

Geleneksel HTTP modeli, basit veri modelinin ötesine geçen hemen her uygulama için hantal olmuştur. " içerik al ve gönder"Katılımcıların herhangi bir sırayla mesaj gönderebildiği ve yüzlerce katılımcının aynı anda sohbet edebildiği bir sohbet uygulaması istemcisi hayal edin.

Bu tür amaçlar için standart yaklaşım " istek-yanıt"çok güçlü kısıtlamalar getiriyor. Bu kısıtlamaların üstesinden gelmek için ilk girişimler AJAX ve Comet idi. Her ikisi de sözde uzun anketlere dayanıyordu: HTTP bağlantısını açmak ve yanıtı tamamlamayarak onu aktif tutmak (bağlantıyı açık tutmak).

Bir istemci web soketlerini kullanarak " çiğ"sunucu için soket ve tam çift yönlü iletişim gerçekleştirme. Web soketleri desteği, JSR-356.

Javax.websocket paketi ve onun sunucu alt paketi, websocket ile ilgili tüm sınıfları, arabirimleri ve açıklamaları içerir.

Java EE platformunda websockets uygulamak için, aşağıda gösterildiği gibi websocket yaşam döngüsü yöntemleriyle bir uç nokta sınıfı oluşturmanız gerekir:

// Örnek uç nokta paketi com.devchronicles.websockets; public class HelloEndpoint, Endpoint'i genişletir (@Override public void onOpen (final Session session, EndpointConfig config) (session.addMessageHandler (new MessageHandler.Whole) () (@Override public void onMessage (String msg) (try (session.getBasicRemote (). SendText ("Merhaba" + msg);) catch (IOException e) ())); ))

// Örnek bitiş noktası

public class HelloEndpoint, Endpoint'i genişletir (

@Override

public void onOpen (son Oturum oturumu, EndpointConfig yapılandırması) (

oturum, toplantı, celse. addMessageHandler (yeni MessageHandler. Whole () {

@Override

public void onMessage (String msg) (

deneyin (

) catch (IOException e) ()

} ) ;

Uç nokta sınıfı üç yaşam döngüsü yöntemi sağlar: onOpen, onCloseve onError... Onu genişleten sınıf, en azından yöntemi uygulamalıdır onOpen.

Bir uç noktayı iki şekilde dağıtabilirsiniz: yapılandırmayla veya programla.

Kodu dağıtmak için uygulamanız aşağıdakileri çağırmalıdır:

ServerEndpointConfig.Builder.create (HelloEndpoint.class, "/ merhaba"). Build ();

ServerEndpointConfig. Oluşturucu. oluştur (HelloEndpoint. sınıfı, "/ merhaba"). inşa etmek ();

Genişletilmiş web soketi şu adreste mevcuttur: ws: // :// Merhaba... Bununla birlikte, konfigürasyonu açıklama yoluyla kullanmak daha iyidir. Bunu yaparken, aynı uç nokta aşağıdaki kod olur:

// Ek açıklama paketi içeren örnek uç nokta com.devchronicles.websockets; @ServerEndpoint ("/ merhaba") public class HelloEndpoint (@OnMessage public void onMessage (Session session, String msg) (try (session.getBasicRemote (). SendText ("Hello" + msg);) catch (IOException e) () ))

// Ek açıklamalar içeren örnek uç nokta

paket com. aygıtlar. web soketleri;

@SunucuEndpoint ("/ merhaba")

public class HelloEndpoint (

@OnMessage

public void onMessage (Session session, String msg) (

deneyin (

oturum, toplantı, celse. getBasicRemote (). sendText ("Merhaba" + msg);

) catch (IOException e) ()

Bu yaklaşım, eski tarz basit Java yaklaşımını izleyerek ek açıklamaları kullanmanıza olanak tanır ( POJO) çünkü temel sınıfı genişletmiyorsunuz. Açıklamalı uç nokta, ilk kod örneğiyle aynı yaşam döngüsü yöntemlerine sahiptir, ancak ek bir onMessage yaşam döngüsü yöntemi.

Uygulamak yerine Açık ve bir işleyici eklemek onMessage açıklama tabanlı yaklaşımda, açıklamalı yaşam döngüsü yöntemini uygulamak yeterlidir onMessage... İle açıklama ekleyebilirsiniz @Mahmutcu farklı veri türlerini elde etmek için çeşitli yöntemler Dize veya ByteBuffer ikili veriler için.

Bir web soketinin istemci tarafı uygulaması, kullanılan web çerçevesine bağlıdır. Her ne olursa olsun, aşağıdaki kod parçası basit bir dil sürümünü gösterir JavaScript:

var webSocket \u003d new WebSocket ("ws: //127.0.0.1: 8080 / websockets / merhaba"); webSocket.send ("dünya");