WebSocket Programlama ve Node.js Socket.IO Modülü

By | 11 October 2016

İşin teknik detayına girmeden önce bir örnekle açıklamaya başlamak istiyorum. Diyelim ki; iki kullanıcının bir blog post okuduğunu ve ikisinin de sırayla yorum attığını düşünelim. İlk kullanıcı yorumu attı ve sunucuya gönderdi, peki ikinci kullanıcı, ilk kullanıcının yorumundan nasıl haberdar olacak? Sunucu tarafından, istemciye bir istek gönderemiyor.  Bu zamana kadar bunun çözümü örneğin Ajax ile her 5 saniyede bir sunucuya istek atarak; “Eğer yeni bir mesaj varsa, ver.” diyorduk ve sunucuya sormak zorunda kalıyorduk. Sunucu bu şekilde ikinci kullanıcıya, diğer yeni atılan yorumları gösterebiliyordu. Bu yöntemin sorunları başta; yorumun atılması ile yorumun alınması arasında bir gecikme oluyor, ikinci olarak da hiç yorum atılmamışsa bile istemci tarafından sürekli boşu boşuna “Yeni yorum var mı?” diye boşuna sunucuya soru soruluyor. Burada çözüm olarak WebSocket geliyor.

WebSocket, bir TCP bağlantısı ile karşılıklı yani istemci-sunucu, sunucu-istemci şeklinde veri alış verişine dayanan bir protokol. Bu şekilde istemci ve sunucu arasında açık olan ve isteyen istediği tarafa, istediği veriyi gönderebiliyor. Ayrıca normalde her isteğin, bir de cevabı olurdu. Her istekte veri Header paketi ile birlikte giderdi. WebSocket ile (defaultta böyle bir şey yok ama ayarlanabilir) ilk bağlantı kurulduğunda Header paketi gönderilir ve ondan sonraki isteklerde de geriye cevap beklenmez.

Node.js üzerinde en çok kullandığım modül olan Socket.io ile WebSocket çalıştıran ufak bir uygulama göstereceğim. Örneğimde express ve socket.io modüllerine ihtiyacım var, bunun için aşağıdaki komut ile ikisini kuruyorum.

npm install express socket.io

Kurulum tamamlandıktan sonra main.js adında aşağıdaki dosyayı oluşturuyorum. Kodları yorum satırlarıyla açıklama çalıştım.

//burada gerekli kütüphaneleri ve en basit haliyle http sunucusunu set ediyoruz.
var app = require("express")();
var http = require("http").Server(app);
var io = require("socket.io")(http);

http.listen(3000, () => {
  console.log("3000 portu dinleniyor...");
});

//sayfaya gelindiğinde index.html döndürüyoruz.
app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});

//connection callbacki yani bir bağlantı gerçekleştiğinde yapılacaklar.
var userCounter = 0;
io.on("connection", (socket) => {
  userCounter = userCounter + 1;
  console.log("Toplam " + userCounter + " kullanıcı aktif. ");

  //burada arayüz tarafından gelen mesaj bastırılıyor ve tekrar io.emit ile soket üzerinden gönderiliyor.
  socket.on("message", (text) => {
    console.log("Message: " + text);

    io.emit("show-message", text);
  });

  //bir istemci bağlantısını sonlandırdığında yapılacaklar.
  socket.on("disconnect", () => {
    userCounter = userCounter - 1;
    console.log("Bir kullanıcı ayrıldı. Toplam " + userCounter + " kullanıcı aktif.');
  });
});

Arka taraf bu şekilde, şimdi arayüz kısmına geçelim ve index.html dosyasını aşağıdaki gibi yazalım.

<!DOCTYPE html>
<html>
<head>
 <title>Socket.io Sample</title>
</head>
<body>
 <input id="text" type="text">
 <input id="submit" type="submit">
 <ul id="list">
 </ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
 "use strict";

 $(document).ready( () => {
   //yukarda kütüphanesini dahil ettiğimiz yerde socket nesnemizi oluşturuyoruz.
   var socket = io();

   //submit id'si tıklandığında text inputunda yazı alınıp, sunucu tarafındaki message callback'ini
   //bekleyen fonksiyona gönderiliyor.
   $('#submit').click( () => {
     socket.emit('message', $('#text').val());
     $('#text').val(''); 
   });

   //server tarafından gelen mesaj liste şeklinde bastırılıyor. 
   socket.on('show-message', (text) => {
     $('#list').append('<li>' + text + '</li>');
   });
 });
</script>
</body>
</html>
</pre>
<pre>

Burada senaryomuz butona tıklandığında input içinde veriyi server tarafına gönderilecek ve server’da işlenen veri tekrar arayüze soket bağlantığı üzerinden gönderiliyor. Kodları denerken butona tıklandığında sayfanın yenilenmemesine dikkat edin, çünkü tüm bağlantı soketler üzerinden gerçekleştiriliyor. Aşağıdaki gibi bir çıktıyla karşılaşıyoruz.

socket.io  sockeio

 

Mesela sayfayı iki kere yeniledim ve ayrılıp, tekrar geldiğim için aşağıdaki gibi bir çıktı verdi.

socket.io

WebSocket ve Socket.io modülü için anlatacaklarım şimdilik bu kadar. Bir dahaki yazımda görüşmek üzere… 🙂

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*