心跳检测(梁王的开发笔记)

前言

最近在做一个类chatroom的模块,前端用的vue+vue-socket.io,chat服务器用nodejs+socketio搭的,通信的时候发现个问题。
当前端连接之后,node会生成一个id然后通过emit给前端并讲id加入一个Set里面,然而如果我前端页面刷新之后我的列表里面原来的id还在。这里我需要一个机制能够帮我检测节点是否存活,如果死掉了就把它从列表里面删了。

分析

我隐约记得以前软件设计与体系结构里面提到过类似的东西,我只记得两个方法的名词,一个是ping-echo,我估计大概是程序在某个特定的时间点向列表里面的所有节点发出ping,然后在规定的时间内等待节点echo,没收到的设置为死节点。另一个就是heartbeat了,每一个节点周期的向服务器发送心跳(heartbeat),如果服务器在一定时间内没有听到每个节点的心跳就认为它已经死了。

实战

现在我开始简单的实现一下心跳检测
node服务器

var io = require('socket.io')(2333);
var uuid = require('node-uuid');
var static = require('node-static');
var os = require('os');


// keeping track of connections
var sockets = {};
var heartbeat = new Set();
io.on('connection', function(socket) {
    socket.on('getId', function() {
        var id;
        // determine an identifier that is unique for us.
        do {
            id = uuid.v4();
        } while (sockets[id]);

        // we have a unique identifier that can be sent to the client
        console.log("dispatch id:" + id)
        sockets[id] = socket;
        socket.emit('yourId', id);
        heartbeat.add(id);
        console.log("now listeners number is: "+Object.getOwnPropertyNames(sockets).length)
    })
    // heart beats 
    socket.on('heartbeat', function(id){ 
        heartbeat.add(id);
        console.log('hear beat from: ' + id);
    })
})

// sweep the dead socket
setInterval(function(){
    for(var key in sockets) {
        if(!heartbeat.has(key)) {
            delete sockets[key];
        }
    }
    heartbeat.clear();
    console.log("after sweep listeners number is: "+Object.getOwnPropertyNames(sockets).length)
},10000)

vue代码(sockets是vue-socket.io组件里面的东西,基本等同于监听对应消息)

sockets: {
    connect() {
        console.log('connect')
        this.$socket.emit('getId');
    },
    disconnect() {
        console.log('disconnect')
    },
    yourId(id) {
        let self = this;
        this.myId = id;
        console.log('id = ' + id);
        setInterval(function() {
            self.$socket.emit('heartbeat', self.myId)
        },2000)
    },
},

不足

其实这个不完全是心跳,因为清扫节点是周期的而不是每个节点都是10秒1次,也许对于不太实时或者单一客户端的系统这样写还勉强可以,但写完之后我在想这个实时性比较高而且多客户端的模块是不是用ping-echo来做这块会更好

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,773评论 19 139
  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 10,263评论 0 11
  • 这篇文章是我一边学习证书验证一边记录的内容,稍微整理了下,共扯了三部分内容: HTTPS 简要原理;数字证书的内容...
    左边飞来一只狗阅读 8,568评论 2 5
  • 回家了
    Summer的简书阅读 1,059评论 0 0
  • 自从决定自己在家操办一日三餐,减少外卖和外出就餐,我的每个工作日早上本可以慢慢享受早餐的时光,演变成了每一分钟都需...
    在纵情中平凡阅读 4,097评论 0 4