计算机系统应用教程网站

网站首页 > 技术文章 正文

socket通信中如何避免实时消息和历史消息重复

btikc 2024-10-29 13:14:18 技术文章 3 ℃ 0 评论

im设计中一般会使用websocket进行通信(netty+socket),为了保留用户的历史消息,消息肯定是需要持久化存储的。那么发送过的消息和socket直接推送的消息之间有可能造成数据重复展示的问题。

个人实现的解决方案有两个

1.socket只推送未度消息,历史消息都通过接口拉取,或者直接服务端推送到socket通道里面。

2.可以在发消息的时候对每一个消息生成一个消息ID,保证唯一性,消息ID的生成可以借鉴推特的雪花算法,maven直接引用依赖可以实现


核心算法如下

public Number generateKey() {
    // 保证当前时间大于最后时间。时间回退会导致产生重复id    long currentMillis = timeService.getCurrentMillis();    Preconditions.checkState(lastTime <= currentMillis,            "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", lastTime,            currentMillis);    // 获取序列号    if (lastTime == currentMillis) {
        if (0L == (sequence = ++sequence & SEQUENCE_MASK)) { // 当获得序号超过最大值时,归0,并去获得新的时间            currentMillis = waitUntilNextTime(currentMillis);        }
    } else {
        // 根据上一次sequence决定本次序列从0还是1开始,保证低并发时奇偶交替        if (lastSequence == 0) {
            sequence = 1L;        } else {
            sequence = 0L;        }
    }
    lastSequence = sequence;    // 设置最后时间戳    lastTime = currentMillis;    // 生成编号    return ((currentMillis - EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS) | (workerId << WORKER_ID_LEFT_SHIFT_BITS)
            | sequence;}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表