首页 > 解决方案 > 使 socket.io 在 Node.js 的 API 端点内工作

问题描述

我有以下逻辑(所有服务器都在 Node.js 中):

1- 客户端对服务器 A 的“api/request”端点进行 API 调用。

2- 服务器 A“请求”端点接收请求,并使用 socket.io 发出事件将原始请求传递给服务器 B。

3- 服务器 B socket.io on event 接收请求,处理它,并在新的 socket.io 发射事件中发回响应。

4- Server A socket.io on event 接收响应,并且应该将响应返回给最初发出请求的客户端。

问题是,由于在服务器 A 中我通过 socket.io 发出事件传递请求,我失去了等待服务器 B 的答案以返回给客户端任何内容的选项。我希望客户端接收来自服务器 B 的响应,作为其对服务器 A 的原始调用的响应。

关于如何实现这一目标的任何想法?

标签: javascriptnode.jssocketssocket.io

解决方案


我找到了一个方法。由于您的代码中只能包含一个io.on('connection', function (socket) {}),因此我必须找到解决方法。

问题是,如果您放置io.on('connection', function (socket) {})在您的router.post('/', async (req, res) => {})中,它只会在您调用端点时触发。就我而言,我有一些我想随时调用的套接字事件,而不仅仅是在调用端点时。所以我不得不把io.on('connection', function (socket) {})我的router.post('/', async (req, res) => {}). 因此我无法var io = req.app.get('socketio');在路由器内部使用。这是我在服务器 A 代码中所做的:

index.js:

const cors = require('cors');
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const taskRequest = require('./routes/taskRequest')(io);

app.use(cors())
app.use(express.json());
app.use('/api/taskRequest', taskRequest);

server.listen(4002);

路线/taskRequest.js

const express = require('express');
const router = express.Router();

module.exports = function(io) {

    //we define the variables
    var sendResponse = function () {};

    io.sockets.on("connection",function(socket){
        // Everytime a client logs in, display a connected message
        console.log("Server-Client Connected!");

        socket.on('connected', function(data) {
            //listen to event at anytime (not only when endpoint is called)
            //execute some code here
        });

        socket.on('taskResponse', data => {
            //calling a function which is inside the router so we can send a res back
            sendResponse(data);
        })     
    });

    router.post('/', async (req, res) => {

        //pickedUser is one of the connected client
        var pickedUser = "JZLpeA4pBECwbc5IAAAA";
        io.to(pickedUser).emit('taskRequest', req.body);

        sendResponse = function (data) {
            return res.status(200).json({"text": "Success", "response": data.data});
        }

    });

    return router;

};

像这样,服务器 A 仅在收到服务器 B 的响应后才将响应发送回客户端。

解决了!


推荐阅读