Nuxt 3中如何启动WebSocket服务器?Nuxt2原有写法不兼容
Nuxt 3 集成 WebSocket 正确实现方案
你之前的代码逻辑是Nuxt2时代的写法,在Nuxt3里完全不适用,核心问题是Nuxt3底层替换成了Nitro+H3架构,启动时会自动创建HTTP服务,不需要你手动调用http.createServer新建实例,也不存在render:before钩子和nuxt.renderer.app属性,自己新建的服务和Nuxt实际运行的服务不是同一个实例,端口、路由都不互通,自然会连接失败。
最简实现(基于socket.io,无需自定义模块)
不需要写额外的Nuxt模块,用Nitro自带的服务端插件就能直接挂载WebSocket服务,步骤如下:
- 先安装依赖
npm i socket.io socket.io-client
- 新建服务端插件,路径为
server/plugins/socket.js,这里直接复用Nitro已经启动的HTTP服务实例,不用自己监听端口:
import { Server } from 'socket.io' export default defineNitroPlugin((nitroApp) => { const io = new Server(nitroApp.h3App.httpServer, { cors: { origin: process.env.NODE_ENV === 'development' ? "*" : '你的生产域名', credentials: true } }) io.on('connection', (socket) => { console.log('客户端连接成功') // 这里写你的业务事件逻辑 socket.on('chat:send', (msg) => { io.emit('chat:receive', msg) }) socket.on('disconnect', () => { console.log('客户端断开连接') }) }) // 把io实例挂到nitroApp上,其他服务端接口/路由里可以直接取用 nitroApp.io = io })
- 客户端插件和你之前写的基本一致,路径
plugins/socket.client.js,不用硬编码localhost,自动适配当前域名:
import { io } from 'socket.io-client' export default defineNuxtPlugin(() => { const socket = io(useRequestURL().origin, { reconnection: true, reconnectionDelay: 1000 }) return { provide: { socket } } })
- 页面中使用时注意,WebSocket相关逻辑要放在客户端生命周期里执行,避免SSR阶段报错:
<template> <div> <p>WebSocket连接状态:{{ isConnected ? '已连接' : '连接中...' }}</p> </div> </template> <script setup> const { $socket } = useNuxtApp() const isConnected = ref(false) onMounted(() => { $socket.on('connect', () => isConnected.value = true) $socket.on('disconnect', () => isConnected.value = false) }) </script>
常见坑点
- 不要手动调用
http.createServer新建服务:Nuxt3启动时会默认占用你配置的端口(默认3000),自己新建的服务要么端口冲突,要么跑在其他端口,客户端连3000端口自然找不到WebSocket服务 - 服务端逻辑必须放在
server目录下:根目录的plugins、modules默认是同构/客户端侧的,拿不到底层HTTP服务实例 - 如果不想用socket.io,换原生
ws库逻辑完全一致,只需要把nitroApp.h3App.httpServer传给ws的Server构造函数即可 - 生产环境用Nginx等反向代理时,记得配置
Upgrade和Connection头支持WebSocket协议,不然连接会被代理拦截
内容的提问来源于stack exchange,提问作者ahbork
相关产品推荐
相关产品推荐

