javascript - 从路由发出 websocket 消息

标签 javascript node.js websocket socket.io

我正在尝试使用 websockets 设置我的服务器,这样当我通过我的路由更新某些内容时,我也可以在该路由上的某些内容更新时发出 websocket 消息。

这个想法是当有人点击路由 /add-team-member 时将一些东西保存到我的 Mongo 数据库,然后向通过 websocket 连接的每个人发送一条消息,并且是任何东西的一部分与该团队相对应的 websocket 房间。

我已经按照 socket.io 的文档按照以下方式设置我的应用程序:

App.js

// there's a lot of code in here which sets what to use on my app but here's the important lines

const app = express();
const routes = require('./routes/index');

const sessionObj = {
    secret: process.env.SECRET,
    key: process.env.KEY,
    resave: false,
    saveUninitialized: false,
    store: new MongoStore({ mongooseConnection: mongoose.connection }),
             secret : 'test',
             cookie:{_expires : Number(process.env.COOKIETIME)}, // time im ms    
}

app.use(session(sessionObj));
app.use(passport.initialize());
app.use(passport.session());

module.exports = {app,sessionObj};

start.js

const mongoose = require('mongoose');
const passportSocketIo = require("passport.socketio");
const cookieParser = require('cookie-parser');

// import environmental variables from our variables.env file
require('dotenv').config({ path: 'variables.env' });

// Connect to our Database and handle an bad connections
mongoose.connect(process.env.DATABASE);

// import mongo db models
require('./models/user');
require('./models/team');

// Start our app!
const app = require('./app');
app.app.set('port', process.env.PORT || 7777);

const server = app.app.listen(app.app.get('port'), () => {
  console.log(`Express running → PORT ${server.address().port}`);
});

const io = require('socket.io')(server);

io.set('authorization', passportSocketIo.authorize({
  cookieParser: cookieParser,
  key:         app.sessionObj.key,       // the name of the cookie where express/connect stores its session_id 
  secret:      app.sessionObj.secret,    // the session_secret to parse the cookie 
  store:       app.sessionObj.store,        // we NEED to use a sessionstore. no memorystore please 
  success:     onAuthorizeSuccess,  // *optional* callback on success - read more below 
  fail:        onAuthorizeFail,     // *optional* callback on fail/error - read more below 
}));


function onAuthorizeSuccess(data, accept){}

function onAuthorizeFail(data, message, error, accept){}

io.on('connection', function(client) {  
  client.on('join', function(data) {
      client.emit('messages',"server socket response!!");
  });

  client.on('getmessage', function(data) {
    client.emit('messages',data);
});  

});

我的问题是我的 ./routes/index 文件中有很多 mongo DB 保存操作,我希望能够从我的路由发出消息而不是从连接 socket.io 的 start.js 末尾开始。

有什么方法可以从我的 ./routes/index 文件发出 websocket 消息,即使在 start.js 中进一步设置了 IO?

例如这样的事情:

router.get('/add-team-member', (req, res) => {
  // some io.emit action here
});

也许我需要移动到我正在初始化 socket.io 东西的地方,但还没有找到任何关于这个的文档,或者我可能已经可以通过某种方式从路由访问 socket.io 了?

感谢并感谢您的帮助,如果有任何不清楚的地方,请告诉我!

最佳答案

如上所述,io 在您的全局范围内。如果你这样做

router.get('/add-team-member', (req, res) => {
    io.sockets.emit('AddTeamMember');
});

然后每个连接的客户端,如果监听该事件 AddTeamMember,将在其各自的客户端上运行关联的 .on 函数。这可能是最简单的解决方案,除非您预计会出现大量没有任何负载平衡计划的用户,否则这应该暂时适合。

另一种选择: socket.io lib 有一个房间功能,您可以使用 io 对象本身加入和发射 https://socket.io/docs/rooms-and-namespaces/如果你有这方面的诀窍,它看起来像这样:

io.sockets.in('yourroom').broadcast('AddTeamMember');

这基本上会做与顶部相同的事情,只是不是向每个客户端广播,而是只向那个房间独有的那些广播。您基本上必须想出一种方法,让用户在////他们发出获取请求之前//进入房间,或者换句话说,让他们独享。这样一来,您就可以减少每次发出路由请求时服务器必须推出的负载量。

最后,如果以上选项都不适合您,并且您绝对必须在他们启动它时发送给那个单一的客户,那么它会变得困惑,因为您必须为那个人提供某种 ID ,并且由于您没有引用,因此您必须在连接时存储所有套接字,然后进行比较。我不完全推荐这样的东西,因为好吧,我从来没有测试过它,也不知道会发生什么类型的反响,但这是我的一个想法:

app.set('trust proxy', true)
var SOCKETS = []
io.on('connection', function(client) {
  SOCKETS.push(client);
  client.on('join', function(data) {
    client.emit('messages',"server socket response!!");
  });

  client.on('getmessage', function(data) {
    client.emit('messages',data);
  });
});

router.get('/add-team-member', (req, res) => {
    for (let i=0; i< SOCKETS.length; i++){
        if(SOCKETS[i].request.connection.remoteAddress == req.ip)
          SOCKETS[i].emit('AddTeamMember');
    }
});

请记住,如果您确实走这条路,您将需要在用户断开连接时维护该数组,如果您正在进行 session 管理,那将很快变得毛茸茸。

祝你好运,让我们知道你的结果。

关于javascript - 从路由发出 websocket 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48250251/

相关文章:

node.js - Google Home 应用开发本地设备访问

java - 使用 Spring Security 的 SpringMVC Websockets 消息传递用户身份验证

php - Ratchet Websockets over WSS on iis8

python - 从 Coinbase Exchange API Websocket 接收数据

javascript - 强制给定的 RegExp 不区分大小写

javascript - jquery每个regexp href同时检查一些字符串

javascript - 如何动态获取subMaterial索引?

javascript - Firestore : Unable to read document data (Uncaught TypeError: docSnap. 存在不是 HTMLFormElement 的函数)

javascript - 如何上传 zip 文件并在 Express js 中为其内容提供永久链接

node.js - 使用 Node.js 数据创建 POST http.request 的问题在 FormValue 而不是 Body 中传递