引用此评论
引用:JackJiang 发表于 2017-06-07 12:01 看样子你改过源码,而且出错的原因很明显,应该是有什么地方改动的不对。 你可以描述一下你大致改动了什 ...
/* * Copyright (C) 2016 即时通讯网(52im.net) The MobileIMSDK Project. * All rights reserved. * Project URL:[url=https://github.com/JackJiang2011/MobileIMSDK]https://github.com/JackJiang2011/MobileIMSDK[/url] * * 即时通讯网(52im.net) - 即时通讯技术社区! PROPRIETARY/CONFIDENTIAL. * Use is subject to license terms. * * QoS4SendDaemonS2C.java at 2016-2-20 11:26:03, code by Jack Jiang. * You can contact author with [url=mailto:jack.jiang@52im.net]jack.jiang@52im.net[/url] or [url=mailto:jb2011@163.com]jb2011@163.com[/url]. */ package net.openmob.mobileimsdk.server.qos; //import java.awt.event.ActionEvent; //import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; //import javax.swing.Timer; import net.openmob.mobileimsdk.server.ServerLauncher; import net.openmob.mobileimsdk.server.protocal.Protocal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class QoS4SendDaemonS2C { private static Logger logger = LoggerFactory.getLogger(QoS4SendDaemonS2C.class); public static boolean DEBUG = false; public static final int CHECH_INTERVAL = 5000; public static final int MESSAGES_JUST$NOW_TIME = 2000; public static final int QOS_TRY_COUNT = 1; private ServerLauncher serverLauncher = null; private ConcurrentHashMap<String, Protocal> sentMessages = new ConcurrentHashMap<String, Protocal>(); private ConcurrentHashMap<String, Long> sendMessagesTimestamp = new ConcurrentHashMap<String, Long>(); private boolean running = false; private boolean _excuting = false; // private Timer timer = null; private static QoS4SendDaemonS2C instance = null; public static QoS4SendDaemonS2C getInstance() { if (instance == null) instance = new QoS4SendDaemonS2C(); return instance; } private QoS4SendDaemonS2C() { init(); } private void init() { // this.timer = new Timer(CHECH_INTERVAL, new ActionListener() // { // public void actionPerformed(ActionEvent e) { // QoS4SendDaemonS2C.this.run(); // } // }); } public void run() { // 极端情况下本次循环内可能执行时间超过了时间间隔,此处是防止在前一 // 次还没有运行完的情况下又重复执行,从而出现无法预知的错误 if (!this._excuting) { ArrayList<Protocal> lostMessages = new ArrayList<Protocal>(); this._excuting = true; try { if (DEBUG) { logger.debug("【IMCORE】【QoS发送方】=========== 消息发送质量保证线程运行中, 当前需要处理的列表长度为" + this.sentMessages.size() + "..."); } for (String key : this.sentMessages.keySet()) { Protocal p = (Protocal)this.sentMessages.get(key); if ((p != null) && (p.isQoS())) { if (p.getRetryCount() >= QOS_TRY_COUNT) { if (DEBUG) { logger.debug("【IMCORE】【QoS发送方】指纹为" + p.getFp() + "的消息包重传次数已达" + p.getRetryCount() + "(最多" + QOS_TRY_COUNT + "次)上限,将判定为丢包!"); } lostMessages.add((Protocal)p.clone()); remove(p.getFp()); } else { //### 2015104 Bug Fix: 解决了无线网络延较大时,刚刚发出的消息在其应答包还在途中时被错误地进行重传 long delta = System.currentTimeMillis() - sendMessagesTimestamp.get(key); // 该消息包是“刚刚”发出的,本次不需要重传它哦 if(delta <= MESSAGES_JUST$NOW_TIME) { if(DEBUG) logger.warn("【IMCORE】【QoS发送方】指纹为"+key+"的包距\"刚刚\"发出才"+delta +"ms(<="+MESSAGES_JUST$NOW_TIME+"ms将被认定是\"刚刚\"), 本次不需要重传哦."); } //### 2015103 Bug Fix END else { boolean sendOK = ServerLauncher.sendData(p); p.increaseRetryCount(); if (sendOK) { if (DEBUG) { logger.debug("【IMCORE】【QoS发送方】指纹为" + p.getFp() + "的消息包已成功进行重传,此次之后重传次数已达" + p.getRetryCount() + "(最多" + 1 + "次)."); } } else if (DEBUG) { logger.warn("【IMCORE】【QoS发送方】指纹为" + p.getFp() + "的消息包重传失败,它的重传次数之前已累计为" + p.getRetryCount() + "(最多" + 1 + "次)."); } } } } else { remove(key); } } } catch (Exception eee) { if (DEBUG) { logger.warn("【IMCORE】【QoS发送方】消息发送质量保证线程运行时发生异常," + eee.getMessage(), eee); } } if ((lostMessages != null) && (lostMessages.size() > 0)) { notifyMessageLost(lostMessages); } this._excuting = false; } } protected void notifyMessageLost(ArrayList<Protocal> lostMessages) { if ((this.serverLauncher != null) && (this.serverLauncher.getServerMessageQoSEventListener() != null)) this.serverLauncher.getServerMessageQoSEventListener().messagesLost(lostMessages); } public QoS4SendDaemonS2C startup(boolean immediately) { stop(); // if (immediately) // this.timer.setInitialDelay(0); // else // this.timer.setInitialDelay(CHECH_INTERVAL); // // this.timer.start(); // this.running = true; return this; } public void stop() { // if (this.timer != null) { // this.timer.stop(); // } this.running = false; } public boolean isRunning() { return this.running; } public boolean exist(String fingerPrint) { return this.sentMessages.get(fingerPrint) != null; } public void put(Protocal p) { if (p == null) { if (DEBUG) logger.warn("Invalid arg p==null."); return; } if (p.getFp() == null) { if (DEBUG) logger.warn("Invalid arg p.getFp() == null."); return; } if (!p.isQoS()) { if (DEBUG) logger.warn("This protocal is not QoS pkg, ignore it!"); return; } if (this.sentMessages.get(p.getFp()) != null) { if (DEBUG) { logger.warn("【IMCORE】【QoS发送方】指纹为" + p.getFp() + "的消息已经放入了发送质量保证队列,该消息为何会重复?(生成的指纹码重复?还是重复put?)"); } } // save it sentMessages.put(p.getFp(), p); // 同时保存时间戳 sendMessagesTimestamp.put(p.getFp(), System.currentTimeMillis()); } public void remove(String fingerPrint) { //### 20151129 Bug Fix: 解决了之前错误地在服务端实现本remove方法时 // 使用了SwingWorker而导致一段时间后一定几率下整个Timer不能正常工作了(OOM) try { // remove it sendMessagesTimestamp.remove(fingerPrint); Object result = sentMessages.remove(fingerPrint); if(DEBUG) logger.warn("【IMCORE】【QoS发送方】指纹为"+fingerPrint+"的消息已成功从发送质量保证队列中移除(可能是收到接收方的应答也可能是达到了重传的次数上限),重试次数=" +(result != null?((Protocal)result).getRetryCount():"none呵呵.")); } catch (Exception e) { if(DEBUG) logger.warn("【IMCORE】【QoS发送方】remove(fingerPrint)时出错了:", e); } //### 20151129 Bug Fix END } public int size() { return this.sentMessages.size(); } public void setServerLauncher(ServerLauncher serverLauncher) { this.serverLauncher = serverLauncher; } }
Copyright © 2014-2024 即时通讯网 - 即时通讯开发者社区 / 版本 V4.4
苏州网际时代信息科技有限公司 (苏ICP备16005070号-1)
Processed in 0.109373 second(s), 25 queries , Gzip On.