如何将 socket.io 集成到我的 express 项目的 mvc 架构中

How to integrate socket.io to the mvc architecture of my express project

提问人:Reina 提问时间:11/8/2023 更新时间:11/9/2023 访问量:32

问:

我正在用 socket.io 和 express 制作后端,但是我无法使用 nextjs 将套接字与我的前端连接,当进入页面时,会执行通过端点与 Web 套接字连接的获取,控制器工作是因为我收到响应,但套接字没有响应,如果有人可以指导我,我将不胜感激, 我是新手。

索引.js

app.use('/items', itemsRouter)

app.listen(port, () => {
  console.log('Server is runnig on port http://localhost:3001')
})

路由器.js

export const itemsRouter = Router()

itemsRouter.get('/', ItemController.getAll)
itemsRouter.post('/', ItemController.create)
itemsRouter.post('/api/data', ItemController.getData)

控制器.js

export class ItemController {
  static getData = async (req, res) => {
    io.on('connection', async (socket) => {
      console.log('an user has connected')
    })
  }
}
节点.js Express socket.io

评论

0赞 Matt 11/8/2023
您想用 Web 套接字实现什么?套接字侦听器通常不是通过路由/控制器设置的,Web 套接字通常是启动控制器的另一种方式,而不是使用 http 路由。
0赞 Reina 11/8/2023
@Matt 您好,感谢您的回答,我正在创建一个 API 以及一个带有 Arduino 板的通信桥,我通过 Web 套接字执行此操作,但是我不确定在哪里初始化它,我没有在互联网上找到很多这样的例子,控制器构造函数对我来说似乎不是一个好的选择,因为在路由中。js 文件我正在创建多个实例。
0赞 Matt 11/9/2023
以下是 socket.io 提供的快速示例。请注意,如何与ioapp

答:

0赞 Matt 11/9/2023 #1

下面是提供的服务器,更新了 socket.io 服务器示例和一个套接字事件处理程序。

const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");

const app = express()

app.use('/items', itemsRouter)

const httpServer = createServer(app);
const io = new Server(httpServer, { /* options */ });

io.on('connection', async (socket) => {
  console.log('an user has connected', socket.id)
  socket.on('apiData', ItemController.getDataSocket)
})

express/http 路由器保持不变。

我添加了彼此相邻的等效 socket.io 和 express 请求/响应控制器,以演示其签名的差异。

export class ItemController {
  static getDataExpress = async (req, res) => {
    const { id } = req.body
    const data = await someFetch(id)
    res.json({ data })
  }
  static getDataSocket = async(payload, callback) => {
    const { id } = payload
    const data = await someFetch(id)
    callback({ data })
  }
}

通常,套接字对于它们的流式处理和广播更有用,而不是 express 已经能够做到的请求/响应模式。通常,您需要从路由触发套接字,因此您通常希望将实例附加到请求。io

将实例添加到索引.jsioapp

app.use((req,res,next) => {
  req.app.set('io', io)
})

例如,向已加入聊天室的感兴趣的客户广播一个新项目。items

export class ItemController {
  static newItem = async (req, res) => {
    const { item } = req.body
    const data = await creatItem(item)
    req.app.get('io).to("items").emit('newItem', item)
    res.json({ item })
  }
}