Socket.io ile Çok Oyunculu Oyun Kurulumu | hyperPad Documentation

Loading...

Logo

z-f2VkDQ.jpg

1. Giriş

Tercih Edilen Ön Koşullar

Bu eğitimde, bir sunucu kurma ve oyununuzu ona bağlayarak Socket.io davranışları aracılığıyla projeniz için çok oyunculu işlevleri etkinleştirme üzerine odaklanacağız. hyperPad'deki diğer karmaşık özellikler ve davranışları ele alacağız ve ilerlemeden önce yazılı programlamanın iyi bir anlayışına sahip olmanız şiddetle önerilir.

Bu eğitim, hyperPad'in temel işlevleri hakkında iyi bir anlayışa sahip olduğunuzu ve yazılı programlamaya dair minimum bir anlayışa sahip olduğunuzu varsaymaktadır, çünkü bir oyun sunucusu oluşturmak için Javascript betimlemelerini kullanacağız. Bu eğitim ayrıca temel ağ bilgisi ve bir sunucu ile istemcileri arasındaki farkları da varsaymaktadır.

Bu eğitimin ana amacı, oyununuza çok oyunculu işlevsellik eklemek için gerekli olanları öğretmektir; oyunu kendisini oluşturmak değil. Socket.io istemcileri ve sunucu arasındaki ilişkiyi ve aralarındaki iletişimin nasıl kurulduğunu keşfedeceğiz.

Gereksinimler

Sunucuyu oluşturmak ve barındırmak için, Node.JS çalıştırabilen bir bilgisayara ihtiyacınız olacak (Mac, Windows vb.). Node.JS'yi yüklemek ve amacımız için ayarlamak bu eğitimde kapsanacaktır. Eğer ev ağınızda bir sunucu barındırıyorsanız, dış ağdan gelen bağlantıları almak istiyorsanız, muhtemelen ağ geçidinizin port yönlendirme ayarlarını değiştirmeniz gerekecektir.

Bu eğitim için, zaten basit bir demo oyunu oluşturduk. İçinde, iki oyuncunun küçük bir labirentte bir tag oyunu oynadığı bir senaryo bulunmaktadır. Socket.io davranışlarının bu örnek projede nasıl kullanıldığını keşfedeceğiz, bu yüzden projeyi hyperPad'de indirip açmanız önerilir.

Tamamlanmış hyperPad örnek projesini buradan indirebilirsiniz: Multiplayer tag tutorial.tap

Genel Bakış

Bu eğitimde, oyununuz için bir sunucu oluşturmanın temellerine değineceğiz. Sunucu, oyundaki çoğu detayı; skorlama, oyun lobbileri vb. gibi, yönetecektir. Ardından, oyunumuzdan sunucuya ve tersi yönde bilgi gönderen davranışları oluşturacağız.

Oyunumuzun genel akışı şu şekildedir:

1. Ana menüden sunucumuza bağlanacağız ve kullanıcıya ya bir oyun oluşturmayı ya da bir oyuna katılmayı seçtireceğiz.

a. Oyun oluşturuyorsa, bekleme odasını yükle.

b. Oyun katılıyorsa, mevcut oyun odalarının listesini yükle.

c. İki oyuncu bir bekleme odasında olduğunda, oyun başlar.

2. Bir oyunda, sunucu oyuncuları rastgele dört alandan birine yerleştirir ve onlardan birini 'Tag' olarak atar.

a. Diğer oyuncuyu etiketlemek, onların konumlarını rastgele değiştirecek, 'It' durumunu değiştirecek ve etiketleyen oyuncuya bir puan ekleyecektir.

b. Belirli bir süre içinde etiketleme gerçekleşmezse, sunucu, şu anda 'It' olan oyuncudan 1 puan düşecek ve 'It' durumunu değiştirerek oyuncuları yeniden doğma alanlarına rastgele yerleştirecektir.

3. Bir oyuncu belirli bir puan sayısına ulaştığında, bir kazananı belirten bir overlay açılır. Ardından, oyuncular odadan ayrılır ve ana menüye geri dönerler.

2. Bölüm: Sunucunun Kurulumu

