Nodejs和socket.io的一个问题

Nodejs和socket.io的一个问题

现在是这样的, 我client端和server端都写好了 sever端socket.io 服务器在www这个文件中(用的是express4.x,和在app.js是一样的), 现在有一个请求,路由为/res,这个响应时间比较长,我想用socket.io把结果推送回去, 最后的消息是在res.js这个文件中,我怎么用www中的socket发送啊

5 回复

当然可以。你的需求是通过Socket.IO将一个长时间运行的请求的结果推送给客户端。为了实现这一点,你需要在www文件中设置Socket.IO,并在处理长时间运行的请求时使用它来发送消息。

示例代码

1. 在 www 文件中设置 Socket.IO

首先,确保你已经在www文件中引入了必要的模块并初始化了Socket.IO

// www 文件
var app = require('../app'); // 引入 app.js
var debug = require('debug')('your-app-name');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */
var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

// 初始化 Socket.IO
var io = require('socket.io')(server);

io.on('connection', function(socket) {
    console.log('a user connected');
    
    socket.on('disconnect', function() {
        console.log('user disconnected');
    });
});

module.exports = server;

2. 在 res.js 中触发事件并发送数据

接下来,在处理长时间运行的请求时,你可以触发一个事件并通过Socket.IO发送结果。

// res.js 文件
const express = require('express');
const router = express.Router();
const io = require('./www').io; // 引入从 www 文件中导出的 io 实例

router.get('/res', function(req, res, next) {
    // 模拟一个长时间运行的任务
    setTimeout(() => {
        const result = { message: "任务完成" };

        // 发送结果给客户端
        io.emit('result', result);
        
        // 返回结果给客户端
        res.json(result);
    }, 5000); // 延迟5秒模拟长时间任务
});

module.exports = router;

3. 客户端代码

在客户端,你需要监听来自服务器的事件,并显示结果。

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Socket.IO Example</title>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <h1>等待服务器结果</h1>
    <div id="result"></div>

    <script>
        var socket = io();

        socket.on('result', function(data) {
            document.getElementById('result').innerText = JSON.stringify(data);
        });

        // 当用户点击按钮时,向服务器发起请求
        document.getElementById('request-btn').addEventListener('click', function() {
            fetch('/res')
                .then(response => response.json())
                .then(data => {
                    console.log(data);
                });
        });
    </script>
</body>
</html>

解释

  1. 服务器端

  2. 客户端

    • 使用Socket.IO连接到服务器。
    • 监听来自服务器的result事件,并更新页面上的内容。

这样,即使请求需要较长时间才能完成,你也可以立即向客户端推送结果。


楼主的描述好抽象… 为什么不直接都用 socket.io 算了?

: client端和server端都写好了 sever端socket.io 服务器在www这个文件中 同不明白,既然socket.io的架子都搭好了,就用socket.io推送信息就可以了。

我猜测你的路由文件(比如:route.js)中处理路由的代码(比如:app.get('/res', function (req, res) {}) )要用socket这个对象处理业务逻辑,但是socket对象在www里面,所以捉鸡了。 快速的解决方法是把io这个对象暴露出来,然后在路由中引用他(需要注意的是:在www这个文件下这样做并不好)

www

	var io = require('socket.io')(server)
	module.exports = io

route.js

	var io = require('path/to/www')
	res.get('/res', function (req, res) { io.on('connection', function () {}) })

要实现从 www 文件中的逻辑通过 Socket.io 将数据推送到客户端,你需要确保服务器端和客户端都已经正确地集成了 Socket.io。以下是一个简单的示例来说明如何实现这一功能。

服务器端 (www 文件)

首先,确保你的服务器端已经引入并配置了 Socket.io

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

// 路由处理
app.get('/res', (req, res) => {
    // 假设这是你的长响应逻辑
    setTimeout(() => {
        const result = { message: 'Processing completed' };
        
        // 通过 Socket.io 发送消息给客户端
        io.emit('result', result); // 或者你可以使用 socket.to(socketId).emit 来发送给特定用户
        
        res.status(200).send('Request processed');
    }, 5000); // 模拟长时间的处理
});

server.listen(3000, () => {
    console.log('Server listening on port 3000');
});

客户端 (res.js 文件)

在客户端,你需要监听来自服务器的事件:

<script src="/socket.io/socket.io.js"></script>
<script>
    const socket = io();

    socket.on('result', (data) => {
        console.log('Received result from server:', data);
        // 这里可以处理接收到的数据,例如更新页面内容
    });

    // 可以发送消息到服务器
    // socket.emit('someEvent', { message: 'Hello Server!' });
</script>

总结

  • www 文件中,当 /res 请求被处理完成后,我们通过 io.emit 将消息发送给所有连接的客户端。
  • 在客户端的 res.js 文件中,我们通过监听 'result' 事件来接收从服务器发送过来的数据,并进行相应的处理。

这种方法能够有效地将长时间运行的任务的结果实时推送给客户端,提升了用户体验。

回到顶部