Socket.io多个响应,而不是一个

问题描述 投票:1回答:1

我正面临socket.io和node js的问题。

语境

我有两台服务器,其中一台正在处理繁重的工作,另一台正在响应客户端。主要情况如下:

  1. 客户请求数据
  2. “中级服务器”将查看我是否在数据库中有此数据。如果还没有,则向第二台服务器发出请求
  3. 第二台服务器进行研究。
  4. 完成后,第二台服务器将数据推送到“中间服务器”
  5. 中间服务器最终将数据推送到客户端(并将其持久保存以用于将来的客户端请求)

这是示例代码

客户

<script type="text/javascript"/>
    var socket = io('https://localhost:9091', {'forceNew': true);
    // send a request to the mid server
    socket.emit('request', data);

    socket.on('response', async (response) => {
        // when the mid server responds, the response is printed
        $('#container').append(response);
    });
</script>

中间服务器

const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

// in order to use this server as a Socket.io client
const secondServer = require('socket.io-client').connect('http://localhost:9092');

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
    res.render('index', {})
});

io.on('connection', async (socket) => {

    console.log('User connected');

    // On client request
    socket.on('request', async (data) => {

        console.log('Requesting from ' + socket.id);

        // The same request is transmited to the second server
        secondServer.emit('request', data);
    });

    // Once the second server has finished his job
    secondServer.on('response', async (data) => {

        console.log('Responding for ' + socket.id);

        // I send the data back to the client
        socket.emit('response', data);
    });

    socket.on('disconnect', () => {
        socket.disconnect();
    });
});

// port is 9091
http.listen(port, () => {
    console.log('Server listening on port ' + port);
});

第二服务器

const io = require("socket.io").listen(9092);

io.on("connection", function (socket) {

    socket.on('request', async () => {
        // await in order to wait the heavyJob to be done before sending the response
        var data = await heavyJob()

        // Send back the data to the mid server
        socket.emit('response', data);

    });
});

问题

我面临的问题是,如果刷新客户端页面,则中间服务器将发送两次数据,一次发送到旧套接字,一次发送到新套接字:

console output

我也尝试使用中端服务器端的socket.emit('response', data)和客户端端的socket.on('response', (data) => {})来响应客户端,而不是使用callback功能。它没有任何改变。

我误会了什么吗?

感谢您的帮助

编辑

不仅发生在客户端刷新页面时。当两个不同的客户端同时发送请求时,就会发生这种情况。服务器响应四次,每个客户端响应两次。

console output

node.js express socket.io ejs
1个回答
0
投票

您是正确的Nico,我没有意识到无法实现回调。是我的错

根据您编辑的代码,您可以从“ io.on('connection'”的回调中拉出“ secondServer.on('response'..”] >>。

您可以在下面尝试,希望对您有所帮助。

中间服务器

io.on('connection', async (socket) => {

    console.log('User connected');

    // On client request
    socket.on('request', async (data) => {

        console.log('Requesting from ' + socket.id);

        // The same request is transmited to the second server
        // give data and socket.id to secondServer.
        secondServer.emit('request', {data:data, id:socket.id});
    });

    // Once the second server has finished his job
    socket.on('disconnect', () => {
        socket.disconnect();
    });
});

secondServer.on('response', async (reply) => {
    const {id, data} = reply;
    console.log('Responding for ' + id);
    // I send the data back to the client
    io.to(id).emit('response', data);
});

第二服务器

const io = require("socket.io").listen(9092);

io.on("connection", function (socket) {

    socket.on('request', async (req) => {
        // await in order to wait the heavyJob to be done before sending the response
        const {id} = req; 
        var data = await heavyJob();
        const reply = { id, data };
        // Send back the data to the mid server
        socket.emit('response', reply);

    });
});

我认为您需要从“ socket.on('request',...”回调中提取“ secondServer.on('response'..”代码。

io.on('connection', async (socket) => {

    console.log('User connected');
    // On client request
    socket.on('request', async (data, callback) => {

        console.log('Requesting from ' + socket.id);
        // The same request is transmited to the second server
        secondServer.emit('request', data);
    });
    secondServer.on('response', async (data) => {
            console.log('Responding for ' + socket.id);
            callback(data.images);
    });  
});
© www.soinside.com 2019 - 2024. All rights reserved.