express.js 4 和 sockets with express router
express.js 4 and sockets with express router
我正在尝试使用 express.js 4 创建一个非常简单的节点 API,但我需要一些 'realtime' 我添加了 socket.io 的事件。我对两者都很陌生,所以我可能遗漏了一些基本的东西,但我找不到好的 docs/tuts。
在 express 应用程序(使用 express 生成器创建)中,我有类似的东西,基于我阅读的简单示例和项目文档。这工作正常,从客户端应用程序,我可以 send/receive 套接字事件:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// error handlers omitted
module.exports = app;
但我想使用我的 API 路由中的套接字(在我上面 'require' 的 ./routes/api.js 文件中)。例如,有人可能使用 API 到 PUT/POST 资源,我希望该广播连接到 socket.io 客户端。
我看不到如何使用 'io' 变量或组织当前在 express routes 中的 io.sockets.on('connection' ...
函数中的代码。这是 ./routes/api.js
文件:
var express = require('express');
var router = express.Router();
var io = ???;
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
io.sockets.emit('update', foo); // how?
});
module.exports = router;
我已经稍微修改了你的文件,你可以检查它是否有效?
您可以将您定义的 io 传递给您的路由,如下所示;
require('./routes/api')(app,io);
我没有测试 Socket.IO 部分,但没有语法错误,路由也有效。
server.js 文件:
var express = require('express');
var app = express();
var path = require('path');
var logger = require('morgan');
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
require('./routes/api')(app,io);
console.log("Server listening at port 3000");
api.js:
module.exports = function(app,io) {
app.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
console.log("PUT OK!");
io.sockets.emit('update'); // how?
res.json({result: "update sent over IO"});
});
}
一种选择是将其传递给 req 对象。
app.js:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// Make io accessible to our router
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/api', api);
// error handlers omitted
module.exports = app;
./routes/api.js:
var express = require('express');
var router = express.Router();
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
req.io.sockets.emit('update', foo);
});
module.exports = router;
假设您想从应用程序的任何地方访问 SocketIO,而不仅仅是在路由器中,您可以为它创建一个单例。这对我有用:
//socket-singletion.js
var socket = require('socket.io');
var SocketSingleton = (function() {
this.io = null;
this.configure = function(server) {
this.io = socket(server);
}
return this;
})();
module.exports = SocketSingleton;
然后,您需要使用您的服务器对其进行配置:
//server config file
var SocketSingleton = require('./socket-singleton');
var http = require('http');
var server = http.createServer(app);
SocketSingleton.configure(server); // <--here
server.listen('3000');
最后,随心所欲地使用它:
//router/index.js
var express = require('express');
var router = express.Router();
var SocketSingleton = require('../socket-singleton');
/* GET home page. */
router.get('/', function(req, res, next) {
setTimeout(function(){
SocketSingleton.io.emit('news', {msg: 'success!'});
}, 3000);
res.render('index', { title: 'Express' });
});
module.exports = router;
另一种选择是使用 req.app。
app.js
const express = require('express');
const path = require('path');
const logger = require('morgan');
const api = require('./routes/api');
const app = express();
const io = require('socket.io').listen(app.listen(3000));
// Keep the io instance
app.io = io;
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
// ...
app.use('/api', api);
module.exports = app;
routes/api.js
const express = require('express');
const router = express.Router();
router.put('/foo', function(req, res) {
/*
* API
*/
// Broadcast the updated foo..
req.app.io.sockets.emit('update', foo);
});
module.exports = router;
我认为最好的方法是将 io 设置为请求的 属性,如下所示:
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/your-sub-link', your-router);
重构了 的答案。
更改单例以创建 socket.io 服务器的新实例
const { Server } = require('socket.io');
const singleton = (() => {
this.configure = (server) => this.io = new Server(server)
return this
})();
module.exports = singleton
初始化您的 Express 应用、服务器和单例。
// initialise app
const app = express();
const server = require('http').createServer(app);
// configure socket.io
socket.configure(server)
然后在你的路由器中
const socket = require('/utils/socket-singleton');
socket.io.emit('event', {message: 'your message here'})
我正在尝试使用 express.js 4 创建一个非常简单的节点 API,但我需要一些 'realtime' 我添加了 socket.io 的事件。我对两者都很陌生,所以我可能遗漏了一些基本的东西,但我找不到好的 docs/tuts。
在 express 应用程序(使用 express 生成器创建)中,我有类似的东西,基于我阅读的简单示例和项目文档。这工作正常,从客户端应用程序,我可以 send/receive 套接字事件:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// error handlers omitted
module.exports = app;
但我想使用我的 API 路由中的套接字(在我上面 'require' 的 ./routes/api.js 文件中)。例如,有人可能使用 API 到 PUT/POST 资源,我希望该广播连接到 socket.io 客户端。
我看不到如何使用 'io' 变量或组织当前在 express routes 中的 io.sockets.on('connection' ...
函数中的代码。这是 ./routes/api.js
文件:
var express = require('express');
var router = express.Router();
var io = ???;
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
io.sockets.emit('update', foo); // how?
});
module.exports = router;
我已经稍微修改了你的文件,你可以检查它是否有效?
您可以将您定义的 io 传递给您的路由,如下所示;
require('./routes/api')(app,io);
我没有测试 Socket.IO 部分,但没有语法错误,路由也有效。
server.js 文件:
var express = require('express');
var app = express();
var path = require('path');
var logger = require('morgan');
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
require('./routes/api')(app,io);
console.log("Server listening at port 3000");
api.js:
module.exports = function(app,io) {
app.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
console.log("PUT OK!");
io.sockets.emit('update'); // how?
res.json({result: "update sent over IO"});
});
}
一种选择是将其传递给 req 对象。
app.js:
var express = require('express');
var path = require('path');
var logger = require('morgan');
var api = require('./routes/api');
var app = express();
var io = require('socket.io').listen(app.listen(3000));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
io.sockets.on('connection', function (socket) {
console.log('client connect');
socket.on('echo', function (data) {
io.sockets.emit('message', data);
});
});
// Make io accessible to our router
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/api', api);
// error handlers omitted
module.exports = app;
./routes/api.js:
var express = require('express');
var router = express.Router();
router.put('/foo', function(req, res) {
/*
do stuff to update the foo resource
...
*/
// now broadcast the updated foo..
req.io.sockets.emit('update', foo);
});
module.exports = router;
假设您想从应用程序的任何地方访问 SocketIO,而不仅仅是在路由器中,您可以为它创建一个单例。这对我有用:
//socket-singletion.js
var socket = require('socket.io');
var SocketSingleton = (function() {
this.io = null;
this.configure = function(server) {
this.io = socket(server);
}
return this;
})();
module.exports = SocketSingleton;
然后,您需要使用您的服务器对其进行配置:
//server config file
var SocketSingleton = require('./socket-singleton');
var http = require('http');
var server = http.createServer(app);
SocketSingleton.configure(server); // <--here
server.listen('3000');
最后,随心所欲地使用它:
//router/index.js
var express = require('express');
var router = express.Router();
var SocketSingleton = require('../socket-singleton');
/* GET home page. */
router.get('/', function(req, res, next) {
setTimeout(function(){
SocketSingleton.io.emit('news', {msg: 'success!'});
}, 3000);
res.render('index', { title: 'Express' });
});
module.exports = router;
另一种选择是使用 req.app。
app.js
const express = require('express');
const path = require('path');
const logger = require('morgan');
const api = require('./routes/api');
const app = express();
const io = require('socket.io').listen(app.listen(3000));
// Keep the io instance
app.io = io;
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
// ...
app.use('/api', api);
module.exports = app;
routes/api.js
const express = require('express');
const router = express.Router();
router.put('/foo', function(req, res) {
/*
* API
*/
// Broadcast the updated foo..
req.app.io.sockets.emit('update', foo);
});
module.exports = router;
我认为最好的方法是将 io 设置为请求的 属性,如下所示:
app.use(function(req,res,next){
req.io = io;
next();
});
app.use('/your-sub-link', your-router);
重构了
更改单例以创建 socket.io 服务器的新实例
const { Server } = require('socket.io');
const singleton = (() => {
this.configure = (server) => this.io = new Server(server)
return this
})();
module.exports = singleton
初始化您的 Express 应用、服务器和单例。
// initialise app
const app = express();
const server = require('http').createServer(app);
// configure socket.io
socket.configure(server)
然后在你的路由器中
const socket = require('/utils/socket-singleton');
socket.io.emit('event', {message: 'your message here'})