Node.js – Websocket’te leave Fonksiyonu İle Odadan Ayrılma

Merhaba,

Önceki 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 şekilde incelemiştik. Bu içeriğimizde ise bağlanılmış bir odadan “leave” fonksiyonu ile ayrılmayı inceleyeceğiz. Tabi olayı komplike bir senaryo üzerinden değerlendireceğimizden dolayı ilk olarak adresini refere ettiğim önceki makalemi satır satır okumanızı, ardından bu içeriğimize göz atmanızı tavsiye ediyorum. Eğer hazırsanız başlayalım…

İlk olarak Node.js’de socket çalışması yaparak, bir namespace altında adını opsiyonel olarak input değerinden alan odalara clientların bağlandığı sistem inşa edelim.

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

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

const io = socketio.listen(server.listen(9876, () => console.log("Broadcast Started")));
const roomNameSpace = io.of("/rooms");

let clientCount = 0;

roomNameSpace.on("connection", socket => {
     clientCount++;
     clientCountFunction();
     socket.on("disconnect", () => { clientCount--; clientCountFunction(); });
     socket.on("signRoom", data => {
          socket.join(data.roomName, () => {
               console.log(`${data.roomName} isimli odaya giriş yapılmıştır.`);
               const roomClientCount = roomClientCountFunc(roomNameSpace, data);
               roomNameSpace.to(data.roomName).emit("message", {
                    roomName: data.roomName,
                    roomClientCount: roomClientCount
               });
          });
     });
});

const clientCountFunction = () => roomNameSpace.emit("clientCount", clientCount);
const roomClientCountFunc = (roomsNameSpace, data) => {
     const hasRoom = roomsNameSpace.adapter.rooms[data.roomName]; // İsmi belirtilen odaya bağlı client sayısı...
     //Odadan en son client ayrıldıktan sonra oda imha edilir. Dolayısıyla olası hatayla karşılaşmamak için kontrollü hesaplama yapılmaktadır.
     return hasRoom ? hasRoom.length : 0;
}

Yukarıdaki kod bloğunu incelerseniz eğer “/rooms” namespace’i altında bir socket çalışması yapılmış bulunmaktadır. Burada 11. satırda tanımlanmış olan “clientCount” değişkeni sisteme dahil olan yani bir başka deyişle namespace’e bağlanan tüm aktif/online /çevrimiçi clientların kaç adet olduğunu bilebilmemiz için bir sayaç görevi görmektedir. 29. satırdaki tanımlanmış “clientCountFunction” fonksiyonu ise “clientCount” değişkeninin bilgisini tüm clientlara iletmek için oluşturulmuş bir fonksiyondur. Birden fazla noktada kullanacağımız için fonksiyon olarak tasarlanmıştır. 30. satıra gelirsek ise keza “clientCountFunction” ile aynı mantıkta tanımlanmış olan “roomClientCountFunc” fonksiyonu birden fazla noktada çağrılacaktır ve işlevsel olarak bağlanılan odadaki total client adedini bizlere dönmekle görevlidir.

Şimdi backend’de tasarlanan yapıya uygun clientların kullanacağı html yapısını dizayn edelim;

<!DOCTYPE html>
<html>
<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:9876/rooms");
          socket.on("clientCount", data => $("#allClientCount").html(data));
          $(() => {
               $("#btnSign").click(() => {
                    socket.emit("signRoom", {
                         roomName: $("#txtRoomName").val()
                    });
                    $("#txtRoomName, #btnSign").attr("disabled", "disabled");
                    $("#btnLeave").css("display", "");
               });
               socket.on("message", data => {
                    $("#roomClientCount").html(data.roomClientCount);
                    $("#message").append(`<li>Odaya giriş yapıldı.</li>`);
               });
          });
     </script>
</head>
<body>
     <input type="text" id="txtRoomName"> <button id="btnSign">Sign In Room</button> | <button id="btnLeave" style="display:none;">Leave
          Room</button><br>
     <strong>Room Client Count : <span id="roomClientCount"></span> | All Client Count : <span id="allClientCount"></span>
     </strong>
     <ul id="message">
     </ul>
</body>
</html>

Görüldüğü üzere client tarafında “Sign In Room” butonuna tıklandığı zaman “signRoom” adında olay tetiklenmekte ve backend’de ilgili olay içerisinde input’a girilen değer adında bir room oluşturmaktadır. Ayriyetten aşağıdaki ekran görüntüsünde olduğu gibi olaylara bağlı bir şekilde “Leave Room” butonu görüntülenmekte ve input ile “Sign In Room” butonu disable edilmektedir.

Node.js - Websocket'te leave Fonksiyonu İle Odadan Ayrılma

