NginxサーバからNodeサーバへの連携とWebSocket通信の設定

今回の記事ではNginxをフロントエンドサーバ、Nodeをバックエンドサーバとしてそれぞれのサーバを構築していきます。そして、それぞれブラウザからHTTP通信を確認したのち、Nginxからプロ式設定を通してNodeサーバにアクセスする方法を確認していきます。その後、WebSocket(WS)を使って連携も確認していき、最後にはWebSocket Secure(WSS)での通信を試していきます。

WebSocketプロトコルの大きな特徴として双方向のリアルタイム通信が挙げられます。常時接続状態が保たれるのでチャットアプリやメッセージングアプリにも使用されます。またリアルタイムな通知やリアルタイムのUIの更新、そしてマルチプレーヤーゲームなどのデータのやり取りに向いています。オンライン上で共同編集するツールなどにも使用されます。

目次

Nginxのインストール

最初はHTTPでのWebサーバの構築まで行って下さい。HTTPS化は後で設定します。

あわせて読みたい
Nginx(エンジンX)サーバのインストールと設定、そしてHTTPS化 Nginx(エンジンX)はApache(アパッチ)と並ぶWebサーバで、インターネットで情報を公開する際にはこのWebサーバを使って公開することになります。今回の記事ではNginxの...

Nodeのインストール

Nodeサーバの設定

以下の記事を参考にNodeサーバ(server_http.js)を作成します。バックエンドサーバなのでHTTPS化は不要です。

あわせて読みたい
Node.jsのインストールとWebサーバのHTTPS化 Node.jsとはJavascript言語をブラウザ上ではなくサーバ上で動かせるようにしたものです。PHP同様Webサーバがなくてもその言語単体でサーバ上で動作するので、バッチ処理...

サーバスクリプト

/home/ec2-user/server/server_http.js

"use strict";

const express = require("express");
const PORT = 80
const app = express();
const path = require('path');

app.use(express.static(path.join(__dirname, 'public')));

app.get("/", (req, res) => {
    res.send("Hello from server on HTTP");
});

app.listen(PORT, () => {
    console.log(`Node server is running on port:${PORT}`);
}).on('error', (err) => {
    console.error('Error starting server:', err.message);
});

process.on("SIGINT", function () {
    console.log("\nGracefully shutting down from SIGINT (Ctrl-C)");
    process.exit(0);
});

NginxサーバからNodeサーバへの連携

まずはNginxサーバにプロキシの設定をしてNodeサーバへの連携がうまくいくか試します。

nginx.confの設定

以下をserverブロックに追記。

    # proxy to node
    location / {
        proxy_pass http://ドメイン名又はIP:80;
        # 以下の設定は任意
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

編集が終わったらNginxサーバを再起動します。

sudo systemctl restart nginx

proxy_passに変数は使えないのでハードコードする必要があります。

通信確認

Nodeサーバ側に作成したファイルと同じ内容がNginxサーバにアクセスした時に表示されれば成功です。

http://Nodeサーバのドメイン又はIP/express.html
http://Nginxサーバののドメイン又はIP/express.html

WebSocket(WS)を使った連携

Node.js側の変更

wsパッケージのインストール

 npm install -l --save ws

サーバスクリプトの変更

server_http.jsをserver_http_ws.jsにリネームコピーして以下の様に編集します。

server_http_ws.js

"use strict";

const express = require("express");
const PORT = 80;
const app = express();
const path = require('path');
const http = require('http');

app.use(express.static(path.join(__dirname, 'public')));

app.get("/", (req, res) => {
    res.send("Hello from server on HTTP");
});

// WebSocketの設定
const server = http.createServer(app);
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server });

wss.on('connection', ws => {
  console.log('Client connected');

  ws.on('message', message => {
    console.log(`Received from client: ${message}`);
    ws.send(`Server received: ${message}`);
  });

  ws.on('close', () => {
    console.log('Client disconnected');
  });
});

//app.listen(PORT, () => {
server.listen(PORT, () => {
    console.log(`Node server is running on port:${PORT}`);
}).on('error', (err) => {
    console.error('Error starting server:', err.message);
});

process.on("SIGINT", function () {
    console.log("\nGracefully shutting down from SIGINT (Ctrl-C)");
    process.exit(0);
});

Nginx側の変更

nginx.confのserverブロック内に以下を追記。

location /ws/ {
    proxy_pass http://mydomain.example.com:80;

    # WebSocket用のヘッダ設定
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;

    # タイムアウトの設定
    proxy_read_timeout 3600s;
}

編集が終わったらNginxサーバを再起動します。

sudo systemctl restart nginx

クライアント(ブラウザ)側のHTMLコード

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket</title>
</head>
<body>
  <script>
    const ws = new WebSocket('ws://Nginxサーバのドメイン名又はIP/ws/');

    ws.onopen = () => {
      console.log('Server Connected');
      ws.send('Hello Server!');
    };

    ws.onmessage = (event) => {
      console.log('Received from server:', event.data);
    };

    ws.onclose = () => {
      console.log('Connection closed');
    };
  </script>
</body>
</html>

通信確認

Nodeサーバ側のコンソールに以下が出力されれば成功です。

Client connected
Received from client: Hello Server!

ブラウザの開発ツールのコンソールに以下が表示されれば成功です。

Server Connected ws.html:11:25
Received from server: Server received: Hello Server!

WebSocket Secure(WSS)を使った連携

Nodeサーバの設定

Nodeサーバはバックエンドサーバなのでブラウザと直接通信しないのでNodeサーバのHTTPS化は不要です。

NginxのHTTPS化

Let’s Encryptを使ってHTTPS化する

最初にHTTPS化しなかったNginxサーバですが、以下の記事に従ってNginxサーバをHTTPS化しましょう。

あわせて読みたい
Nginx(エンジンX)サーバのインストールと設定、そしてHTTPS化 Nginx(エンジンX)はApache(アパッチ)と並ぶWebサーバで、インターネットで情報を公開する際にはこのWebサーバを使って公開することになります。今回の記事ではNginxの...

Nginxサーバの再起動を忘れないようにしましょう。

sudo systemctl restart nginx

クライアント(ブラウザ)側のHTMLコード

接続先のプロトコルが ws から wss に変わります。

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket</title>
</head>
<body>
  <script>
    // const ws = new WebSocket('ws://Nginxサーバのドメイン名又はIP/ws/');
    const ws = new WebSocket('wss://Nginxサーバのドメイン名又はIP/ws/');

    ws.onopen = () => {
      console.log('Server Connected');
      ws.send('Hello Server!');
    };

    ws.onmessage = (event) => {
      console.log('Received from server:', event.data);
    };

    ws.onclose = () => {
      console.log('Connection closed');
    };
  </script>
</body>
</html>

通信確認

HTTPSを使わなかった時同様の出力がNginxサーバのコンソールとブラウザのコンソールそれぞれに出ていれば成功です。

まとめ

今回の記事ではNginxをフロントエンドサーバ、Nodeサーバをバックエンドサーバとしてその連携方法を学習してきました。nginx.confのproxy_passには変数が使えず、URLはハードコードしましたね。WebSocketの処理にはNode側でwsモジュールをインストールしました。WSSを使用する場合はプロトコル部分をwssに変更しましたね。ブラウザと直接通信をするのはNginxサーバなのでNginxサーバのHTTPS化は必要でしたが、バックエンドのNodeサーバはHTTPS化は必要ありませんでした。WebSocket通信は双方向リアルタイムのプロトコルなのでチャットアプリやマルチユーザゲーム、共同編集などに広く使用されています。チャットアプリを自作してみるのもよいでしょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次