NW.jsで使う方法
このガイドでは、NW.js(以前はnode-webkitとして知られていました)アプリケーション内でSocket.IOを使用する方法について説明します。
使い方
デフォルトでは、NW.jsは2つの異なるJavaScriptコンテキストを作成します
- ブラウザコンテキスト。これはWeb API(ウィンドウ/フレームごとに1つのコンテキスト)へのアクセス権を持っています
- Nodeコンテキスト。これはNode.js API(すべてのウィンドウ/フレーム間で共有)へのアクセス権を持っています
参考: https://nwjs.readthedocs.io/en/latest/For%20Users/Advanced/JavaScript%20Contexts%20in%20NW.js/
Socket.IOクライアントは、ユースケースに応じて、両方のコンテキストで作成できます。
ブラウザコンテキスト
index.html
<!doctype html>
<html lang="en">
  <body>
    <p>Status: <span id="status"></span></p>
    <p>Transport: <span id="transport"></span></p>
    <!-- from the socket.io-client package -->
    <script src="./node_modules/socket.io-client/dist/socket.io.min.js"></script>
    <!-- or from a CDN -->
    <!--<script src="https://cdn.socket.io/4.7.5/socket.io.js"></script>-->
    <script>
      const socket = io("https://:3000");
      const statusSpan = document.getElementById("status");
      const transportSpan = document.getElementById("transport");
      statusSpan.innerText = "Disconnected";
      transportSpan.innerText = "N/A";
      socket.on("connect", () => {
        statusSpan.innerText = "Connected";
        transportSpan.innerText = socket.io.engine.transport.name;
        socket.io.engine.on("upgrade", (transport) => {
          transportSpan.innerText = transport.name;
        });
        console.log(`connect ${socket.id}`);
      });
      socket.on("connect_error", (err) => {
        console.log(`connect_error due to ${err.message}`);
      });
      socket.on("disconnect", (reason) => {
        statusSpan.innerText = "Disconnected";
        transportSpan.innerText = "N/A";
        console.log(`disconnect due to ${reason}`);
      });
      socket.emit("hello", "world");
    </script>
  </body>
</html>
この場合、Socket.IOクライアントはブラウザによって提供されるWebSocketオブジェクトを使用します。
利点
- Socket.IO接続はDevToolsでデバッグできます

欠点
- WebSocketのみを使用する場合、extraHeadersオプションは無視されます
const socket = io("https://:3000", {
  transports: ["websocket"],
  extraHeaders: {
    "my-custom-header": "1234" // ignored
  }
});
Nodeコンテキスト
index.html
<!doctype html>
<html lang="en">
  <body>
    <p>Status: <span id="status"></span></p>
    <p>Transport: <span id="transport"></span></p>
    <script>
      const statusSpan = document.getElementById("status");
      const transportSpan = document.getElementById("transport");
      const { registerListeners, emit } = require("./socket");
      registerListeners({ statusSpan, transportSpan });
      emit("hello", "world");
    </script>
  </body>
</html>
socket.js
const { io } = require("socket.io-client");
const socket = io("https://:3000");
exports.registerListeners = function ({ statusSpan, transportSpan }) {
  statusSpan.innerText = "Disconnected";
  transportSpan.innerText = "N/A";
  function onConnect() {
    statusSpan.innerText = "Connected";
    transportSpan.innerText = socket.io.engine.transport.name;
    socket.io.engine.on("upgrade", (transport) => {
      transportSpan.innerText = transport.name;
    });
    console.log(`connect ${socket.id}`);
  }
  if (socket.connected) {
    onConnect();
  }
  socket.on("connect", onConnect);
  socket.on("connect_error", (err) => {
    console.log(`connect_error due to ${err.message}`);
  });
  socket.on("disconnect", (reason) => {
    statusSpan.innerText = "Disconnected";
    transportSpan.innerText = "N/A";
    console.log(`disconnect due to ${reason}`);
  });
}
exports.emit = function (...args) {
  socket.emit(...args);
}
この場合、Socket.IOクライアントは、wsパッケージによって提供されるWebSocketオブジェクトを使用します。
利点
- Socket.IO接続は、アプリケーションの異なるウィンドウ間で共有されます 
- クライアントは、 - agent、- ca、または- certなど、Node.js固有の追加オプションをサポートしています
const socket = io("https://:3000", {
  ca: fs.readFileSync("cert.pem")
});
- WebSocketのみを使用する場合、extraHeadersオプションは正しく送信されます
const socket = io("https://:3000", {
  transports: ["websocket"],
  extraHeaders: {
    "my-custom-header": "1234"
  }
});
欠点
- Socket.IO接続は、DevToolsでデバッグできません(「バックグラウンドページを検査」を選択した場合でも)
サンプルプロジェクト
https://github.com/socketio/socket.io/tree/main/examples/nwjs-example
以上です。お読みいただきありがとうございます!