Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları

Merhaba,

Bu içeriğimizde Node.js mimarisinde websocket teknolojisi terminolojisinden olan Namespace ve Room kavramlarına değineceğiz. Aslında bu kavramlar, işlevsel olarak kelime bazlı her ne kadar anlaşılabilir olsalarda, genel programlama bilgisi olan herkes tarafından da terminolojik manalarına çokta yabancı olmadığımız terimlerdir. Şöyle ki, bir namespace kavramı yazılım dünyasında yapıları kümelememizi sağlayan yapılardır. Hatta daha da terminolojik olursak yazılımı genel hatlarıyla belirleyen kütüphaneler oluşturmamızı ve bu kütüphanelerin namespace değerleri üzerinden birbirleriyle haberleşmesini sağlayan yapılardır diyebiliriz…

Gördüğünüz üzere bu içeriğimizde teorik olarak çokta yabancılık çekmeyeceğimiz kavramları inceleyeceğiz. Şimdi gelin Node.js – Websocket teknolojisiyle bu kavramları önbilgilerimiz eşliğinde bir kez daha değerlendirelim ve bir an önce içeriğimizin esas amacı olarak konuyu pratik boyutta değerlendirmeye başlayalım.

Websocket’te Namespace Nedir?

Node.js Websocket teknolojisinde socket çalışmalarımızı bölmek için Namespace diye nitelendirilen parçalar kullanılmaktadır. Namespaceler sayesinde socket işlemlerimizi parçalar eşliğinde yönetebilir ve bir işlemi bir diğerinden kolaylıkla ayırabiliriz.

Eğer ki, tarafımızdan bir namespace tanımlanmazsa yahut kullanmazsak, varsayılan olarak Default/Root/Global/Kök diye nitelendirilen namespace devreye girecek ve geçerli olacaktır.

Websocket’te Room Nedir?

Roomlar, namespaceler içerisinde bulunan yapılardır. Yani bir namespace, bir veya birden fazla room barındırabilir. Teknik olarak görevleri namespace içerisinde farklı parçalar oluşturmaktır. Bu parçalar birbirlerinden bağımsız bir şekilde kullanılabildiği gibi ihtiyaca dönük namespace genelinde ortak yorumlanabilirler.

Dikkat ederseniz her iki yapıda sunucu/server tarafında oluşturulmaktadır.

Websocket’te Namespace Oluşturmak

Eğer ki bir namespace tanımlamak isteniyorsa mevcut soket bağlantısı üzerinden “of” fonksiyonu ile ilgili namespace tanımlanabilir.

const http = require("http");
const socket = require("socket.io");

const server = http.createServer((request, response) => {
     response.end("...");
});
server.listen(1234);
const io = socket.listen(server);

const xnamespace = io.of("/xnamespace");
const ynamespace = io.of("/ynamespace");

Yukarıdaki kod bloğunda görüldüğü üzere “xnamespace” ve “ynamespace” olmak üzere iki adet namespace tanımlanmıştır.

xnamespace.on("connection", socket => {
     console.log("connect xnamespace");
});

ynamespace.on("connection", socket => {
     console.log("connect ynamespace");
});

Görüldüğü üzere tanımlanan her iki namespace “connection” eventını dinlemekte ve bir client tarafından bağlantı gerçekleştirileceği zaman console’a veri girmektedir.

Oluşturulan namespacelere, client tarafından bağlanmak isteniyorsa aşağıdaki gibi belirtilmesi yeterlidir.

--- index.html ---
<!DOCTYPE html>
<html lang="en">
<head>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
     <script>
          const socket = io.connect("http://localhost:1234/xnamespace");
     </script>
</head>
<body>
</body>
</html>

Yukarıdaki kod bloğunda bulunan bağlantı cümlesini detaylı incelemek için aşağıya alırsak eğer;

.
.
.
const socket = io.connect("http://localhost:1234/xnamespace");
.
.
.

Evet… Gördüğünüz gibi bir namespace’e bağlanmak için tek yapılması gereken socket adresinin yanına “/[Namespace Adı]” belirtilmesidir. Eğer ki bu belirtilmiyorsa sistem varsayılan/default namespace üzerinden çalışıyor demektir. Biz örneğimizde “xnamespace”i vermiş bulunmaktayız. Dolayısıyla bu sayfayı kullanacak olan clientlar “xnamespace” isimli namespace’e bağlanacak demektir.

Namespaceler, websocket çalışmalarındaki farklı yapısal çalışmaları birbirlerinden izole etmekte olduklarından dolayı birine bağlanan client bir diğerinden bağımsız seyr etmiş olacaktır. Şöyle ki;
Bir önceki “index.html” sayfası “xnamespace” isimli namespace’e bağlanmaktaydı. Birde aşağıda “ynamespace”e bağlanacak olan sayfayı oluşturalım.

<!DOCTYPE html>
<html lang="en">
<head>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
     <script>
          const socket = io.connect("http://localhost:1234/ynamespace");
     </script>
</head>
<body>
</body>
</html>

Şimdi bu sayfalara bağlanan clientların durumunu aşağıdaki ekran görüntüsünden inceleyelim.
Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları
Görüldüğü üzere namespaceler birbirlerinden izole bir şekilde çalışmaktadır.

Namespace Üzerinden Emit Oluşturmak

Namespace üzerinden emit oluştururken dikkat edilmesi gereken iki husus vardır. Bu iki hususu aşağıdaki namespaceli bir sockete bağlanmış html dosyası üzerinden değerlendirelim;