Bir Socket.io sunucusu oluşturmak, oyuncu bağlantılarını dinleyen Socket.io kütüphanesini kullanan bir Javascript uygulaması çalıştırmamızı gerektirir. Socket.io, ağlı bir uygulama oluşturmanın birçok iç işleyişini bizim için basitleştiren bir Javascript ağ kütüphanesidir. Daha fazla detay aşağıda.

Node.JS'yi İndirin ve Kurun

Başlamak için, Node.JS sayfasına gidin ve sunucuyu barındırmak istediğiniz bilgisayara (Mac, Windows vb.) indirin. İndirme işlemi bittiğinde, yükleyiciyi çalıştırın ve talimatlarına uyun. Kurulum sırasında tüm seçenekleri varsayılan olarak bırakabilirsiniz. Node.JS, Javascript uygulamalarını web tarayıcısına ihtiyaç duymadan kendi başına çalıştırmamızı sağlar.

Örnek Sunucuyu İndirme ve Çalıştırma

Sonrasında, bu eğitimin Çok Oyunculu Sunucu Örneğini GitHub'dan indirin:

https://github.com/hyperPad/multiplayerServerExample

"Clone or download" butonuna tıklayın ve "Download ZIP" seçeneğini seçin. Bu, sunucu örneği için kodun bir kopyasını indirecektir.

chrome_2019-08-05_14-22-14.png

İndirilen ZIP dosyasını çıkarın. İçinde birkaç küçük dosya bulacaksınız, ancak burada en dikkat çekici dosya "index.js" dosyasıdır; bu, sunucumuzun kodunu içerir. Bir sonraki adımda, sunucu örneği klasöründe komut satırınızı/terminalinizi açın.

"npm install" yazın ve enter'a basın, ardından çalışmasına izin verin. npm, package.json dosyasını okuyan ve sunucumuz içi gereken paketleri (Socket.io dahil!) indiren bir paket yöneticisidir.

cmd_2019-08-05_14-55-19.png

Komut tamamlandığında, sunucuyu çalıştırmak için gereken her şeyi almış olursunuz. Terminalde "node ." yazın ve sunucu başlatılacaktır.

cmd_2019-08-05_15-02-38.png

Hepsi bu kadar! Artık sunucumuz, gelen Socket.io bağlantılarını dinliyor.

"node ." komutu, mevcut dizindeki Node.JS'yi başlatır; burada dizin indeks dosyasını arayacak ve çalıştıracaktır. Varsayılan olarak, bu, sunucumuzun kodunun büyük kısmının bulunduğu "index.js" Javascript dosyasıdır ve bu eğitim boyunca incelenecektir.

Terminali açık bırakın; çünkü kapatmak sunucuyu da kapatacaktır. Oyuncuların bağlanması veya ayrılması, odaların oluşturulması veya yok edilmesi gibi olaylarda terminalde mesajlar yazdırılacaktır.

Not: Dış ağdan gelen bağlantıları kabul etmek için, muhtemelen ev ağ geçidinizde port 3000'i açmanız gerekecektir. Bu işlem ağdan ağ geçidine değişiklik gösteriyor, ancak genellikle ev modem/route için bir port yönlendirme kılavuzu bulmak için İnternet'te bir arama yapmak yeterlidir. Port yönlendirme ayarlarını değiştirdiğinizde Node.JS sunucusunu kapatıp yeniden başlatmanız gerekebilir.

3. Bölüm: Sunucuya Bağlanma

Sunucu temelini oluşturduktan sonra, artık hyperPad oyununda buna bağlanabiliriz. Projenizde hangi sahnede olursanız olun, bu işlemin gerçekleşmesi gereken ilk şey olarak ayarlanmalıdır (çünkü her şey sunucu ile iletişim kurmalıdır). Bu davranışı, tüm sahnelerde uygulanması için Global Katman üzerindeki bir nesneye iliştirmek en iyisidir.

Untitled.jpg

Örnek projede, Global Katmanın "Server" etiketi yukarıdaki şekilde içerir. (Projeyi indirme, bu eğitimin Gereksinimler bölümünde bulunmaktadır.)

Bu iki davranış, sunucuya bağlanmak için gereken her şeydir. İlk olarak, özel tab altında, Socket.io İstemci davranışını alın ve bırakın. Burada, özellikler penceresindeki URL sekmesine sunucunuzun URL'sini gireceksiniz. Yukarıdaki resimde, sunucumuzun URL'si "http://192.168.0.191:3000" idi; protokol ve port dahil. Bu, sunucu URL'nizle eşleşecek şekilde değiştirmeniz gereken bir şeydir, aksi halde oyuna başladığınızda muhtemelen çalışmayacaktır.

Artık istediğimiz sunucu bilgisine sahibiz, ancak hala ona bağlanmamız gerekiyor. Bu yüzden yapmamız gereken tek şey Bağlanma Socket davranışını eklemektir. Bir tane bırakın, özelliklerini açın ve boş kutudaki istemciyi seçin ve Fonksiyon özelliğini "Bağlan" olarak ayarlayın.

Artık projemiz yüklendiğinde, otomatik olarak sunucumuza bağlanacağız.

mceclip1.png

4. Bölüm: Odaları Oluşturma ve Katılma

Bir sonraki adım, oyuncuların katılabileceği ve birlikte oynayabileceği oyun lobilerini oluşturmaktır.

mceclip2.png

İşte basit Ana Menü ekranımız. Tek yapmanız gereken, bir odanın başlaması için bir düğmeye dokunmak ya da mevcut odalar aramak.

Odaları Oluşturma

Odamızı oluşturmak için sunucu ile nasıl iletişim kurduğumuzu kontrol edelim.

mceclip3.png

Oldukça basit değil mi? Hızlıca üzerinden geçmemiz gerekirse, düğmemize dokunduğumuzda bir oda adı yazmamız için uyarılırız. Bunun ardından, bu ad sunucuya iletilir ve oda oluşturulur; ve bekleme odası sahnesine yükleniriz.

Buradan itibaren, Socket'e Emit kullanımı sık olacak. Bu, verileri sunucuya göndermenin ana yoludur. Onu yalnızca Broadcast Message ve Receive Message'nin "çevrimiçi versiyonu" olarak düşünün (Emit to Socket her iki işlevi de aynı anda yerine getirir).

Şimdi, sunucumuzda bir bilgi eklememiz gerekiyor, böylece Emit davranışımızdan gelen mesajı aldığında oda oluşturur.

mceclip4.png

socket.on('createRoom', (roomName, callback) => {

Bu satır, sunucuda 'createRoom' olayı ile Emit'leri dinleyen bir socket olayı (lambda ifadesi olarak) oluşturur.

İlk parametre, Emit to Socket davranışıyla geçtiğimiz değerdir; bu durumda kullanıcının yazdığı oda adıdır. Burada, bu parametreye 'roomName' adını verdik.

İkinci parametre, socket olayı içinde sonra çağıracağımız bir işlevdir. Emit to Socket davranışı yalnızca geri arama işlevi sunucuda çağrıldığında devam eder. Burada, bu parametreye 'callback' adını verdik.

const room = {
id: uuid(),
name: roomName,
sockets: []
};

Bu, bir odanın temel bilgilerini içeren bir yapı örneği oluşturacaktır.

'id', 'uuid()' yardımcı işleviyle oluşturulan benzersiz bir tanımlayıcı olacaktır. Bu, bu odayı daha sonra oluşturulan birçok başka odanın listesinin karşısında spesifik olarak belirlememize yardımcı olacaktır.

'name', kullanıcının daha önce yazdığı adı alacaktır.

'sockets', boş bir dizi olarak başlatılacaktır. Daha sonra, bu odaya bağlanan oyuncu soketlerini takip edecektir.

rooms[room.id] = room;

'rooms', şu anda aktif olan odaların küresel bir listesi. Yeni bir oda oluşturduğumuzdan, bunu kimliği ile listede depolayacağız.

joinRoom(socket, room);

Bu, oyuncu soketini odanın 'sockets' dizisine eklemek için 'joinRoom' küresel işlevini çağıracaktır. Oyuncu odayı oluşturduğundan, bu da onun katılmasını sağlayacaktır.

callback();
});

Son olarak, oda oluşturulmuş olması için geri çağırma işlevini tetikliyoruz. Bu, Emit to Socket'ın devam etmesine izin verecek, böylece bir sonraki olarak Bekleme Odası sahnesini yükleyecektir. Bu ayrıca 'createRoom' socket olayının sonunu işaret eder.

Odaları Katılma

Odak odalarına katılmak biraz farklıdır; çünkü bir düğmeden farklı bir sahneden bilgiye erişmemiz gerekecektir.

mceclip5.png

