上一篇smack 源码分析一(android上实现长连接) 整体分析了smack长连接的流程, 本篇将详细介绍PacketWriter.

PacketWriter是在上篇在介绍initConnection()方法中创建的,那么详细看下PacketWriter的实现:

protected PacketWriter(XMPPConnection connection) {        this.queue = new ArrayBlockingQueue<Packet>(500, true);        this.connection = connection;        init(); }protected void init() {        this.writer = connection.writer;        done = false;        lastActive = System.currentTimeMillis();                //开辟一个写网络流数据线程        writerThread = new Thread() {            public void run() {                writePackets(this);            }        };        writerThread.setName("Smack Packet Writer (" + connection.connectionCounterValue + ")");        writerThread.setDaemon(true);    }/**     * 向网络流写数据包     * @param thisThread     */    private void writePackets(Thread thisThread) {        try {            // Open the stream.            openStream();            // Write out packets from the queue.            while (!done && (writerThread == thisThread)) {                Packet packet = nextPacket();                if (packet != null) {                    synchronized (writer) {                        writer.write(packet.toXML());                        writer.flush();                        // Keep track of the last time a stanza was sent to the                        // server                        lastActive = System.currentTimeMillis();                    }                }            }            synchronized (writer) {                while (!queue.isEmpty()) {                    Packet packet = queue.remove();                    writer.write(packet.toXML());                }                writer.flush();            }            queue.clear();            writer.write("</stream:stream>");            writer.flush();        } catch (IOException ioe) {            if (!done) {                done = true;                connection.packetReader.notifyConnectionError(ioe);            }        } finally {            try {                if (writer != null) {                    writer.close();                }            } catch (Exception e) {            }        }    }

在PacketWriter构造方法中传递参数XMPPConnection作为PacketWriter成员变量, 然后调用init()方法 ,而在init()方法中, 开辟一个线程专门用于向服务器写数据. writerPackets()里面是一个无限循环体, 不断的从消息队列queue读取pakcet消息读取完之后调用wirter.flush()方法, 将消息发送的服务器. 这个过程就完成了终端完服务器发送消息的过程.

接下来是, 终端如何与云端保持连接呢, 那肯定是发送心跳包咯. 我们来看下PacketWriter是如何发送心跳包的:

/**     * A TimerTask that keeps connections to the server alive by sending a space     * character on an interval.     */    private class KeepAliveTask implements Runnable {        private int delay;        private Thread thread;        public KeepAliveTask(int delay) {            this.delay = delay;        }        protected void setThread(Thread thread) {            this.thread = thread;        }                public void run() {            try {                // Sleep 15 seconds before sending first heartbeat. This will give time to                // properly finish TLS negotiation and then start sending heartbeats.                Thread.sleep(15000);            }            catch (InterruptedException ie) {                // Do nothing            }            while (!done && keepAliveThread == thread) {                synchronized (writer) {                    // Send heartbeat if no packet has been sent to the server for a given time                    if (System.currentTimeMillis() - lastActive >= delay) {                        try {                            writer.write(" ");                            writer.flush();                        }                        catch (Exception e) {                            // Do nothing                        }                    }                }                try {                    // Sleep until we should write the next keep-alive.                    Thread.sleep(delay);                }                catch (InterruptedException ie) {                    // Do nothing                }            }        }    }

心跳发送类: KeepAliveTask 是一个自定义线程, 它定义了心跳发送的时间间隔, 在其run方法里面一个无限循环体每隔delay毫秒就向云端发发送一个空消息(当然, 如需要你可以根据项目需求自定义一个心跳包). 整个PacketWriter介绍基本到此结束, 在你应用登陆成功之后就可以开启KeepAliveTask 线程定时发送心跳包到服务器保持终端与服务器的长连接.

更多相关文章

  1. Android错误解决方法大集合
  2. Android(安卓)Activity之间传递图片(Bitmap)的方法
  3. android 视频播放器的制作
  4. Android中WebView获取网页中标题 ,内容, 图片的方法
  5. Android的onCreateOptionsMenu()创建菜单Menu详解
  6. 【android】ORMLite框架 的使用方法---给你的数据库操作插上翅膀
  7. Android面试题整理(一)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Handler 源码解析——Handler的创建
  2. RelativeLayout相对布局中的属性
  3. Android调用系统短信发送界面并预设接收
  4. Android快速开发不可或缺的11个工具类(下
  5. Android中对多媒体操作阶段总结
  6. Android 多模拟器使用adb shell
  7. Android 10 定位问题,获取NMEA(支持5.0~10.
  8. 2017 github 上android 源码(适合工作中开
  9. Android(安卓)Signature V2 Scheme签名下
  10. android intent 及 intent action全面描