Node.js-Express-Socket.io如何从外部函数向特定的socket.id发送消息?

时间:2020-03-25 23:07:10

标签: node.js

我在为此找到正确答案时遇到了问题。考虑到我正在处理多个用户,我正在尝试向特定的socket.id发送消息,但我需要从另一个无法访问socket.io的功能中进行操作。

我需要将消息发送到函数内的特定socket.id:

var authorizePublish = function(client, topic, payload, callback) {
//here
}

socketLib.js

/// Import Modules ///
const mosca = require('mosca');
const DeviceService = require('../services/device.service');
const config = require('../config');
const util = require('../modules/util.js');

module.exports = async function(httpServer, sessionParser) {
    var io = require("socket.io")(httpServer); // For Sockets

    io.use(function(socket, next) {
        sessionParser(socket.request, socket.request.res, next);
    });

    io.sockets.on('connection', function(socket) {
        const userSessionId = socket.request.session.userId;
        const userId = socket.request.session.passport.user;
        const socketId = socket.request.session.id;
        if (userSessionId == '') 
            console.log('client connected');
        console.log(`Client connected: ${userSessionId}, with userid: ${userId}, with socket: ${socketId} conectado`);

        socket.on('msg:message', async function (data) {
            socket.emit('message', data);
        });          

        socket.on('disconnect', function(data) {
            console.log('user disconnected');
        });
    });

    /// Mosca  Settings ///
    var moscaServer = null;
    var moscaSettings = {  
        interfaces: [ { type: "mqtt", port: 1884 }, { type: "http", port: 5000, bundle: true, static: './' }
    ],};
    var debug = util.isDebug(),
        isAuth = util.isAuth()

    //// Mosca Server ////
    var dbHost = config.dbHost;
    moscaServer = new mosca.Server(moscaSettings); 
    moscaServer.on('ready', setup);

    var authenticate = function(client, username, callback) {
      console.log('-------- Authenticating MQTT user... --------');

      callback(null, flag);

      if(authenticate) client.user = username; 
    }

    /// Mosca Events ///
    moscaServer.on('published', function (packet, client) {
        var arr = packet.topic.split('/');
        if (arr.length !== 3) { return; }
    });

    /// Mosca Functions ///
    var authorizePublish = function(client, topic, payload, callback) {
      if (client.user == topic.split('/')[1]) {

        // socket.emit('message', payload.toString());  (Here is where I need to get access to the client socket.id in order to send him a message with the payload.

        callback(null, true);
      }
      else {
        callback(null, false);
      }

    }

    function setup() {
    if (isAuth) {
        moscaServer.authenticate = authenticate;
    }
    if (config.authPub === true) {
        moscaServer.authorizePublish = authorizePublish;
    }
    if(config.authSubs == true) {
        moscaServer.authorizeSubscribe = authorizeSubscribe;
    }
    console.log('Mosca server is up and running')
    }    

}

1 个答案:

答案 0 :(得分:0)

首先,发送到特定套接字ID的方式是这样的:

io.to(id).emit(msg, data);

其中id是您要发送到的socket.io连接的socket.id

或者,您可以将其放入函数中

function sendToId(id, msg, data) {
    io.to(id).emit(msg, data);
}

因此,第二步是可以在您有多个选择的任何地方进行此操作:

  1. 您可以导入io实例,并将其与上面的代码行结合使用。
  2. 您可以从确实可以访问sendToId()实例的模块中导出名为io之类的函数,然后可以导入该函数以便使用它。
  3. 您可以将io实例分配给已知对象,以便任何可以访问该更广为人知的对象的人都可以从那里检索该对象。例如,可以像在app中一样,在Express app.set("io", io)对象上将其正确设置,然后任何有权访问app对象的人都可以let io = app.get("io");来获取它并使用它。