OpenFire源码学习之二十五:消息回执与离线消息(下)

本文介绍了OpenFire中消息回执和离线消息的处理方案,包括使用Redis存储消息、客户端回执操作、离线消息优化及通信协议。详细阐述了消息存储格式、离线消息的获取策略以及Redis的资源管理策略。
摘要由CSDN通过智能技术生成

这一篇紧接着上面继续了。

方案二

基于redis的消息回执。主要流程分为下面几个步骤:

1)将消息暂存储与redis中,设置好消息的过期时间

2)客户端回执消息id来消灭暂存的消息

3)开通单独线程论坛在第1)步中的消息。根据消息的时间重新发送消息。如果消息第一次存放的时间大雨有效期(自定义10秒),解析消息中的to查找用户是否还在线。如果在则T掉(因为它长时间不理会服务的重要命令),如果不在线则将消息放置离线表。

 

OK,先来看看消息的存储格式吧。

1.MESSAGE消息 用户集合

 SADD  SOGU:[username]  [VALUE(messageID)] [VALUE(messageID)] ...

2.已读消息设备集合

 SADD  RT:[terminalid]  [VALUE(messageID)] [VALUE(messageID)] ...

3.消息内容

 HMSET  OGM:[messageID]  CREATIONDATE [VALUE]  UPDATEDATE [VALUE] STANZA [VALUE]

4.用户、设备关联

 SADD URT:[USERNAME]  [VALUE(terminalid)] .......

(先根据消息id查找时间,在java中排序后 查找stanza)

MESSAGE

--离线表

ZADD OFOFFLINE:[username]  [INDEX(时间戳)] [VALUE(messageID)] 、[VALUE]、[VALUE]......              [VALUE]

HMSET OFOFFLINE:[messageID] STANZA[VALUE]

        CREATIONDATE [VALUE]  MESSAGESIZ[VALUE]

 

将消息暂时消息存储:

    public void storeMessage(String username, Packet packet) {
    	
		Jedis jedis = XMPPServer.getInstance().getGroupRedisManager().getJedis();
    	String packetID = "";
    	if (packet instanceof Message) 
    		packetID = ((Message)packet).getID();
   		else if (packet instanceof IQ) 
   			 packetID = ((IQ)packet).getID();
   		else 
   			return;
    	
    	try {
    		jedis.sadd("SOGU:" + username, packetID);
        	Map<String, String> hash = new HashMap<String, String>();
        	hash.put("STANZA", packet.toXML());
        	hash.put("CREATIONDATE", StringUtils.dateToMillis(new Date()));
        	jedis.hmset("OGM:" + packetID, hash);
		} finally {
			XMPPServer.getInstance().getGroupRedisManager().returnRes(jedis);
		}
    	
    	htp.execute(addMessagesToDB(packet));
    }
    
    private Runnable addMessagesToDB(final Packet packet) {
    	return new Runnable() {
			@Override
			public void run() {
				MyDBopt.insertMessage(packet);
			}
		

客户端收到消息来回执服务端的操作

    private void handle(IQ packet) {
    	JID recipientJID = packet.getTo();
    	if (IQ.Type.crs != packet.getType()) {
            // Check if the packet was sent to the server hostname
            if (recipientJID != null &
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值