Odaya katılma için, sunucuya bağlandığımızda temel davranışlarımızı global katmanımıza yerleştirdik. Bu şekilde, sahnelerimizden herhangi birinde bilgilere erişebiliriz; bu durumda oda listesini. Düğmeye dokunmak, sizi yalnızca oyuncunun odalar listesini yükleyecektir.

Burada sunucu ile iletişim kurma için ikinci davranışımıza sahibiz. Socket Olayı, yalnızca sunucudan belirlenen mesaj yayımlandığında aktive olduğu için, Alıcı Mesajı gibi düşünülebilir.

Socket Olayı ve Emit to Socket kullanırken düşünmenin en iyi yolu, Socket Olayının yalnızca sunucudan gelen bilgiye tepki vermesi, Emit to Socket'in ise yerel olarak gerçekleştirilen şeylere tepki olarak adlandırılmasıdır.

Mantık olarak, sunucuya bağlandığımızda, mevcut oda isimlerini almak için 'getRoomNames' talebini Emit edeceğiz.

mceclip19.png

Daha sonra, oyuncunun katılabileceği bir etiket ayarlayacağız.

mceclip6.png

Bu, Oda Listesi sahnesidir. Burada mevcut oyun odaları yüklenecek ve görüntülenecektir. Sadece oda adına dokunarak oyuncu içeri alınacaktır. Önceki davranışlarımız sayesinde, liste otomatik olarak açık odaları yükleyecek ve oda adı etiketlerini ekrana yerleştirecektir. Hiçbir şey görünmüyorsa, tekrar yüklemek için Refresh List butonumuz var.

mceclip8.png

Burada listeyi oluşturma için mantığı belirledik. Burada çok fazla ayrıntıya girmeyeceğiz çünkü bu mantığın sunucuyla nasıl bağlantılı olduğunu anlamak istiyoruz.

Başlamak için, sunucunun mevcut odaların bilgilerini göndermesi için Emit to Socket davranışına sahibiz. Oradan, Gelen Dizi Değeri davranışı alarak gidecektir. Sunucudan gelen tüm veriler Dizi olarak gönderilecektir ve gerekli bilgi ilk değerlere olacaktır. Bu yüzden, Get Array Value davranışımızı 0. indekste değer elde etmek için ayarlıyoruz. Oradan, davranışlarımız bu verileri çıkartacak ve her odanın bir etiketini oluşturup ekranımızda görüntüleyecektir.

Sonrasında, tıklamamız gereken nesne kontrol edilecektir; sahnemizde bu, Oda Adı olan etikettir.

mceclip9.png

Bu metin, bulunduğunda düğme görevini üstlenmektedir, ancak katılmak istediğimiz oda kimliğini iliştirmek için hala ihtiyacımız vardır. Bunu yapmak için ilk olarak oda kimliğini almalı ve Get Attribute davranışıyla dinamik olarak ayarlarımıza geçmeliyiz. Ardından, sunucuya bu odaya katılmak istediğimizi Emit ederiz ve bekleme odasına yükleyeceğiz.

mceclip10.png

socket.on('joinRoom', (roomId, callback) => {

Bu, 'joinRoom' socket olayının giriş noktasıdır. İlk parametre, sunucuya iletilen ve katılmak istediğimiz oda kimliği olacaktır. Burada, bu parametreye 'roomId' adını verdik.

const room = rooms[roomId];
joinRoom(socket, room);

İstemciden verilen roomId kullanarak, sunucudaki doğru odanın örneğini bulabiliriz. Bununla birlikte, katılmak isteyen oyuncunun soketi ve oda örneği ile birlikte 'joinRoom' küresel işlevini çağırıyoruz. 'joinRoom' işlevine birazdan daha yakından bakacağız.

callback();
});

Son olarak, Bekleme Odası sahnesini yüklemeye devam etmek için geri çağırma işlevini tetikliyoruz; bu da 'joinRoom' socket etkinliğini sonlandırır.

Peki, 'joinRoom' işlevinde tam olarak ne oluyor? Bir bakalım.

mceclip11.png

room.socket.push(socket);

Daha önce bahsedildiği gibi, 'room.sockets' üye dizisi odadaki bağlanmış soketleri takip etmektedir. Bu satır işte bunu yaparak, soketi diziye eklemektedir.

