【问题标题】:Express JS Controllers with Socket IO Issue带有套接字 IO 问题的 Express JS 控制器
【发布时间】:2021-10-10 18:01:26
【问题描述】:

我正在尝试设置 Socket IO 以在我的 Express 应用程序中的不同控制器中正常工作。

这是我在 server.js 中初始化 Socket IO 的方式

//Run When Connection Received
io.on('connection', (socket) => {
    socket.emit('message', 'This is a test message from the server.')
})

这是我的一个控制器的样子:

const getComments = asyncHandler(async (request, response) => {
    const { liveID, token: accessToken } = request.body
    var source = new EventSource(
        `https://streaming-graph.facebook.com/${liveID}/live_comments?access_token=${accessToken}&comment_rate=one_per_two_seconds&fields=from{name,id},message`
    )
    source.onmessage = function (event) {
        // Do something with event.message for example
        console.log(event)

        // THIS IS WHERE I NEED TO EMIT A SOCKET IO EVENT.
        // THE DATA IN 'event' NEEDS TO BE SENT BACK TO THE CLIENT VIA THE SOCKET

    }
    source.onerror = function (error) {
        console.log('Error!')
        console.log(error)
    }

    source.onopen = function (event) {
        console.log(event)
    }
})

我一直在尝试遵循 Socket IO 中的这个文档,但是对于我的生活,我似乎无法弄清楚如何使用上面的示例来完成这项工作,我尝试了很多不同的东西,但我似乎错过了东西。

https://socket.io/docs/v4/server-application-structure/

这里的任何帮助将不胜感激!

【问题讨论】:

  • 您能在连接到 socket.io 服务器的地方添加客户端代码吗?如果添加了有用的答案,将更容易提供有用的答案。否则答案将再次看起来更像教程。
  • 客户端代码对这个问题有点不敬。控制器正在从 Facebook API 获取 cmets 流。当它收到时,它应该向客户端发出一条消息。客户端在捕获套接字 IO 消息时没有问题。我遇到的问题是将我的控制器配置为能够发出套接字 IO 消息,因为控制器是与 server.js 文件分开的文件。不幸的是,所有“教程”和示例都显示了从一个 server.js 文件初始化和发送/接收消息。
  • 好的,谢谢,现在说得通了。
  • 您是否尝试广播或发送给特定用户?还是特定的用户组?如果是一组用户,您是否需要进行身份验证以验证他们是否可以接收消息?你说“发回给客户”,但就像……客户一开始就要求这个动作吗?
  • 只有一个客户端连接到这个应用程序。这只是其中的一部分,但目前我只是想将来自 facebook API 的实时视频 cmets 流发送回连接的客户端。我知道如何做那部分。我无法弄清楚的部分是如何能够在我的控制器文件中调用 Socket IO,而不是在我正在初始化 Socket IO 服务器的 server.js 文件中。

标签: node.js express socket.io


【解决方案1】:

在控制器中访问 io 的方法是将其附加到请求对象,如下所示:

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

当一个套接字连接时,向套接字添加一个用户 ID

io.on('connection', (socket) => {
    // assuming you send user id in a header for example
    socket.userId = socket.client.request.headers.userId;
})

然后在控制器中:

const getComments = asyncHandler(async (request, response) => {
    var io = request.io;

    // https://socket.io/docs/v4/server-api/#serverfetchsockets
    // return all Socket instances
    const sockets = await io.fetchSockets();

    // assuming there's a loggedin user object attached to request
    const socket = sockets.find(s => s.userId === request.user.id);

    const { liveID, token: accessToken } = request.body
    var source = new EventSource(
        `https://streaming-graph.facebook.com/${liveID}/live_comments?access_token=${accessToken}&comment_rate=one_per_two_seconds&fields=from{name,id},message`
    )
    source.onmessage = function (event) {
        // Do something with event.message for example
        console.log(event)

        socket.emit(....);

    }
    source.onerror = function (error) {
        console.log('Error!')
        console.log(error)
    }

    source.onopen = function (event) {
        console.log(event)
    }

})

【讨论】:

    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多