<!DOCTYPE html>
<html lang="en">
<head>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
     <script>
          const socket = io.connect("http://localhost:1234/xnamespace");
          $(() => {
               $("#btnLogin").click(() => {
                    socket.emit("login", $("#txtName").val());
               });
               socket.on("message", data => $("#message").append(`<li>${data}</li>`));
          });
     </script>
</head>
<body>
     <input type="text" id="txtName"> <button id="btnLogin">Giriş Yap</button>
     <ul id="message"></ul>
</body>
</html>
  • Eğer, “socket” isimli parametre üzerinden emit işlemi yaparsak sadece o anda mesaj gönderen client tarafında ilgili işlem yapılacaktır.
    xnamespace.on("connection", socket => {
         console.log("connect xnamespace");
         socket.on("disconnect", () => console.log("disconnect xnamespace"));
         socket.on("login", data => {
              socket.emit("message", data);
         });
    });
    

    Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları

  • Yok eğer namespace’e bağlı tüm clientlara işlem yapılacaksa broadcast komutunu kullanarak bu işlemi gerçekleştirebileceğimiz gibi direkt olarak namespace’i tarif eden “xnamespace” sabiti üzerinden de emit işlemini uygulayabiliriz.

    xnamespace.on("connection", socket => {
         console.log("connect xnamespace");
         socket.on("disconnect", () => console.log("disconnect xnamespace"));
         socket.on("login", data => {
              xnamespace.emit("message", data);
         });
    });
    

    Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları

Websocket’te Room Oluşturmak

Herhangi bir room’a bağlanabilmek için “join” fonksiyonu kullanılır. “join” fonksiyonu parametre olarak aldığı değerdeki odaya varsa bağlanmamızı, yoksa oluşturup bağlanmamızı sağlayan bir fonksiyondur.

xnamespace.on("connection", socket => {
     console.log("connect xnamespace");
     socket.on("disconnect", () => console.log("disconnect xnamespace"));
     socket.on("login", data => {
          socket.join(data, () => {
               console.log(`Connected. Root Name : ${data}`);
          });
     });
});

Görüldüğü üzere parametreden gelen değer adında room oluşturulmaktadır.

<!DOCTYPE html>
<html lang="en">
<head>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
     <script>
          const socket = io.connect("http://localhost:1234/xnamespace");
          $(() => {
               $("#btnLogin").click(() => {
                    socket.emit("login", $("#txtRoomName").val());
               });
               socket.on("message", data => $("#message").append(`<li>${data} odasına bağlanıldı.</li>`));
          });
     </script>
</head>
<body>
     <input type="text" id="txtRoomName"> <button id="btnLogin">Odaya Giriş Yap</button>
     <ul id="message"></ul>
</body>
</html>

Room Üzerinden Emit Oluşturmak

Oluşturulan odaya emit ile olay bağlayabilmek için “to” ya da “in” fonksiyonları kullanılmaktadır. Room üzerinden “Expect Sender” ve “Including Sender” olmak üzere iki farklı şekilde emit oluşturulabilir.

  • Expect Sender
    Mesajı gönderen kişi hariç o odada kim varsa herkese gönderir. “socket” parametresi ile gerçekleştirilir.

    xnamespace.on("connection", socket => {
         console.log("connect xnamespace");
         socket.on("disconnect", () => console.log("disconnect xnamespace"));
         socket.on("login", data => {
              socket.join(data, () => {
                   console.log(`Connected. Root Name : ${data}`);
              });
              socket.in(data).emit("message", data);
              //Ya da
              socket.to(data).emit("message", data);
         });
    });
    

    Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları
    Yukarıdaki ekran görüntüsüne dikkat ederseniz eğer bir odaya ilk defa girilmeye çalışıldığında mesaj yazdırılmamaktadır. Çünkü oda o esnada oluşturulmakta ve dolayısıyla oluşturulan o odaya ilk ilgili client giriş yapmış bulunmaktadır. Dolayısıyla kendisinden başka client olmadığından dolayı diğer clientta mesaj yazdırılmamaktadır. İlk adımdan sonra yine aynı odaya diğer client tarafından giriş yapılırsa bundan sonra odayı oluşturan client ilk giriş yapan olduğundan dolayı mesaj bu client tarafında tetiklenmektedir.

  • Including Sender
    Mesajı gönderende dahil o odadaki herkese gönderilir. “io” ya da “namespace” sabiti üzerinden gerçekleştirilir.

    xnamespace.on("connection", socket => {
         console.log("connect xnamespace");
         socket.on("disconnect", () => console.log("disconnect xnamespace"));
         socket.on("login", data => {
              socket.join(data, () => {
                   console.log(`Connected. Root Name : ${data}`);
              });
              xnamespace.in(data).emit("message", data);
              //Ya da
              xnamespace.to(data).emit("message", data);
         });
    });
    

    Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları

    Görüldüğü üzere odaya bağlı olan tüm clientlara(gönderende dahil) ilgili mesaj gösterilmektedir.

Ve son olarak aşağıdaki özet bilgiyle içeriğimizi noktalayalım.

Room örneklendirmelerinden anlaşılacağı üzere, bir client aynı anda birden fazla room’da bulunabilir…

İlgilenenlerin faydalanması dileğiyle…

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. Makaleden fevkalade yararlanmış bir kullanıcı dedi ki:

    Türküye’yi bir adım daha ileriye taşıyan bir makale. Sağ olun, var olun. Makalelerinizden mahrum bırakmayın bizi…

  1. 01 Şubat 2019

    […] yazılarımdan Node.js – Websocket’te Namespace ve Room Kavramları ve Kullanımları başlıklı yazımda Node.js’de namespace ve room kavramlarını detaylıca ele alarak pratik […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*