0%

IM - 消息可靠性的解决

当消息下推到客户端的时候,服务端对于推送状态是无感知的。

在用户建立连接的时候,在Channel中缓存并初始化tid0,每一条消息下推的时候,都会设置一个自增tid,并将等待Ack的消息存储在队列中,一旦某个tidAck了就将该消息移出队列。

也有一些情况,比如超过设置的期望时间,还没有Ack,则可以认为该消息丢失了,则启动重新下推的操作。

ACK的数据结构可以定义为:

1
2
3
4
5
6
7
8
9
10
11
@Data
public class Ack {
private long tid;
private String msgId;
}

@Data
public class WaitAckMessage {
private Message message;
private long tid;
}

定义一个AckBuffer来存储ack的信息

1
2
3
4
5
6
7
8
9
10
11
12
public class AckBuffer {
private static Set<Long> set = Sets.newHashSet();

public void acknowledge(Ack ack) {
//可以使用redis的zset来实现
set.remove(ack.getTid());
}

public void addAck(Ack ack) {
set.add(ack.getTid());
}
}