メインコンテンツへスキップ

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でデバッグできます

DevTools with NW.js

欠点

  • 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接続は、アプリケーションの異なるウィンドウ間で共有されます

  • クライアントは、agentca、または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

以上です。お読みいただきありがとうございます!

例のリストに戻る