如何與 Nuxt 搭配使用
本指南說明如何在 Nuxt 應用程式中使用 Socket.IO。
伺服器
在底層,Nuxt 使用 Nitro 來處理 HTTP 要求。
將 Socket.IO 伺服器附加至 Nitro 伺服器有兩個步驟
啟用 WebSockets
Nitro 中的 WebSockets 支援目前為 實驗性質,因此需要手動啟用
nuxt.config.js
// https://nuxt.dev.org.tw/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>
在上述範例中,transport
變數是建立 Socket.IO 連線所使用的低階傳輸,可以是
- HTTP 長輪詢(
"polling"
) - WebSocket(
"websocket"
) - WebTransport(
"webtransport"
)
如果一切順利,您應該會看到
Status: connected
Transport: websocket
然後您可以透過以下方式在 Socket.IO 伺服器和客戶端之間交換訊息
socket.emit()
用於傳送訊息
socket.emit("hello", "world");
socket.on()
用於接收訊息
socket.on("hello", (value) => {
// ...
});
各位,就這樣了,感謝您的閱讀!