[英]Implement socket.io in node.js application controller
下午好。 我是在 node.js 中编程 sockets 的新手,我需要在 my 应用程序的 Z594C103F2C6E004C3D8AB05C 中实现 socket.io。 我拥有的架构如下:
启动服务器的文件是 index.js
const express = require('express');
const app = express();
const port = 3000;
const socketRouter = require('./routes/socket')
app.use(express.json());
//Route
app.use('/socket', socketRouter);
app.listen(port, () => {
console.log(`Server connection on http://127.0.0.1:${port}`); // Server Connnected
});
我定义路由的文件是 socket.js
const { Router } = require('express');
const { showData } = require('../controllers/socket');
const router = Router();
router.post('/send-notification', showData);
module.exports = router;
而我的 controller 是:
const { response } = require('express');
const showData = (req, res = response) => {
const notify = { data: req.body };
//socket.emit('notification', notify); // Updates Live Notification
res.send(notify);
}
module.exports={
showData
}
我需要在这个 controller 中实现 socket.io 才能从中发射,但我无法让它工作。 你能告诉我怎么做吗? 非常感谢
澄清:如果我在主文件中实现 socket.io 它可以工作,但我想要一些顺序和单独的东西。 这是它的工作原理:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
app.post('/send-notification', (req, res) => {
const notify = { data: req.body };
socket.emit('notification', notify); // Updates Live Notification
res.send(notify);
});
const server = app.listen(port, () => {
console.log(`Server connection on http://127.0.0.1:${port}`); // Server Connnected
});
const socket = require('socket.io')(server);
socket.on('connection', socket => {
console.log('Socket: client connected');
});
如果您想按功能分开套接字消息和 REST 端点,或者您选择组织它,您可以在其他文件中使用相同的socket
和app
(如果您还需要公开 API)。 以下是如何做到这一点的示例:
创建一个新文件,比如controller1.js
:
function initialize(socket, app) {
socket.on('some-socket-message', socket => {
// Whatever you want to do
});
app.get('/some-endpoint', (req, res) => {
// whatever you want to do
});
}
module.exports = {initialize}
然后将以下内容添加到您的controller.js
const controller1 = require('path/to/controller1');
...
// At some point after socket and app have been defined
controller1.initalize(socket, app);
这将是根据需要分离 controller 的基础,同时在所有控制器中仍使用相同的套接字连接和 API 端口。 您还可以将initialize
方法重构为不同的方法,但这取决于您自己的判断以及您希望如何命名函数等。它也不需要称为initalize
,这只是我的偏好名称。
感谢您的回答,但我不清楚。 我在哪里进行套接字的初始配置? 我在controller中没有这样的配置
将您的 socket.io 代码移动到其自己的模块中,您可以在其中导出共享 socket.io 服务器实例的方法:
// local socketio.js module
const socketio = require('socket.io');
let io;
modules.exports = {
init: function(server) {
io = socketio(server);
return io;
},
getIO: function() {
if (!io) {
throw new Error("Can't get io instance before calling .init()");
}
return io;
}
}
然后,在您的主应用程序文件中初始化 socketio.js 模块:
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
const server = app.listen(port, () => {
console.log(`Server connection on http://127.0.0.1:${port}`); // Server Connnected
});
// initialize your local socket.io module
const sio = require('./socketio.js');
sio.init(server);
// now load socket.io dependent routes
// only after .init() has been called on socket.io module
const socketRouter = require('./routes/socket')
app.use('/socket', socketRouter);
然后,在任何你想访问 socket.io 服务器实例的地方,你都可以require("./socketio.js")
并使用.getIO()
方法来获取 socket.io 实例:
// use correct path to socketio.js depending upon where this module
// is located in the file system
const io = require("../../socketio.js").getIO();
// some Express route in a controller
const showData = (req, res) => {
const notify = { data: req.body };
// send notification to all connected clients
io.emit('notification', notify);
res.send(notify);
};
module.exports= {
showData
};
注意:服务器上典型的 socket.io 使用约定是使用io
作为服务器实例,使用socket
作为单独的客户端连接套接字实例。 请不要尝试同时使用socket
。 这清楚地表明io.emit(...)
正在尝试发送到所有连接的客户端,而socket.emit()
正在尝试发送到单个连接的客户端。
另请注意,如果您的路由是由浏览器本身发送表单帖子的表单帖子触发的,那么该特定客户端将不会收到从该表单帖子路由完成的io.emit(...)
的结果,因为该浏览器将在根据表单帖子的响应加载新的 web 页面的过程中,将破坏其当前的 socket.io 连接。 如果表单发布完全通过 Javascript 使用 Ajax 调用完成,则该网页将保持活动状态并接收io.emit(...)
的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.