简体   繁体   English

io.sockets.on无法在Node.js中的路由中工作

[英]io.sockets.on not working inside a route in Node.js

I'm trying to use io.sockets.on inside a route in a Node.js and Express app. 我正在尝试在Node.js和Express应用程序中的路由中使用io.sockets.on。 I have been following what is said here: https://stackoverflow.com/a/31277123/8271839 我一直在关注这里所说的内容: https//stackoverflow.com/a/31277123/8271839

I can successfully send io.sockets.emit events, but I cannot receive events with io.sockets.on. 我可以成功发送io.sockets.emit事件,但我无法通过io.sockets.on接收事件。

Here is my code: 这是我的代码:

index.js: 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');

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

app.set('socketio', io);

server.listen(4002);

io.sockets.on("connection",function(socket){
    console.log("connected");
    socket.on("connected", function (data) {
        console.log("hello");
    })
});

routes/taskRequest.js: 路线/ taskRequest.js:

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

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

    var io = req.app.get('socketio');

    //pickedUser is one of the connected client
    var pickedUser = "JZLpeA4pBECwbc5IAAAA";

    //we only send the emit event to the pickedUser
    io.to(pickedUser).emit('taskRequest', req.body);

    io.on('connection', function (socket) {
        console.log('connected 2');
        socket.on('taskResponse', function () {
            console.log('hello 2');
        });
    });

});

module.exports = router; 

When a client is connected, I get the "connected" message in console, but not the "connected 2" message. 当客户端连接时,我在控制台中收到“已连接”消息,但不是“已连接2”消息。

Also, when client emits "connected" message, I get "hello" in console, but when clients emits "taskResponse" message, I don't get "hello 2" in console. 此外,当客户端发出“已连接”消息时,我在控制台中得到“hello”,但是当客户端发出“taskResponse”消息时,我在控制台中没有得到“hello 2”。

Though when io.to(pickedUser).emit('taskRequest', req.body); 虽然当io.to(pickedUser).emit('taskRequest', req.body); is called, it works, client receives the "taskRequest" message. 被调用,它工作,客户端收到“taskRequest”消息。

Why is .emit() working inside my route but not .on() ? 为什么.emit()在我的路线内工作而不是.on()?

According to you code, io is a Socket.IO server instance attached to an instance of http.Server listening for incoming events. 根据您的代码, io是附加到http.Server实例的Socket.IO服务器实例,用于侦听传入事件。 Then inside the route you are again attaching a instance to listen to to incoming events which does not work. 然后在路由中再次附加一个实例来监听不起作用的传入事件。 the io.to(pickedUser).emit works because the server instance with socketio is correctly listening to the connection thus giving the console.log("connected");. io.to(pickedUser).emit有效,因为带有socketio的服务器实例正在正确地监听连接,因此给出了console.log(“connected”);.

index.js: 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');

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

app.set('socketio', io);

server.listen(4002);

routes/taskRequest.js: 路线/ taskRequest.js:

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

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

    var io = req.app.get('socketio');

    //pickedUser is one of the connected client
    var pickedUser = "JZLpeA4pBECwbc5IAAAA";

    io.on('connection', function (socket) {
        console.log('connected 2');
        io.to(pickedUser).emit('taskRequest', req.body);
        socket.on('taskResponse', function () {
            console.log('hello 2');
        });
    });

});

module.exports = router; 

I mark TRomesh answer as the right answer, since indeed you can only have one io.on('connection', function (socket) {}) in your code. 我将TRomesh的答案标记为正确的答案,因为你的代码中确实只能有一个io.on('connection', function (socket) {})

Now here is what I have done to make it work for me: the issue was that if you place io.on('connection', function (socket) {}) within your router.post('/', async (req, res) => {}) , it will only be triggered when you call your endpoint. 现在我正在做的就是让它适合我:问题是如果你把io.on('connection', function (socket) {})放在你的router.post('/', async (req, res) => {}) ,只有在调用端点时才会触发。 In my case, I had some sockets events that I wanted to be called at anytime, not only when the endpoint is called. 在我的例子中,我有一些我想在任何时候调用的套接字事件,而不仅仅是在调用端点时。 So I had to place the io.on('connection', function (socket) {}) outside of my router.post('/', async (req, res) => {}) . 所以我不得不将io.on('connection', function (socket) {})放在我的router.post('/', async (req, res) => {}) Thus I couldn't use var io = req.app.get('socketio'); 因此我无法使用var io = req.app.get('socketio'); inside the router. 在路由器内部。 Here is what I have done instead: 以下是我所做的事情:

index.js: 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);

routes/taskRequest.js 路线/ 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;

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM