Nodejs socket.io写的实时监控,目前挂在heroku上面

Nodejs socket.io写的实时监控,目前挂在heroku上面

刚学node.js,用socket.io写的一个监控公司网站访问情况的页面。 没什么技术含量,还要请教一个问题 socket.broadcast.emit(‘webHouseUser’, {number: houseSumCount}); socket.broadcast.emit(‘webHouseUserDetail’, {number: houseSumCount, detail: houseCount}); 这是我写的广播代码,但是对于没有监听webHouseUserDetail这个消息的页面依然会推送,造成了很多不必要的流量,求解怎么解决这个问题呢?


4 回复

当然可以。以下是一个关于如何使用Node.js和Socket.IO实现一个简单的实时监控系统,并部署到Heroku上的示例。同时,我会解决你提到的广播问题。

示例代码

1. 初始化项目

首先,确保你的项目中已经安装了expresssocket.io。你可以通过npm来安装它们:

npm init -y
npm install express socket.io

2. 创建服务器文件 server.js

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

// 创建 Express 应用程序
const app = express();
const server = http.createServer(app);
const io = socketIo(server);

let houseSumCount = 0;
let houseCount = {};

// 监听连接事件
io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // 发送初始数据
    socket.emit('webHouseUser', { number: houseSumCount });

    // 广播更新数据
    socket.on('updateHouseData', (data) => {
        houseSumCount += data.increment;
        houseCount[data.id] = data.count;

        // 只有监听了 'webHouseUserDetail' 的客户端才会收到此消息
        socket.to(socket.id).emit('webHouseUserDetail', { number: houseSumCount, detail: houseCount });
    });

    // 断开连接时
    socket.on('disconnect', () => {
        console.log('A user disconnected:', socket.id);
    });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

3. 部署到 Heroku

确保你已经在Heroku上创建了一个应用,并且已经安装了Heroku CLI。然后,将你的项目推送到Heroku:

heroku create your-app-name
git add .
git commit -m "Initial commit"
git push heroku master

解决方案

在上述代码中,我们通过socket.to(socket.id).emit()方法来确保只有特定的客户端能够接收到webHouseUserDetail消息。这意味着只有发送了updateHouseData事件的客户端才能接收到这个消息。

这种方式避免了不必要的流量,因为你明确地指定了哪个客户端应该接收该消息。

总结

以上就是如何使用Node.js和Socket.IO创建一个简单的实时监控系统,并将其部署到Heroku的方法。希望这能帮助你解决问题并改进你的应用!


有试过用io.of(’/chat’)和io.of(’/user’);这样的方法吗

流量收费么?

当你使用 socket.broadcast.emit 时,所有的客户端都会接收到该事件,即使它们没有监听该特定事件。为了确保只有监听了特定事件的客户端才会接收消息,你需要在客户端明确地监听这些事件。

以下是解决办法:

客户端代码

客户端需要分别监听不同的事件,并在不需要的时候忽略它们。例如:

// 监听 'webHouseUser' 事件
socket.on('webHouseUser', function(data) {
    console.log('Received webHouseUser event:', data);
    // 处理数据
});

// 监听 'webHouseUserDetail' 事件
socket.on('webHouseUserDetail', function(data) {
    console.log('Received webHouseUserDetail event:', data);
    // 处理数据
});

服务器端代码

你可以发送不同的事件到不同的客户端,或者根据客户端的需求动态决定发送哪个事件。这可以通过保持客户端连接的信息(例如,保存在一个数组或对象中)来实现。

示例:按需发送事件

const clients = {}; // 用于存储连接的客户端

io.on('connection', function(socket) {
    clients[socket.id] = socket;

    // 当客户端请求订阅特定事件时,将其添加到相应的列表中
    socket.on('subscribeToWebHouseUser', () => {
        socket.join('webHouseUser');
    });

    socket.on('subscribeToWebHouseUserDetail', () => {
        socket.join('webHouseUserDetail');
    });

    // 发送 'webHouseUser' 事件给所有在 'webHouseUser' 房间中的客户端
    socket.broadcast.to('webHouseUser').emit('webHouseUser', { number: houseSumCount });

    // 发送 'webHouseUserDetail' 事件给所有在 'webHouseUserDetail' 房间中的客户端
    socket.broadcast.to('webHouseUserDetail').emit('webHouseUserDetail', { number: houseSumCount, detail: houseCount });

    socket.on('disconnect', function() {
        delete clients[socket.id];
    });
});

在这个示例中,客户端可以请求订阅特定的事件。服务器将根据订阅状态广播事件。客户端可以选择是否订阅这些事件,从而避免不必要的数据传输。

这种方法允许你精确控制哪些客户端接收到特定的数据,从而减少不必要的流量。

回到顶部