socket.join(room.id, () => {
socket.roomId = room.id;
console.log(socket.id, "Katıldı", room.id);
});

Bu, istemcinin bir odaya bağlanmasını resmi olarak sağlayan çağrıdır. İlk önce, odayı kabul etmek için soketi yönlendiriyoruz. Bu sürec tamamlandığında, daha sonrasında geri çağırma işlevini çağırıyoruz ve oda kimliğini sokete ekliyoruz. Sonuncusu olarak, bir oyuncunun bir odaya katıldığını konsolda yazdırıyoruz!

mceclip12.png

Bekleme Odası

Bekleme odası, diğer oyuncuların katılmasını beklerken veya bir oyun başlamadan önce yüklenen bir sahnedir.

mceclip13.png

Odaya girdiğimizde, sunucuya 'hazır' mesajı yayarız. Sunucu iki tanesini aldığında, oyunun başladığını ileten bir mesaj gönderir ('initGame'). Bu mesajı Socket Olayı ile alırız ve böylece oyun aşamamız yüklenir. Davranışlarımız için, bunun hakkında bu kadar. İsterseniz, sizi ana menüye geri götürecek bir düğme ekleyebilirsiniz.

Sunucu tarafında, orada neler olup bittiğini analiz edelim.

mceclip14.png

Bu, bir istemcinin bir odaya katıldığında ve bağlanmaya hazır olduğunda çağrılan 'hazır' olaydır.

const room = rooms[socket.roomId];

Sokete oda kimliğini eklediğimiz için, odanın oyun başlatılma durumunu kontrol etmek amacıyla odayı alabiliriz.

