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

Nuxtでの使い方

このガイドでは、Nuxtアプリケーション内でSocket.IOを使用する方法を説明します。

サーバー

内部的には、NuxtはHTTPリクエストを処理するためにNitroを使用しています。

Socket.IOサーバーをNitroサーバーにアタッチするには、2つのステップがあります。

WebSocketsを有効にする

NitroでのWebSocketsのサポートは現在実験的であるため、手動で有効にする必要があります。

nuxt.config.js
// https://nuxt.dokyumento.jp/docs/api/configuration/nuxt-config

export default defineNuxtConfig({
devtools: {
enabled: true
},
+ nitro: {
+ experimental: {
+ websocket: true
+ },
+ }
})

参考: https://nitro.unjs.io/guide/websocket

Socket.IOサーバーをフックする

Socket.IOサーバーは、Nitroプラグインで作成されます。

server/plugins/socket.io.ts
import type { NitroApp } from "nitropack";
import { Server as Engine } from "engine.io";
import { Server } from "socket.io";
import { defineEventHandler } from "h3";

export default defineNitroPlugin((nitroApp: NitroApp) => {
const engine = new Engine();
const io = new Server();

io.bind(engine);

io.on("connection", (socket) => {
// ...
});

nitroApp.router.use("/socket.io/", defineEventHandler({
handler(event) {
engine.handleRequest(event.node.req, event.node.res);
event._handled = true;
},
websocket: {
open(peer) {
const nodeContext = peer.ctx.node;
const req = nodeContext.req;

// @ts-expect-error private method
engine.prepare(req);

const rawSocket = nodeContext.req.socket;
const websocket = nodeContext.ws;

// @ts-expect-error private method
engine.onWebSocket(req, rawSocket, websocket);
}
}
}));
});

はい、完了です!

クライアント

クライアント側では、Vue 3ガイドからのすべてのヒントが有効です。

唯一の違いは、Socket.IOクライアントをサーバーサイドレンダリング(SSR)から除外する必要があることです。

構成

├── components
│ ├── Connection.client.vue
│ └── socket.ts
...
components/socket.ts
import { io } from "socket.io-client";

export const socket = io();
components/Connection.client.vue
<script setup>
import { socket } from "./socket";

const isConnected = ref(false);
const transport = ref("N/A");

if (socket.connected) {
onConnect();
}

function onConnect() {
isConnected.value = true;
transport.value = socket.io.engine.transport.name;

socket.io.engine.on("upgrade", (rawTransport) => {
transport.value = rawTransport.name;
});
}

function onDisconnect() {
isConnected.value = false;
transport.value = "N/A";
}

socket.on("connect", onConnect);
socket.on("disconnect", onDisconnect);

onBeforeUnmount(() => {
socket.off("connect", onConnect);
socket.off("disconnect", onDisconnect);
});

</script>

<template>
<div>
<p>Status: {{ isConnected ? "connected" : "disconnected" }}</p>
<p>Transport: {{ transport }}</p>
</div>
</template>

注記

Connection.client.vue.client サフィックスは、コンポーネントがクライアント側でのみレンダリングされる(SSRなし)ことを示します。

参考: https://nuxt.dokyumento.jp/docs/guide/directory-structure/components#client-components

上記の例では、transport変数はSocket.IO接続を確立するために使用される低レベルトランスポートであり、次のいずれかになります。

すべてがうまくいけば、次のように表示されます。

Status: connected
Transport: websocket

その後、Socket.IOサーバーとクライアント間でメッセージを交換できます。

  • socket.emit() を使用してメッセージを送信
socket.emit("hello", "world");
  • socket.on() を使用してメッセージを受信
socket.on("hello", (value) => {
// ...
});

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

例のリストに戻る