You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Adonis 4.1.0中使用Socket.io?求兼容解决方案

在Adonis 4.1.0中集成Socket.io的可行方案

刚好我之前在Adonis 4.x版本上折腾过Socket.io的集成,给你整理几个亲测靠谱的方案,适配你的场景:

方案一:直接在Adonis HTTP服务器上挂载Socket.io

这是最轻量化的方案,不用额外启动独立服务,直接复用Adonis的现有HTTP服务器:

  1. 安装依赖:
npm install socket.io
  1. 修改start/server.js,获取原生HTTP服务器实例并挂载Socket.io:
const socketIo = require('socket.io')
const { Ignitor } = require('@adonisjs/ignitor')

new Ignitor(require('@adonisjs/fold'))
  .appRoot(__dirname)
  .fireHttpServer()
  .then((httpServer) => {
    // 初始化Socket.io,可配置跨域规则
    const io = socketIo(httpServer, {
      cors: {
        origin: "http://your-frontend-domain", // 替换成你的前端域名
        methods: ["GET", "POST"]
      }
    })

    // 处理连接事件
    io.on('connection', (socket) => {
      console.log('用户已连接:', socket.id)

      // 监听客户端发送的消息
      socket.on('send-message', (data) => {
        console.log('收到消息:', data)
        // 广播给所有在线客户端
        io.emit('receive-message', data)
      })

      socket.on('disconnect', () => {
        console.log('用户已断开:', socket.id)
      })
    })
  })

优点:零额外服务开销,配置简单,适合中小型单实例应用。

方案二:独立Socket.io服务+Redis适配器(分布式场景)

如果你的应用是多实例部署,直接挂载的方案无法跨实例广播消息,这时候可以用Redis做状态共享:

  1. 安装依赖:
npm install socket.io socket.io-redis redis
  1. 创建独立的Socket服务文件start/socketServer.js:
const http = require('http')
const socketIo = require('socket.io')
const redisAdapter = require('socket.io-redis')

const server = http.createServer()
const io = socketIo(server, {
  cors: {
    origin: "http://your-adonis-domain",
    methods: ["GET", "POST"]
  }
})

// 配置Redis适配器,实现跨实例消息同步
io.adapter(redisAdapter({ host: 'localhost', port: 6379 }))

io.on('connection', (socket) => {
  socket.emit('welcome', '已连接到Socket.io服务')
  
  // 这里编写你的业务逻辑,比如房间管理、消息推送等
})

// 启动Socket服务,监听独立端口
server.listen(3001, () => {
  console.log('Socket.io服务运行在端口3001')
})
  1. 在package.json中添加启动脚本:
"scripts": {
  "start": "node server.js",
  "start:socket": "node start/socketServer.js"
}

启动时同时运行Adonis和Socket服务即可。客户端连接时需指定Socket服务端口:const socket = io('http://localhost:3001')。

方案三:使用社区适配的Adonis Socket.io包

社区有维护适配Adonis 4.x的Socket.io集成包,写法更贴合Adonis生态:

  1. 安装适配包:
npm install adonis-socket.io
  1. 在start/app.js的providers数组中注册Provider:
providers: [
  // ...其他provider
  'adonis-socket.io/providers/SocketIoProvider'
]
  1. 创建Socket控制器,比如app/Controllers/Ws/ChatController.js:
class ChatController {
  async onConnection(socket) {
    // 可选:在这里做鉴权,比如通过token获取用户信息
    const token = socket.handshake.query.token
    try {
      const user = await use('Auth').verify(token)
      socket.user = user
      console.log('用户鉴权通过:', user.username)
    } catch (err) {
      socket.disconnect(true) // 鉴权失败直接断开连接
    }

    // 监听客户端事件
    socket.on('send-message', (data) => {
      // 广播给当前房间的其他用户
      socket.broadcast.emit('new-message', { ...data, user: socket.user.username })
    })
  }
}

module.exports = ChatController
  1. 在start/routes.js中配置Socket路由:
const Ws = use('Ws')

Ws.route('/chat', 'ChatController.onConnection', {
  auth: false // 根据需求设置是否强制鉴权
})

优点:完全遵循Adonis的开发范式,适合熟悉Adonis生态的开发者。

额外注意事项

  • 跨域配置:务必根据你的前端域名配置Socket.io的cors选项,避免跨域错误;
  • 版本兼容:Adonis 4.1.0适配的Node.js版本建议在8.x-12.x,Socket.io选择2.x或3.x版本更稳妥,避免最新版本的兼容性问题;
  • 鉴权逻辑:无论哪种方案,都可以在connection事件中通过客户端传递的token,调用Adonis的Auth服务完成用户鉴权,非法连接直接断开。

内容的提问来源于stack exchange,提问作者Tijan Manandhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:09:46