Mat*_*kin 17 sockets node.js socket.io
我正在尝试将Socket.io与Node.js一起使用并发送到路由逻辑中的套接字.
我有一个相当标准的Express 3设置,其中包含一个位于路由中的server.js文件,然后我有一个index.js,它位于路径文件夹中,用于导出站点的所有页面/可公开访问的功能.所以他们看起来像:
exports.index = function (req, res) {
res.render('index', {
title: "Awesome page"
});
};
Run Code Online (Sandbox Code Playgroud)
与server.js中定义的路由类似:
app.get('/',routes.index);
Run Code Online (Sandbox Code Playgroud)
我假设我必须在server.js中创建socket.io对象,因为它需要服务器对象,但是如何访问该对象并从index.js导出函数向它发出?
aar*_*sil 88
现在有一种更好的方法可以使用Express 4.0.
您可以使用app.set()来存储io对象的引用.
基本配置:
var app = require('express')();
var server = app.listen(process.env.PORT || 3000);
var io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);
Run Code Online (Sandbox Code Playgroud)
内部路由或中间件:
exports.foo = function(req,res){
// now use socket.io in your routes file
var io = req.app.get('socketio');
io.emit('hi!');
}
Run Code Online (Sandbox Code Playgroud)
关于信息app.set()和app.get()低于:
app.set(名称,值)
将设置名称指定给值.您可以存储所需的任何值,但可以使用某些名称来配置服务器的行为.这些特殊名称列在应用程序设置表中.
调用
app.set('foo', true)Boolean属性与调用相同app.enable('foo').同样,调用app.set('foo', false)Boolean属性与调用相同app.disable('foo').使用检索设置的值
app.get().
资料来源:https: //expressjs.com/en/api.html#app.set
hex*_*ide 19
您可以将路径文件设置为函数,并在需要该文件时传递Socket.IO对象.
module.exports = function(io) {
var routes = {};
routes.index = function (req, res) {
io.sockets.emit('payload');
res.render('index', {
title: "Awesome page"
});
};
return routes;
};
Run Code Online (Sandbox Code Playgroud)
然后需要这样的路线:
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var routes = require('./routes')(io);
Run Code Online (Sandbox Code Playgroud)
joh*_*ohn 13
aarosil的答案很棒,但我遇到了与Victor一样的问题,使用这种方法管理客户端连接.对于客户端上的每次重新加载,您将在服务器上获得尽可能多的重复消息(第二次重新加载= 2次重复,第三次= 3次重复等).
扩展了aarosil的答案,我使用这种方法在我的路由文件中使用套接字对象,并管理连接/控制重复消息:
内部服务器文件
// same as aarosil (LIFESAVER)
const app = require('express')();
const server = app.listen(process.env.PORT || 3000);
const io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);
Run Code Online (Sandbox Code Playgroud)
内部路线文件
exports.foo = (req,res) => {
let socket_id = [];
const io = req.app.get('socketio');
io.on('connection', socket => {
socket_id.push(socket.id);
if (socket_id[0] === socket.id) {
// remove the connection listener for any subsequent
// connections with the same ID
io.removeAllListeners('connection');
}
socket.on('hello message', msg => {
console.log('just got: ', msg);
socket.emit('chat message', 'hi from server');
})
});
}
Run Code Online (Sandbox Code Playgroud)
在这里添加超级晚,但我想访问我的路由中的套接字,并且特别想在保存到数据库后广播一条消息。我使用@aarosil 提供的答案来设置/获取 io 对象,在连接时向每个客户端发送其套接字 id,然后在路由中使用套接字 id 来socket.broadcast.emit()代替io.emit().
在服务器中:
const io = require('socket.io')(server)
app.set('socketio', io)
io.on('connect', socket => {
socket.emit('id', socket.id) // send each client their socket id
})
Run Code Online (Sandbox Code Playgroud)
我发送每个请求的套接字 ID,然后我可以在我的路由中执行以下操作:
router.post('/messages', requireToken, (req, res, next) => {
// grab the id from the request
const socketId = req.body.message.socketId
// get the io object ref
const io = req.app.get('socketio')
// create a ref to the client socket
const senderSocket = io.sockets.connected[socketId]
Message.create(req.body.message)
.then(message => {
// in case the client was disconnected after the request was sent
// and there's no longer a socket with that id
if (senderSocket) {
// use broadcast.emit to message everyone except the original
// sender of the request !!!
senderSocket.broadcast.emit('message broadcast', { message })
}
res.status(201).json({ message: message.toObject() })
})
.catch(next)
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22104 次 |
| 最近记录: |