Jeśli to czytasz, prawdopodobnie jesteś zainteresowany stworzeniem aplikacji lub usługi, która wymaga dwukierunkowej komunikacji, którą może zainicjować każda ze stron. Node JavaScript (Node.js) można wykorzystać do szybkiego opracowania i wdrożenia takiej aplikacji przy użyciu WebSockets, które zostały zaprojektowane z myślą o tym przypadku użycia.
Co to jest WebSocket?
A WebSocket to komputerowy protokół komunikacyjny zapewniający dupleks kanały komunikacyjne za pośrednictwem pojedynczego połączenia TCP. Innymi słowy, pozwala urządzeniom obsługującym Internet komunikować się ze sobą, jedno działające jako klient, a drugie działające jako serwer, przy czym oba mogą inicjować komunikację.
Jakie rodzaje aplikacji korzystają z WebSockets?
Protokół WebSocket jest używany wszędzie tam, gdzie rozwiązanie wymaga komunikacji w czasie rzeczywistym, a przykładowe przypadki użycia obejmują:
WebSockets tworzą połączenie gniazda TCP pomiędzy wieloma urządzeniami lub procesami. Jak zostanie to omówione później, podobna funkcjonalność może być zaimplementowana przy użyciu HTTP Long Polling lub hostowanej usługi pub/sub, ale najpierw zbudujmy prosty przykład przy użyciu WebSockets i Node.js.
Czy Node.js jest dobry dla WebSockets?
Tak, Node.js jest doskonałym wyborem do implementacji websockets, ponieważ zapewnia szybkie i skalowalne środowisko po stronie serwera, które obsługuje popularną bibliotekę bibliotekę ws.
Dlaczego używamy Node.js dla WebSockets?
WebSockets wymagają trwałego połączenia między klientem a serwerem, co oznacza, że serwer musi być w stanie obsłużyć dużą liczbę jednoczesnych połączeń. Node.js wykorzystuje sterowany zdarzeniami, nieblokujący model I / O, dzięki czemu dobrze nadaje się do obsługi wymagań dotyczących zasobów aplikacji opartych na WebSocket.
Jak zaimplementować WebSockets w Node.js
Poniższy przewodnik przeprowadzi Cię przez proces tworzenia serwera WebSocket w Node.js i pokaże, jak można się z nim połączyć za pomocą klienta WebSocket działającego w przeglądarce.
Ile połączeń WebSocket może obsłużyć serwer Node.js?
Aplikacje produkcyjne mogą obsługiwać dziesiątki tysięcy połączeń WebSocket jednocześnie, ale dokładna liczba będzie zależeć od kilku czynników, takich jak zasoby sprzętowe serwera, przepustowość sieci i złożoność logiki aplikacji.
Przykład interfejsu API Node.js WebSocket - podstawowa aplikacja do czatu
Cały kod źródłowy powiązany z tym blogiem jest hostowany na GitHub
Aby zbudować podstawową aplikację do czatowania za pomocą WebSockets, potrzebny będzie zarówno komponent kliencki, jak i serwerowy.
W przypadku serwera użyjemy Node.js, a kod po stronie klienta będzie działał w przeglądarce internetowej, takiej jak Chrome.
Kod Node.js WebSockets (serwer)
Ta aplikacja będzie wymagać zarówno serwera WWW (serwer HTTP), jak i serwera WebSocket (wss). Serwer WWW pozwala nam załadować naszego klienta (działającego w przeglądarce), a serwer WebSocket obsługuje dwukierunkowe wiadomości czatu.
Jak utworzyć serwer websocket w NodeJS?
Utwórz aplikację Node.js i zainstaluj zarówno pakiet Express.js i 'wsktóre zapewnią odpowiednio nasz serwer WWW i serwer WebSocket.
npm init [Postępuj zgodnie z instrukcjami i zaakceptuj domyślne ustawienia] npm install --save express npm install --save ws
Część serwera WWW będzie obsługiwać pojedynczą stronę internetową dla klienta, websocket-client.html, na porcie 3000:
const express = require('express') const webserver = express() .use((req, res) => res.sendFile('/websocket-client.html', { root: __dirname }) ) .listen(3000, () => console.log(`Słuchanie na ${3000}`))
Serwer WebSocket można utworzyć w zaledwie kilku wierszach przy użyciu pakietu biblioteki Node.js WebSocket (ws):
const { WebSocketServer } = require('ws') const sockserver = new WebSocketServer({ port: 443 })
Pisanie zdarzeń Websocket dla przykładów NodeJS
Po utworzeniu instancji serwera WebSocket i określeniu portu, na którym ma działać, możemy zdefiniować dowolne działanie, które powinno nastąpić po nawiązaniu połączenia WebSocket. W naszym przypadku zapisujemy zdarzenia połączenia w konsoli i przekazujemy wszelkie otrzymane wiadomości do wcześniej połączonych klientów. WebSockets są zaprojektowane do działania na tych samych portach co HTTP/HTTPS (tj. 80 i 443).
sockserver.on('connection', ws => { console.log('New client connected!') ws.send('connection established') ws.on('close', () => console.log('Client has disconnected!') ws.on('message', data => { sockserver.clients.forEach(client => { console.log(`rozesłanie wiadomości: ${data}`) client.send(`${data}`) }) }) ws.onerror = function () { console.log('websocket error') } })
W ten sposób część serwerowa została zakończona. Za każdym razem, gdy wiadomość jest odbierana na dowolnym gnieździe, proxy przesyła wiadomość do każdego podłączonego klienta, co jest podstawą każdej aplikacji do czatu grupowego.
Pełny kod index.js wygląda następująco:
const express = require('express') const webserver = express() .use((req, res) => res.sendFile('/websocket-client.html', { root: __dirname }) ) .listen(3000, () => console.log(`Listening on ${3000}`)) const { WebSocketServer } = require('ws') const sockserver = new WebSocketServer({ port: 443 }) sockserver.on('connection', ws => { console.log('New client connected!') ws.send('connection established') ws.on('close', () => console.log('Client has disconnected!') ws.on('message', data => { sockserver.clients.forEach(client => { console.log(`rozłączenie wiadomości: ${data}`) client.send(`${data}`) }) }) ws.onerror = function () { console.log('websocket error') } })
I można go uruchomić z wiersza poleceń w następujący sposób:
node index.js
Komunikaty mogą być tekstowe lub zakodowane w formacie JSON (JSON.stringify). Ten kod domyślnie używa zestawu znaków utf-8.
Przykład kodu WebSockets (klient / przeglądarka)
Nie musimy instalować dodatkowego oprogramowania ani pakietów, aby korzystać z WebSockets w nowoczesnych przeglądarkach internetowych. Utwórz nasłuchujący WebSocket, podając poprawnie sformatowany URI:
const webSocket = new WebSocket('ws://localhost:443/');
I definiując procedurę obsługi zdarzeń, gdy wiadomość zostanie odebrana z serwera:
webSocket.onmessage = (event) => { console.log(event) document.getElementById('messages').innerHTML += 'Wiadomość z serwera: ' + event.data + "<br>"; };
To wszystko. Możemy teraz odbierać dane z serwera WebSocket.
Aby wysłać zdarzenie wiadomości z klienta, należy wysłać funkcję send() na obiekcie gniazda:
webSocket.send('hello')
Aby nasza aplikacja czatu była funkcjonalna, musimy tylko dodać pole wejściowe i przycisk "wyślij wiadomość", więc kod HTML frontendu powinien wyglądać mniej więcej tak (stylowanie i css pominięto dla zwięzłości):
<html> <head> </head> <body> <form id="input-form"> <label for="message">Enter Message:</label> <input type="text" id="message" name="message"><br><br> <input type="submit" value="Send"> </form> <div id="messages"></div> <script> const webSocket = new WebSocket('ws://localhost:443/'); webSocket.onmessage = (event) => { console.log(event) document.getElementById('messages').innerHTML += 'Wiadomość z serwera: ' + event.data + "<br>"; }; webSocket.addEventListener("open", () => { console.log("Jesteśmy połączeni"); }); function sendMessage(event) { var inputMessage = document.getElementById('message') webSocket.send(inputMessage.value) inputMessage.value = "" event.preventDefault(); } document.getElementById('input-form').addEventListener('submit', sendMessage); </script> </body> </html>
Upewnij się, że nadałeś swojej stronie HTML nazwę "websocket-client.html" i uruchom kilka kart w przeglądarce, nawigując do http://localhost:3000Wiadomości powinny być widoczne w każdej zakładce:
Tworzenie tej samej aplikacji czatu bez serwera Node.js
Jeśli nie masz serwera lub masz obawy dotyczące skalowania infrastruktury serwerowej, aby sprostać przyszłym wymaganiom aplikacji, powinieneś zdecydować się na hostowane rozwiązanie do komunikacji w czasie rzeczywistym, takie jak Socket.io lub PubNub.
PubNub to globalnie rozproszona i skalowalna platforma w chmurze, dzięki czemu nie musisz martwić się o wdrażanie i utrzymywanie serwerów na zapleczu. Zestawy SDK PubNub mogą identyfikować użytkowników i wysyłać wiadomości do określonych kanałów, które otrzymają tylko subskrybowani użytkownicy.
Jak więc można napisać prostą aplikację czatu przedstawioną powyżej za pomocą PubNub? Jedną z zalet PubNub jest to, że jest on niezależny od protokołu.PubNub wykorzystuje architekturę "publikuj" i "subskrybuj" (pub/sub) do wysyłania i odbierania dwukierunkowych wiadomości.
Przykład kodu JavaScript SDK
Najpierw należy dołączyć PubNub JavaScript SDK w nagłówku, dostępny z ich CDN:
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.7.2.2.min.js"></script>.
Aby zasubskrybować przychodzące wiadomości, utwórz instancję PubNub, zdefiniuj kanał i dodaj słuchacza:
var pubnub = new PubNub({ publishKey: 'demo', subscribeKey: 'demo', userId: "" + Math.random() }) pubnub.subscribe({ channels: ['ws-channel'] }) pubnub.addListener({ message: payload => { console.log() document.getElementById('messages').innerHTML += 'Wiadomość od klienta: ' + payload.message + "<br>"; } })
Strona zostanie zaktualizowana za każdym razem, gdy wiadomości zostaną odebrane na kanale "ws-channel". Powyższy kod używa kluczy "demo", ale można uzyskać niestandardowe klucze PubNub keys za darmo.
Aby wysyłać wiadomości przez PubNub, publikuj na tym samym kanale, który subskrybowałeś wcześniej, w tym przypadku:
pubnub.publish({ channel: 'ws-channel', message: inputMessage.value })
Model kanałowy jest bardzo elastyczny i rozszerzalny, ale w tym prostym przykładzie wystarczy po prostu wysyłać i odbierać wiadomości na tym samym kanale. Twoja wiadomość zostanie dostarczona w dowolne miejsce na świecie w czasie poniżej 100 ms.
Ponieważ wdrożenie PubNub nie wymaga komponentu serwera, cała aplikacja napisana w HTML i JS jest zawarta w jednym pliku:
<html> <head> <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.7.2.2.min.js"></script> </head> <body> <H1>Ten kod używa PubNub, który jest niezależny od protokołu</H1> <form id="input-form"> <label for="message">Enter Message:</label> <input type="text" id="message" name="message"><br><br> <input type="submit" value="Send"> </form> <div id="messages"></div> <script> var pubnub = new PubNub({ publishKey: 'demo', subscribeKey: 'demo', userId: "" + Math.random() }) pubnub.subscribe({ channels: ['ws-channel'] }) pubnub.addListener({ message: payload => { console.log() document.getElementById('messages').innerHTML += 'Wiadomość od klienta: ' + payload.message + "<br>"; } }) function sendMessage(event) { var inputMessage = document.getElementById('message') pubnub.publish({ channel: 'ws-channel', message: inputMessage.value }) inputMessage.value = "" event.preventDefault(); } document.getElementById('input-form').addEventListener('submit', sendMessage); </script> </body> </html>
Aktualną wersję tego kodu można zobaczyć pod adresem
https://pubnubdevelopers.github.io/nodejs-websocket-examples/pubnub-client.html
I to już wszystko! Aby uzyskać więcej informacji na temat rozwoju z PubNub, sprawdź ich zakres samouczków i demaAlternatywnie, sprawdź PubNub interaktywna wycieczka na żywo aby zrozumieć, w jaki sposób platforma zapewnia interaktywność aplikacji w czasie rzeczywistym.
Jak PubNub może ci pomóc?
Ten artykuł został pierwotnie opublikowany na PubNub.com
Nasza platforma pomaga programistom tworzyć, dostarczać i zarządzać interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych i urządzeń IoT.
Fundamentem naszej platformy jest największa w branży i najbardziej skalowalna sieć przesyłania wiadomości w czasie rzeczywistym. Dzięki ponad 15 punktom obecności na całym świecie obsługującym 800 milionów aktywnych użytkowników miesięcznie i niezawodności na poziomie 99,999%, nigdy nie będziesz musiał martwić się o przestoje, limity współbieżności lub jakiekolwiek opóźnienia spowodowane skokami ruchu.
Poznaj PubNub
Sprawdź Live Tour, aby zrozumieć podstawowe koncepcje każdej aplikacji opartej na PubNub w mniej niż 5 minut.
Rozpocznij konfigurację
Załóż konto PubNub, aby uzyskać natychmiastowy i bezpłatny dostęp do kluczy PubNub.
Rozpocznij
Dokumenty PubNub pozwolą Ci rozpocząć pracę, niezależnie od przypadku użycia lub zestawu SDK.