Şimdi leave fonksiyonu ile bağlantı kurulan odadan ayrılma işlemini gerçekleştirelim.

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

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

const io = socketio.listen(server.listen(9876, () => console.log("Broadcast Started")));
const roomNameSpace = io.of("/rooms");

let clientCount = 0;

roomNameSpace.on("connection", socket => {
     clientCount++;
     clientCountFunction();
     socket.on("disconnect", () => { clientCount--; clientCountFunction(); });
     socket.on("signRoom", data => {
          socket.join(data.roomName, () => {
               console.log(`${data.roomName} isimli odaya giriş yapılmıştır.`);
               const roomClientCount = roomClientCountFunc(roomNameSpace, data);
               roomNameSpace.to(data.roomName).emit("message", {
                    roomName: data.roomName,
                    roomClientCount: roomClientCount
               });
          });
     });
     socket.on("leaveRoom", data => {
          socket.leave(data.roomName, () => {
               const roomClientCount = roomClientCountFunc(roomNameSpace, data);
               roomNameSpace.to(data.roomName).emit("message", {
                    roomName: data.roomName,
                    roomClientCount: roomClientCount,
                    leaved: true
               }); // Odadaki diğer clientlara son durum bilgisi vermek için tetikleniyor.
               socket.emit("message", {
                    roomName: data.roomName,
                    roomClientCount: "",
                    leaved: true
               });/* Üstteki tanımlanan emit odadaki tüm clientlar için geçerlidir.
                     Dolayısıyla mevcut kullanıcıda odadan çıktığı için bir olay gerçekleşmeyecektir.
                     Son durumdan haberdar etmek için ilgili client'a özel event fırlatılmaktadır.*/
          });
     });
});

const clientCountFunction = () => roomNameSpace.emit("clientCount", clientCount);
const roomClientCountFunc = (roomsNameSpace, data) => {
     const hasRoom = roomsNameSpace.adapter.rooms[data.roomName]; // İsmi belirtilen odaya bağlı client sayısı...
     //Odadan en son client ayrıldıktan sonra oda imha edilir. Dolayısıyla olası hatayla karşılaşmamak için kontrollü hesaplama yapılmaktadır.
     return hasRoom ? hasRoom.length : 0;
}

Yukarıdaki kod bloğunu incelerseniz eğer “leaveRoom” eventının eklendiğini göreceksiniz. Burada “leave” fonksiyonu kullanılarak adı belirtilen odadan çıkış sağlanılmış, bir başka deyişle ayrılınmıştır. Ayriyetten odadan ayrılındığına dair odaya bağlı diğer clientlarla birlikte ayrılan client “message” eventı ile bilgilendirilmektedir.

Son geliştirmenin ilgili html düzenlemesine gelirsek eğer;

<!DOCTYPE html>
<html>
<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:9876/rooms");
          socket.on("clientCount", data => $("#allClientCount").html(data));
          $(() => {
               $("#btnSign").click(() => {
                    socket.emit("signRoom", {
                         roomName: $("#txtRoomName").val()
                    });
                    $("#txtRoomName, #btnSign").attr("disabled", "disabled");
                    $("#btnLeave").css("display", "");
               });
               socket.on("message", data => {
                    $("#roomClientCount").html(data.roomClientCount);
                    if (!data.leaved)
                         $("#message").append(`<li>Odaya giriş yapıldı.</li>`);
                    else
                         $("#message").append(`<li>Odadan çıkış yapıldı.</li>`);
               });
               $("#btnLeave").click(() => {
                    socket.emit("leaveRoom", {
                         roomName: $("#txtRoomName").val()
                    });
                    $("#txtRoomName, #btnSign").removeAttr("disabled");
                    $("#btnLeave").css("display", "none");
               });
          });
     </script>
</head>
<body>
     <input type="text" id="txtRoomName"> <button id="btnSign">Sign In Room</button> | <button id="btnLeave" style="display:none;">Leave
          Room</button><br>
     <strong>Room Client Count : <span id="roomClientCount"></span> | All Client Count : <span id="allClientCount"></span>
     </strong>
     <ul id="message">
     </ul>
</body>
</html>

şeklinde olacaktır.
Node.js - Websocket'te leave Fonksiyonu İle Odadan Ayrılma

Görüldüğü üzere Node.js – Websocket’te bağlantı kurulan odadan “leave” fonksiyonu ile nasıl ayrılacağını detaylıca incelemiş bulunmaktayız.

Makale içeriğinde kullandığım kaynak kodlarını ve örnek projeyi aşağıdaki link üzerinden elde edebilirsiniz.
Kaynak Kodlar ve Örnek Test Projesi

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

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

*

Copy Protected by Chetan's WP-Copyprotect.