if (room.sockets.length == 2) {

Şimdi odada bekleyen iki oyuncunun olup olmadığını kontrol ediyoruz. Diyelim ki bu doğru ve oyunu başlatmaya devam edelim.

for (const client of room.sockets) {
client.emit('initGame');
}

Artık iki oyuncu olduğuna göre, her soketi döngüye alıyor ve her istemcinin seviye sahnesini yüklemesi için 'initGame' olayını yayıyoruz, daha önce gösterildiği gibi.

5. Bölüm: Oyun

Artık işin özü ile karşı karşıyayız. İşte bu eğitim için tasarladığımız oyun seviyesi.

mceclip15.png

Bununla birlikte, daha önce "Oyun Mantığı" adlı bir etiketimiz var, bunu açalım ve inceleyelim.

mceclip16.png

Vay canına, bu kadar çok davranış! Ama endişelenmeyin; bu, oyuncuları oyuna yerleştirme şeklimizdir. Daha fazla yakından bakalım;

mceclip17.png

Sunucumuza oyunun başladığını bildiren bir Emit to Socket davranışı ile başlıyoruz; 'startGame' olayı ile. Ardından, sunucunun döndürdüğü diziyi alıyoruz, ilk değerine ulaşarak bir Dizi Değeri Al yöntemiyle nesnemizin ihtiyaç duyduğu çeşitli özellikleri alıyoruz. Ayrı bir ağaç, rakip oyuncunun benzer şekilde aynı şeyi yapmakta. Son olarak, oyuncu nesnemizi başlatmak için 'init' mesajını yayımlıyoruz.

Şimdi, 'startGame' olayını yaydığımızda sunucu tarafında neler olup gittiğine bakalım.

mceclip20.png

Bu socket olayının ilk yarısı, her istemci için bazı başlangıç değerleri ayarlamakta ve daha sonra, yayılan istemciler dışında kalan herhangi bir istemciyi 'others' dizisine eklemektedir.

mceclip21.png

İkinci yarıda, 'ack' adı verilen bir yerel sözlük listesi oluşturulmaktadır. İçinde kendimiz ve diğer istemcilere dair bilgiler vardır. Daha sonra, istemciye bu bilgileri geri göndermek, ki bu da Emit to Socket davranışımızın bir sonucu olarak oluşan değer olacaktır.

Daha sonra, oyun başlamadan önce herkesin ihtiyaç duyduğu tüm bilgileri alması için 5 saniye bekleme süresi yapılır. 'beginRound' işlevi (satır 99), bu proje için bazı oyun mantığını kontrol eder. Bunun etrafında çok fazla ayrıntıya girmeyeceğiz ama temelde oyuncuları nerede doğuracağımızı, puanları kontrol etmeyi ve ayrıca istemcilere bu oyuncunun 'It' olduğunu bildirmektedir.

Daha önce bahsettiğimiz 'init' mesajı, her şey hazır olduğunda "Oyun Mantığı" etiketimizde çağrılır. Artık oyuncu nesnemizde, 'init' mesajını aldığı zaman hangi davranışların uygulandığına bakalım.

mceclip22.png

Burada, oyuncunun oyundaki her şeyi başlatan birkaç davranış ağacına sahip olduğunu görebiliyoruz.

Öncelikle "init" mesajını alan bu davranış, nesnemizin sunucu üzerindeki kimliğini alır ve bir Socket Olayını etkinleştirmenin yanı sıra oyun ekranımızı kurarak karakterimizi doğru şekilde takip ederiz.

Hareket Senkronizasyonu

mceclip24.png

İşte en önemli davranışlarımızdan biri. Bu küçük ağaç, her seferinde joystickimizi hareket ettirdiğimizde oyuncumuzun konumunu sunucuda güncellemektedir. Muhtemelen, bu davranışın bazı sözlük değerlerine de atıfta bulunduğunu fark ettiniz. Bu değerleri, X ve Y konumlarını içeren bir tek başına sözlük davranışından alıyoruz.

Şimdi, sunucudaki 'moved' olayına bir göz atalım.

mceclip25.png

data = JSON.parse(data);

Sözlükler, bir istemciden sunucuya gönderilirken, verileri kolayca okumak için parselenmelidir. Bu, hyperPad'deki sözlüklerin, sunucuya yayıldığında JSON yapısına kodlandığı anlamına gelir. Bu satır, JSON dize yapısını parstahlayarak, sözlük listesini aynı yerel 'data' değişkenine kaydeder.

socket.x = data.x;
socket.y = data.y;

Burada, istemciden gelen yeni değerlerle birlikte soketteki X ve Y konumlarının güncellenmesine devam ediyoruz.

for (const client of room.sockets) {
if (client == socket) {
continue;
}
client.emit(socket.id, {
x: socket.x,
y: socket.y,
score: socket.score,
isIt: socket.isIt
});
}

Ardından, kendimiz dışında tüm istemcilere yeni konumumuzu ve diğer ayrıntıları güncelleyebilmek için tüm istemciler üzerinde yineleme yapıyoruz.

mceclip26.png

Burada, oyunumuzun büyük çoğunluğunu kontrol eden bu ağaç yer almakta. Sunucu; kimin 'It' olduğunu kontrol ettiğinde bir Socket Olayı kullanıyoruz ve bu, sunucu üzerindeki 'beginRound' (satır 99) ile yayıldıktan sonra ortaya çıkmaktadır.

Sonrasında, nesnemizin sunucudaki kimliğini alarak verileri almak üzere bir Genel Dizi Değeri Al davranışıyla birlikte, oyuncunun 'It' olduğu durumunu kontrol edeceğiz. Sonrasında, puanımızı, 'It' olup olmadığımızı ve nesnemizin x ve y konumlarını alır ve bunları nesnemizin değerlerine uygularız. Geri kalanı ise gameplay UI'sını tanımlamak ve kontrol etmek içindir.

Sonuç

Burada çok şey almak zor oldu, ancak umarım bu noktaya kadar geldiyseniz, oyuncular için Socket.io davranışlarını kullanarak çok oyunculu deneyimler oluşturma yöntemine dair bir anlayış kazanmışsınızdır.

Denemeyi kendiniz yapın! Oluşturduğunuz mevcut bir oyunu alın ve ona çevrimiçi işlevsellik eklemeye çalışın; örneğin, bir sunucuya bağlanan ve üst 10 puanın oyuncu isimleriyle liste halinde görüntüleyen bir yüksek skor liderlik sahnesi oluşturmak gibi.

Javascript gibi bir betimleme dilini tek bir makaleyle öğretmek zordur. Neyse ki, sorun yaşıyorsanız, Node.JS ve Socket.io için Javascript uygulamaları yazmanızda yardımcı olacak birçok kaynak bulunmaktadır;

Javascript Öğren - https://developer.mozilla.org/bm/docs/Web/JavaScript

Socket.io Öğren - https://socket.io/docs/

Node.JS Öğren - https://nodejs.org/en/docs/