노드 JS 웹소켓 프로그래밍 예제
Published: 2023-11-28 14:38:39

이 글을 읽고 계신다면 양쪽에서 시작할 수 있는 양방향 통신이 필요한 애플리케이션이나 서비스를 만드는 데 관심이 있을 것입니다. 이 사용 사례를 염두에 두고 설계된 웹소켓을 사용하여 이러한 애플리케이션을 빠르게 개발하고 배포하는 데 노드 자바스크립트(Node.js)를 사용할 수 있습니다.

웹소켓이란 무엇인가요?
------------

A [웹소켓](https://www.pubnub.com/guides/what-are-websockets-and-when-should-you-use-them/) 은 컴퓨터 통신 프로토콜로 [이중](https://en.wikipedia.org/wiki/Duplex_(telecommunications)) 통신 채널을 제공하는 컴퓨터 통신 프로토콜입니다. 즉, 웹소켓을 사용하면 인터넷이 가능한 장치가 서로 통신할 수 있으며, 한 장치는 클라이언트 역할을 하고 다른 한 장치는 서버 역할을 하며 둘 다 통신을 시작할 수 있습니다.

### 어떤 유형의 애플리케이션이 웹소켓을 사용하나요?

웹소켓 프로토콜은 솔루션에 실시간 통신이 필요한 모든 곳에서 사용되며, 사용 사례의 예는 다음과 같습니다:

-   [채팅 앱](https://www.pubnub.com/solutions/chat/)
    
-   [주가 업데이트](https://www.pubnub.com/solutions/data-streaming/)
    
-   [지도에서 실시간 위치 추적](https://www.pubnub.com/solutions/geolocation/)
    
-   [실시간 청중 상호작용](https://www.pubnub.com/solutions/live-audience-engagement/)
    
-   [온라인 경매](https://www.pubnub.com/solutions/marketplaces/)
    
-   [IoT 디바이스 업데이트](https://www.pubnub.com/solutions/iot-device-control/)
    

웹소켓은 여러 장치 또는 프로세스 간에 TCP 소켓 연결을 생성합니다. 나중에 설명하겠지만, 다음을 사용하여 유사한 기능을 구현할 수 있습니다. [HTTP 롱 폴링](https://www.pubnub.com/learn/glossary/http-long-polling/) 또는 호스팅된 게시/서브 서비스를 사용하여 유사한 기능을 구현할 수 있지만, 먼저 WebSockets와 Node.js를 사용하여 간단한 예제를 구축해 보겠습니다.

웹소켓에 Node.js가 좋은가요?
-------------------

예, Node.js는 웹소켓을 구현하는 데 있어 널리 사용되는 [ws 라이브러리](https://www.npmjs.com/package/ws).

### 웹소켓에 Node.js를 사용하는 이유는 무엇인가요?

웹소켓은 클라이언트와 서버 간에 지속적인 연결이 필요하므로 서버가 많은 수의 동시 연결을 처리할 수 있어야 합니다. Node.js는 [이벤트 중심의](https://www.pubnub.com/guides/event-driven-architecture/) 비차단 I/O 모델을 사용하므로 웹소켓 기반 애플리케이션의 리소스 요구 사항을 처리하는 데 매우 적합합니다.

### Node.js에서 웹소켓을 구현하는 방법

다음 가이드에서는 Node.js에서 WebSocket 서버를 만드는 방법을 안내하고 브라우저에서 실행 중인 WebSocket 클라이언트를 사용하여 서버에 연결하는 방법을 보여 줍니다.

### Node.js 서버가 처리할 수 있는 WebSocket 연결 수는 몇 개인가요?

프로덕션 애플리케이션은 수만 개의 WebSocket 연결을 동시에 처리할 수 있지만 정확한 수는 서버 하드웨어 리소스, 네트워크 대역폭 및 애플리케이션 로직의 복잡성과 같은 여러 요인에 따라 달라집니다.

Node.js 웹소켓 API 예제 - 기본 채팅 애플리케이션
---------------------------------

이 블로그와 관련된 모든 소스 코드는 다음에서 호스팅됩니다. [GitHub](https://github.com/PubNubDevelopers/nodejs-websocket-examples)

웹소켓으로 기본적인 채팅 애플리케이션을 구축하려면 클라이언트와 서버 컴포넌트가 모두 필요합니다.

서버에는 Node.js를 사용하고 클라이언트 측 코드는 Chrome과 같은 웹 브라우저에서 실행됩니다.

### Node.js 웹소켓 코드(서버)

이 애플리케이션에는 웹 서버[(HTTP 서버](https://www.pubnub.com/guides/http/))와 웹소켓 서버(wss)가 모두 필요합니다. 웹 서버는 브라우저에서 실행되는 클라이언트를 로드하고, 웹소켓 서버는 양방향 채팅 메시지를 처리합니다.

### NodeJS에서 웹소켓 서버를 만드는 방법은 무엇인가요?

Node.js 앱을 만들고 두 개의 [Express.js](https://expressjs.com/) 와 '[ws](https://www.npmjs.com/package/ws)' 패키지를 설치하여 각각 웹 서버와 웹소켓 서버를 제공합니다.

```js
npm init [프롬프트에 따라 기본값을 수락합니다] npm install --save express npm install --save ws
```

웹 서버 부분은 포트 3000에서 클라이언트에게 단일 웹 페이지인 websocket-client.html을 제공합니다:

```js
const express = require('express') const webserver = express() .use((req, res) => res.sendFile('/websocket-client.html', { root: __dirname }) ) .listen(3000, () => console.log(`${3000}`에서 리스닝 중'))
```

웹소켓 서버는 Node.js 웹소켓 라이브러리(ws) 패키지를 사용하여 단 몇 줄로 만들 수 있습니다:

```js
const { WebSocketServer } = require('ws') const sockserver = new WebSocketServer({ port: 443 })
```

### NodeJS 예제를 위한 웹소켓 이벤트 작성하기

웹소켓 서버의 인스턴스를 생성하고 실행할 포트를 지정한 후에는 웹소켓 연결이 설정된 후 발생해야 하는 모든 작업을 정의할 수 있습니다. 이 예제에서는 콘솔에 연결 이벤트를 작성하고 이전에 연결된 클라이언트에 수신한 모든 메시지를 전달합니다. 웹소켓은 HTTP/HTTPS와 동일한 포트(즉, 80 및 443)에서 실행되도록 설계되었습니다.

```js
sockserver.on('connection', ws => { console.log('새 클라이언트가 연결되었습니다!') ws.send('연결이 설정되었습니다') ws.on('close', () => console.log('클라이언트의 연결이 끊어졌습니다!')) ws.on('message', data => { sockserver.clients.forEach(client => { console.log(`메시지 배포 중: ${데이터}`) client.send(`${데이터}`) }) }) ws.onerror = 함수 () { console.log('웹소켓 오류') } }))
```

이것으로 서버 부분이 완료되었습니다. 어떤 소켓에서든 메시지가 수신될 때마다 연결된 모든 클라이언트에 메시지를 프록시하며, 이는 모든 그룹 채팅 앱의 기본이 됩니다.

전체 index.js 코드는 다음과 같습니다:

```js
const express = require('express') const webserver = express() .use((req, res) => res.sendFile('/websocket-client.html', { root: __dirname }) ) .listen(3000, () => console.log(`${3000}`에서 대기 중')) const { WebSocketServer } = require('ws') const sockserver = new WebSocketServer({ port: 443 }) sockserver.on('connection', ws => { console.log('새 클라이언트가 연결되었습니다!') ws.send('연결이 설정되었습니다') ws.on('닫기', () => console.log('클라이언트의 연결이 끊어졌습니다!')) ws.on('메시지', data => { sockserver.clients.forEach(client => { console.log(`메시지 배포 중: ${데이터}`) client.send(`${데이터}`) }) }) ws.onerror = 함수 () { console.log('웹소켓 오류') } }))
```

명령줄에서 다음과 같이 실행할 수 있습니다:

```js
node index.js
```

메시지는 텍스트 또는 JSON으로 인코딩(JSON.stringify)할 수 있습니다. 이 코드는 기본적으로 utf-8 문자셋을 사용합니다.

### 웹소켓 코드 예제(클라이언트/브라우저)

최신 웹 브라우저에서 WebSocket을 사용하기 위해 추가 소프트웨어나 패키지를 설치할 필요가 없습니다. 올바른 형식의 URI를 제공하여 수신 웹소켓을 만듭니다:

```js
const webSocket = new WebSocket('ws://localhost:443/');
```

그리고 서버에서 메시지가 수신될 때를 위한 이벤트 핸들러를 정의합니다:

```js
webSocket.onmessage = (event) => { console.log(event) document.getElementById('messages').innerHTML += '서버로부터의 메시지: ' + event.data + "<br>"; };
```

이제 웹소켓 서버에서 데이터를 수신할 수 있습니다.

클라이언트에서 메시지 이벤트를 보내려면 소켓 객체에서 send()를 호출합니다:

```js
webSocket.send('hello')
```

채팅 앱이 작동하도록 하려면 입력 필드와 '메시지 보내기' 버튼만 추가하면 되므로 프론트엔드 HTML 코드는 다음과 같아야 합니다(간결성을 위해 스타일링 및 CSS 생략):

```js
<html> <head> </head> <body> <form id="input-form"> <label for="message">메시지 입력:</label> <입력 유형="텍스트" id="메시지" 이름="메시지"><br><br> <입력 유형="제출" 값="보내기"> </form> <div id="메시지"></div> <script> const webSocket = new WebSocket('ws://localhost:443/'); webSocket.onmessage = (event) => { console.log(event) document.getElementById('messages').innerHTML += '서버에서 보낸 메시지입니다: ' + event.data + "<br>"; }; webSocket.addEventListener("open", () => { console.log("연결되었습니다"); }); 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>
```

HTML 페이지의 이름을 "웹소켓-클라이언트.html"로 지정하고 브라우저에서 몇 개의 탭을 실행해 다음 주소로 이동합니다. [http://localhost:3000](http://localhost:3000/)모든 탭에 수신된 메시지가 표시되어야 합니다:

![](https://images.ctfassets.net/3prze68gbwl1/6fmgnp5AhVVAvBOt3jxdmQ/330a9faef0f816db63f34f6cf49ab0a6/node.js-websockets.png)

Node.js 서버 없이 동일한 채팅 앱 만들기
--------------------------

서버가 없거나 애플리케이션의 향후 수요를 충족하기 위해 서버 인프라를 확장하는 것에 대해 우려하는 경우, Socket.io 또는 [PubNub](https://www.pubnub.com/).

PubNub는 전 세계적으로 분산되고 확장 가능한 클라우드 플랫폼이므로 백엔드에 서버를 배포하고 유지 관리하는 것에 대해 걱정할 필요가 없습니다. [PubNub SDK](https://www.pubnub.com/docs/sdks) 는 사용자를 식별하고 특정 채널로 메시지를 보낼 수 있으며, 이 메시지는 구독한 사용자만 수신하게 됩니다.

그렇다면 위에서 소개한 간단한 채팅 앱은 PubNub로 어떻게 작성할 수 있을까요? PubNub의 한 가지 장점은 다음과 같습니다. [프로토콜 불가지론적](https://support.pubnub.com/hc/en-us/articles/360051496552-Does-PubNub-use-WebSockets-or-some-other-protocol-)PubNub는 '게시' 및 '구독' 아키텍처(pub/sub)를 사용하여 양방향 메시지를 주고받습니다.

### JavaScript SDK 코드 예시

먼저, 헤더에 해당 CDN에서 제공하는 PubNub JavaScript SDK를 포함합니다:

```js
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.7.2.2.min.js"></script>
```

수신 메시지를 구독하려면 PubNub 인스턴스를 생성하고 채널을 정의한 다음 수신기를 추가합니다:

```js
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 += 'Message from client: ' + payload.message + "<br>"; } }))
```

'ws-channel'에서 메시지가 수신될 때마다 페이지가 업데이트됩니다. 위의 코드는 'demo' 키를 사용하지만 사용자 정의된 [PubNub 키](https://admin.pubnub.com/#/register) 를 무료로 얻을 수 있습니다.

PubNub을 통해 메시지를 보내려면 이 경우 이전에 구독한 채널과 동일한 채널에 게시하세요:

```js
pubnub.publish({ channel: 'ws-channel', message: inputMessage.value })
```

채널 모델은 매우 유연하고 확장성이 뛰어나지만, 이 간단한 예에서는 동일한 채널에서 메시지를 주고받는 것으로 충분합니다. 메시지는 100밀리초 이내에 전 세계 어디든 전달될 것입니다.

PubNub 배포에는 서버 구성 요소가 필요하지 않으므로 HTML과 JS로 작성된 전체 애플리케이션이 단일 파일 내에 포함되어 있습니다:

```js
<html> <head> <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.7.2.2.min.js"></script> </head> <body> <H1>이 코드는 프로토콜에 구애받지 않는 PubNub를 사용합니다</H1> <form id="input-form"> <label for="message"> 메시지를 입력합니다:</label> <입력 유형="텍스트" id="메시지" 이름="메시지"><br><br> <입력 유형="제출" 값="보내기"> </form> <div id="메시지"></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 += 'Message from client: ' + 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>
```

이 코드의 라이브 버전은 다음 링크에서 확인할 수 있습니다.

[https://pubnubdevelopers.github.io/nodejs-websocket-examples/pubnub-client.html](https://pubnubdevelopers.github.io/nodejs-websocket-examples/pubnub-client.html)

![](https://images.ctfassets.net/3prze68gbwl1/75i6TIsSzEevRV2gsusTd1/2e8d9e8e9acba51f103a18a9a6bb27af/pubnub.png)

여기까지입니다! PubNub로 개발하는 방법에 대한 자세한 내용은 다양한 [튜토리얼](https://www.pubnub.com/tutorials/) 와 [데모](https://www.pubnub.com/demos/)또는 [PubNub 인터랙티브 라이브 투어](https://www.pubnub.com/tour/introduction/) 를 통해 이 플랫폼이 애플리케이션에 실시간 상호작용을 제공하는 방법을 알아보세요.

펍넙이 어떤 도움을 줄 수 있을까요?
====================

이 문서는 원래 [PubNub.com에](https://pubnub.com/blog/nodejs-websocket-programming-examples/) 게시되었습니다.

저희 플랫폼은 개발자가 웹 앱, 모바일 앱 및 IoT 기기를 위한 실시간 인터랙티브를 구축, 제공 및 관리할 수 있도록 지원합니다.

저희 플랫폼의 기반은 업계에서 가장 크고 확장성이 뛰어난 실시간 에지 메시징 네트워크입니다. 전 세계 15개 이상의 PoP가 8억 명의 월간 활성 사용자를 지원하고 99.999%의 안정성을 제공하므로 중단, 동시 접속자 수 제한, 트래픽 급증으로 인한 지연 시간 문제를 걱정할 필요가 없습니다.

PubNub 체험하기
-----------

[라이브 투어를](https://www.pubnub.com/tour/introduction/) 통해 5분 이내에 모든 PubNub 기반 앱의 필수 개념을 이해하세요.

설정하기
----

PubNub [계정에](https://admin.pubnub.com/signup/) 가입하여 PubNub 키에 무료로 즉시 액세스하세요.

시작하기
----

사용 사례나 [SDK에](https://www.pubnub.com/docs) 관계없이 [PubNub 문서를](https://www.pubnub.com/docs) 통해 바로 시작하고 실행할 수 있습니다.