繁体   English   中英

在 node.js 应用程序 controller 中实现 socket.io

[英]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 端点,或者您选择组织它,您可以在其他文件中使用相同的socketapp (如果您还需要公开 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM