﻿
{"id":10245,"date":"2019-02-01T01:20:23","date_gmt":"2019-02-01T01:20:23","guid":{"rendered":"http:\/\/www.gencayyildiz.com\/blog\/?p=10245"},"modified":"2019-02-01T01:20:23","modified_gmt":"2019-02-01T01:20:23","slug":"node-js-websockette-leave-fonksiyonu-ile-odadan-ayrilma","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/node-js-websockette-leave-fonksiyonu-ile-odadan-ayrilma\/","title":{"rendered":"Node.js &#8211; Websocket&#8217;te leave Fonksiyonu \u0130le Odadan Ayr\u0131lma"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>\u00d6nceki yaz\u0131lar\u0131mdan <a href=\"http:\/\/www.gencayyildiz.com\/blog\/node-js-websockette-namespace-ve-room-kavramlari-ve-kullanimlari\/\" rel=\"noopener\" target=\"_blank\">Node.js \u2013 Websocket\u2019te Namespace ve Room Kavramlar\u0131 ve Kullan\u0131mlar\u0131<\/a> ba\u015fl\u0131kl\u0131 yaz\u0131mda Node.js&#8217;de namespace ve room kavramlar\u0131n\u0131 detayl\u0131ca ele alarak pratik bir \u015fekilde incelemi\u015ftik. Bu i\u00e7eri\u011fimizde ise ba\u011flan\u0131lm\u0131\u015f bir odadan &#8220;leave&#8221; fonksiyonu ile ayr\u0131lmay\u0131 inceleyece\u011fiz. Tabi olay\u0131 komplike bir senaryo \u00fczerinden de\u011ferlendirece\u011fimizden dolay\u0131 ilk olarak adresini refere etti\u011fim \u00f6nceki makalemi sat\u0131r sat\u0131r okuman\u0131z\u0131, ard\u0131ndan bu i\u00e7eri\u011fimize g\u00f6z atman\u0131z\u0131 tavsiye ediyorum. E\u011fer haz\u0131rsan\u0131z ba\u015flayal\u0131m&#8230;<\/p>\n<p>\u0130lk olarak Node.js&#8217;de socket \u00e7al\u0131\u015fmas\u0131 yaparak, bir namespace alt\u0131nda ad\u0131n\u0131 opsiyonel olarak input de\u011ferinden alan odalara clientlar\u0131n ba\u011fland\u0131\u011f\u0131 sistem in\u015fa edelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nconst http = require(&quot;http&quot;);\r\nconst socketio = require(&quot;socket.io&quot;);\r\n\r\nconst server = http.createServer((request, response) =&gt; {\r\n     response.end(&quot;...&quot;);\r\n});\r\n\r\nconst io = socketio.listen(server.listen(9876, () =&gt; console.log(&quot;Broadcast Started&quot;)));\r\nconst roomNameSpace = io.of(&quot;\/rooms&quot;);\r\n\r\nlet clientCount = 0;\r\n\r\nroomNameSpace.on(&quot;connection&quot;, socket =&gt; {\r\n     clientCount++;\r\n     clientCountFunction();\r\n     socket.on(&quot;disconnect&quot;, () =&gt; { clientCount--; clientCountFunction(); });\r\n     socket.on(&quot;signRoom&quot;, data =&gt; {\r\n          socket.join(data.roomName, () =&gt; {\r\n               console.log(`${data.roomName} isimli odaya giri\u015f yap\u0131lm\u0131\u015ft\u0131r.`);\r\n               const roomClientCount = roomClientCountFunc(roomNameSpace, data);\r\n               roomNameSpace.to(data.roomName).emit(&quot;message&quot;, {\r\n                    roomName: data.roomName,\r\n                    roomClientCount: roomClientCount\r\n               });\r\n          });\r\n     });\r\n});\r\n\r\nconst clientCountFunction = () =&gt; roomNameSpace.emit(&quot;clientCount&quot;, clientCount);\r\nconst roomClientCountFunc = (roomsNameSpace, data) =&gt; {\r\n     const hasRoom = roomsNameSpace.adapter.rooms&#x5B;data.roomName]; \/\/ \u0130smi belirtilen odaya ba\u011fl\u0131 client say\u0131s\u0131...\r\n     \/\/Odadan en son client ayr\u0131ld\u0131ktan sonra oda imha edilir. Dolay\u0131s\u0131yla olas\u0131 hatayla kar\u015f\u0131la\u015fmamak i\u00e7in kontroll\u00fc hesaplama yap\u0131lmaktad\u0131r.\r\n     return hasRoom ? hasRoom.length : 0;\r\n}\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer &#8220;\/rooms&#8221; namespace&#8217;i alt\u0131nda bir socket \u00e7al\u0131\u015fmas\u0131 yap\u0131lm\u0131\u015f bulunmaktad\u0131r. Burada <strong>11.<\/strong> sat\u0131rda tan\u0131mlanm\u0131\u015f olan &#8220;clientCount&#8221; de\u011fi\u015fkeni sisteme dahil olan yani bir ba\u015fka deyi\u015fle namespace&#8217;e ba\u011flanan t\u00fcm aktif\/online \/\u00e7evrimi\u00e7i clientlar\u0131n ka\u00e7 adet oldu\u011funu bilebilmemiz i\u00e7in bir saya\u00e7 g\u00f6revi g\u00f6rmektedir. <strong>29.<\/strong> sat\u0131rdaki tan\u0131mlanm\u0131\u015f &#8220;clientCountFunction&#8221; fonksiyonu ise &#8220;clientCount&#8221; de\u011fi\u015fkeninin bilgisini t\u00fcm clientlara iletmek i\u00e7in olu\u015fturulmu\u015f bir fonksiyondur. Birden fazla noktada kullanaca\u011f\u0131m\u0131z i\u00e7in fonksiyon olarak tasarlanm\u0131\u015ft\u0131r. <strong>30.<\/strong> sat\u0131ra gelirsek ise keza &#8220;clientCountFunction&#8221; ile ayn\u0131 mant\u0131kta tan\u0131mlanm\u0131\u015f olan &#8220;roomClientCountFunc&#8221; fonksiyonu birden fazla noktada \u00e7a\u011fr\u0131lacakt\u0131r ve i\u015flevsel olarak ba\u011flan\u0131lan odadaki total client adedini bizlere d\u00f6nmekle g\u00f6revlidir. <\/p>\n<p>\u015eimdi backend&#8217;de tasarlanan yap\u0131ya uygun clientlar\u0131n kullanaca\u011f\u0131 html yap\u0131s\u0131n\u0131 dizayn edelim;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n     &lt;script src=&quot;https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jquery\/3.3.1\/jquery.min.js&quot;&gt;&lt;\/script&gt;\r\n     &lt;script src=&quot;https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/socket.io\/2.2.0\/socket.io.js&quot;&gt;&lt;\/script&gt;\r\n     &lt;script&gt;\r\n          const socket = io.connect(&quot;http:\/\/localhost:9876\/rooms&quot;);\r\n          socket.on(&quot;clientCount&quot;, data =&gt; $(&quot;#allClientCount&quot;).html(data));\r\n          $(() =&gt; {\r\n               $(&quot;#btnSign&quot;).click(() =&gt; {\r\n                    socket.emit(&quot;signRoom&quot;, {\r\n                         roomName: $(&quot;#txtRoomName&quot;).val()\r\n                    });\r\n                    $(&quot;#txtRoomName, #btnSign&quot;).attr(&quot;disabled&quot;, &quot;disabled&quot;);\r\n                    $(&quot;#btnLeave&quot;).css(&quot;display&quot;, &quot;&quot;);\r\n               });\r\n               socket.on(&quot;message&quot;, data =&gt; {\r\n                    $(&quot;#roomClientCount&quot;).html(data.roomClientCount);\r\n                    $(&quot;#message&quot;).append(`&lt;li&gt;Odaya giri\u015f yap\u0131ld\u0131.&lt;\/li&gt;`);\r\n               });\r\n          });\r\n     &lt;\/script&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n     &lt;input type=&quot;text&quot; id=&quot;txtRoomName&quot;&gt; &lt;button id=&quot;btnSign&quot;&gt;Sign In Room&lt;\/button&gt; | &lt;button id=&quot;btnLeave&quot; style=&quot;display:none;&quot;&gt;Leave\r\n          Room&lt;\/button&gt;&lt;br&gt;\r\n     &lt;strong&gt;Room Client Count : &lt;span id=&quot;roomClientCount&quot;&gt;&lt;\/span&gt; | All Client Count : &lt;span id=&quot;allClientCount&quot;&gt;&lt;\/span&gt;\r\n     &lt;\/strong&gt;\r\n     &lt;ul id=&quot;message&quot;&gt;\r\n     &lt;\/ul&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere client taraf\u0131nda &#8220;Sign In Room&#8221; butonuna t\u0131kland\u0131\u011f\u0131 zaman &#8220;signRoom&#8221; ad\u0131nda olay tetiklenmekte ve backend&#8217;de ilgili olay i\u00e7erisinde input&#8217;a girilen de\u011fer ad\u0131nda bir room olu\u015fturmaktad\u0131r. Ayriyetten a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde oldu\u011fu gibi olaylara ba\u011fl\u0131 bir \u015fekilde &#8220;Leave Room&#8221; butonu g\u00f6r\u00fcnt\u00fclenmekte ve input ile &#8220;Sign In Room&#8221; butonu disable edilmektedir.<\/p>\n<p><a href=\"http:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/02\/Node.js-Websockette-leave-Fonksiyonu-\u0130le-Odadan-Ayr\u0131lma.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/02\/Node.js-Websockette-leave-Fonksiyonu-\u0130le-Odadan-Ayr\u0131lma.gif\" alt=\"Node.js - Websocket&#039;te leave Fonksiyonu \u0130le Odadan Ayr\u0131lma\" width=\"800\" height=\"450\" class=\"aligncenter size-full wp-image-10252\" \/><\/a><\/p>\n<p>\u015eimdi leave fonksiyonu ile ba\u011flant\u0131 kurulan odadan ayr\u0131lma i\u015flemini ger\u00e7ekle\u015ftirelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nconst http = require(&quot;http&quot;);\r\nconst socketio = require(&quot;socket.io&quot;);\r\n\r\nconst server = http.createServer((request, response) =&gt; {\r\n     response.end(&quot;...&quot;);\r\n});\r\n\r\nconst io = socketio.listen(server.listen(9876, () =&gt; console.log(&quot;Broadcast Started&quot;)));\r\nconst roomNameSpace = io.of(&quot;\/rooms&quot;);\r\n\r\nlet clientCount = 0;\r\n\r\nroomNameSpace.on(&quot;connection&quot;, socket =&gt; {\r\n     clientCount++;\r\n     clientCountFunction();\r\n     socket.on(&quot;disconnect&quot;, () =&gt; { clientCount--; clientCountFunction(); });\r\n     socket.on(&quot;signRoom&quot;, data =&gt; {\r\n          socket.join(data.roomName, () =&gt; {\r\n               console.log(`${data.roomName} isimli odaya giri\u015f yap\u0131lm\u0131\u015ft\u0131r.`);\r\n               const roomClientCount = roomClientCountFunc(roomNameSpace, data);\r\n               roomNameSpace.to(data.roomName).emit(&quot;message&quot;, {\r\n                    roomName: data.roomName,\r\n                    roomClientCount: roomClientCount\r\n               });\r\n          });\r\n     });\r\n     socket.on(&quot;leaveRoom&quot;, data =&gt; {\r\n          socket.leave(data.roomName, () =&gt; {\r\n               const roomClientCount = roomClientCountFunc(roomNameSpace, data);\r\n               roomNameSpace.to(data.roomName).emit(&quot;message&quot;, {\r\n                    roomName: data.roomName,\r\n                    roomClientCount: roomClientCount,\r\n                    leaved: true\r\n               }); \/\/ Odadaki di\u011fer clientlara son durum bilgisi vermek i\u00e7in tetikleniyor.\r\n               socket.emit(&quot;message&quot;, {\r\n                    roomName: data.roomName,\r\n                    roomClientCount: &quot;&quot;,\r\n                    leaved: true\r\n               });\/* \u00dcstteki tan\u0131mlanan emit odadaki t\u00fcm clientlar i\u00e7in ge\u00e7erlidir.\r\n                     Dolay\u0131s\u0131yla mevcut kullan\u0131c\u0131da odadan \u00e7\u0131kt\u0131\u011f\u0131 i\u00e7in bir olay ger\u00e7ekle\u015fmeyecektir.\r\n                     Son durumdan haberdar etmek i\u00e7in ilgili client'a \u00f6zel event f\u0131rlat\u0131lmaktad\u0131r.*\/\r\n          });\r\n     });\r\n});\r\n\r\nconst clientCountFunction = () =&gt; roomNameSpace.emit(&quot;clientCount&quot;, clientCount);\r\nconst roomClientCountFunc = (roomsNameSpace, data) =&gt; {\r\n     const hasRoom = roomsNameSpace.adapter.rooms&#x5B;data.roomName]; \/\/ \u0130smi belirtilen odaya ba\u011fl\u0131 client say\u0131s\u0131...\r\n     \/\/Odadan en son client ayr\u0131ld\u0131ktan sonra oda imha edilir. Dolay\u0131s\u0131yla olas\u0131 hatayla kar\u015f\u0131la\u015fmamak i\u00e7in kontroll\u00fc hesaplama yap\u0131lmaktad\u0131r.\r\n     return hasRoom ? hasRoom.length : 0;\r\n}\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer &#8220;leaveRoom&#8221; event\u0131n\u0131n eklendi\u011fini g\u00f6receksiniz. Burada &#8220;leave&#8221; fonksiyonu kullan\u0131larak ad\u0131 belirtilen odadan \u00e7\u0131k\u0131\u015f sa\u011flan\u0131lm\u0131\u015f, bir ba\u015fka deyi\u015fle ayr\u0131l\u0131nm\u0131\u015ft\u0131r. Ayriyetten odadan ayr\u0131l\u0131nd\u0131\u011f\u0131na dair odaya ba\u011fl\u0131 di\u011fer clientlarla birlikte ayr\u0131lan client &#8220;message&#8221; event\u0131 ile bilgilendirilmektedir.<\/p>\n<p>Son geli\u015ftirmenin ilgili html d\u00fczenlemesine gelirsek e\u011fer;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n     &lt;script src=&quot;https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jquery\/3.3.1\/jquery.min.js&quot;&gt;&lt;\/script&gt;\r\n     &lt;script src=&quot;https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/socket.io\/2.2.0\/socket.io.js&quot;&gt;&lt;\/script&gt;\r\n     &lt;script&gt;\r\n          const socket = io.connect(&quot;http:\/\/localhost:9876\/rooms&quot;);\r\n          socket.on(&quot;clientCount&quot;, data =&gt; $(&quot;#allClientCount&quot;).html(data));\r\n          $(() =&gt; {\r\n               $(&quot;#btnSign&quot;).click(() =&gt; {\r\n                    socket.emit(&quot;signRoom&quot;, {\r\n                         roomName: $(&quot;#txtRoomName&quot;).val()\r\n                    });\r\n                    $(&quot;#txtRoomName, #btnSign&quot;).attr(&quot;disabled&quot;, &quot;disabled&quot;);\r\n                    $(&quot;#btnLeave&quot;).css(&quot;display&quot;, &quot;&quot;);\r\n               });\r\n               socket.on(&quot;message&quot;, data =&gt; {\r\n                    $(&quot;#roomClientCount&quot;).html(data.roomClientCount);\r\n                    if (!data.leaved)\r\n                         $(&quot;#message&quot;).append(`&lt;li&gt;Odaya giri\u015f yap\u0131ld\u0131.&lt;\/li&gt;`);\r\n                    else\r\n                         $(&quot;#message&quot;).append(`&lt;li&gt;Odadan \u00e7\u0131k\u0131\u015f yap\u0131ld\u0131.&lt;\/li&gt;`);\r\n               });\r\n               $(&quot;#btnLeave&quot;).click(() =&gt; {\r\n                    socket.emit(&quot;leaveRoom&quot;, {\r\n                         roomName: $(&quot;#txtRoomName&quot;).val()\r\n                    });\r\n                    $(&quot;#txtRoomName, #btnSign&quot;).removeAttr(&quot;disabled&quot;);\r\n                    $(&quot;#btnLeave&quot;).css(&quot;display&quot;, &quot;none&quot;);\r\n               });\r\n          });\r\n     &lt;\/script&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n     &lt;input type=&quot;text&quot; id=&quot;txtRoomName&quot;&gt; &lt;button id=&quot;btnSign&quot;&gt;Sign In Room&lt;\/button&gt; | &lt;button id=&quot;btnLeave&quot; style=&quot;display:none;&quot;&gt;Leave\r\n          Room&lt;\/button&gt;&lt;br&gt;\r\n     &lt;strong&gt;Room Client Count : &lt;span id=&quot;roomClientCount&quot;&gt;&lt;\/span&gt; | All Client Count : &lt;span id=&quot;allClientCount&quot;&gt;&lt;\/span&gt;\r\n     &lt;\/strong&gt;\r\n     &lt;ul id=&quot;message&quot;&gt;\r\n     &lt;\/ul&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<p>\u015feklinde olacakt\u0131r.<br \/>\n<a href=\"http:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/02\/Node.js-Websockette-leave-Fonksiyonu-\u0130le-Odadan-Ayr\u0131lma-1.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/02\/Node.js-Websockette-leave-Fonksiyonu-\u0130le-Odadan-Ayr\u0131lma-1.gif\" alt=\"Node.js - Websocket&#039;te leave Fonksiyonu \u0130le Odadan Ayr\u0131lma\" width=\"800\" height=\"450\" class=\"aligncenter size-full wp-image-10256\" \/><\/a><\/p>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Node.js &#8211; Websocket&#8217;te ba\u011flant\u0131 kurulan odadan &#8220;leave&#8221; fonksiyonu ile nas\u0131l ayr\u0131laca\u011f\u0131n\u0131 detayl\u0131ca incelemi\u015f bulunmaktay\u0131z.<\/p>\n<p>Makale i\u00e7eri\u011finde kulland\u0131\u011f\u0131m kaynak kodlar\u0131n\u0131 ve \u00f6rnek projeyi a\u015fa\u011f\u0131daki link \u00fczerinden elde edebilirsiniz.<br \/>\n<a href=\"http:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/02\/NodeJsWebSocketLeaved.rar\">Kaynak Kodlar ve \u00d6rnek Test Projesi<\/a><\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, \u00d6nceki yaz\u0131lar\u0131mdan Node.js \u2013 Websocket\u2019te Namespace ve Room Kavramlar\u0131 ve Kullan\u0131mlar\u0131 ba\u015fl\u0131kl\u0131 yaz\u0131mda Node.js&#8217;de namespace ve room kavramlar\u0131n\u0131 detayl\u0131ca ele alarak pratik bir \u015fekilde incelemi\u015ftik. Bu i\u00e7eri\u011fimizde ise ba\u011flan\u0131lm\u0131\u015f bir odadan &#8220;leave&#8221; fonksiyonu&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":8600,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2145],"tags":[2748,2147,2749,2750,2713],"class_list":["post-10245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-node-js","tag-leave-fonksiyonu","tag-node-js","tag-node-js-leave-fonksiyonu","tag-node-js-leave-function","tag-websocket"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=10245"}],"version-history":[{"count":11,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10245\/revisions"}],"predecessor-version":[{"id":10260,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10245\/revisions\/10260"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/8600"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=10245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=10245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=10245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}