`

smack 源码分析- PacketWriter (android上实现长连接)

 
阅读更多

上一篇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 楼 dd18349182956 2016-09-19  
你这是哪个版本的smack?

相关推荐

    Android使用smack连接ejabberd服务器注册、收发消息

    implementation 'org.igniterealtime.smack:smack-android-extensions:4.3.5' implementation 'org.igniterealtime.smack:smack-tcp:4.3.5' implementation 'org.igniterealtime.smack:smack-im:4.3.5' ...

    smack-resolver-dnsjava-4.0.0-rc2.zip

    综上所述,"smack-resolver-dnsjava-4.0.0-rc2.zip" 包含了 Smack 的一个版本,它利用 DNSJava 实现了对 XMPP 服务器的智能解析。同时,描述中的 Peon 可能是一个辅助 XMPP 服务器管理的工具,同样使用 Java 编写。...

    smack-resolver-javax-4.1.0-alpha6.zip

    标题中的"smack-resolver-javax-4.1.0-alpha6.zip"是一个软件库的压缩包,Smack是一款开源的XMPP客户端库,而"javax"可能指的是它提供了与Java平台兼容的解析器组件。这个版本是4.1.0的Alpha6,意味着它是一个开发...

    smack4.1.6连接openfire,tigase,ejabberd所需jar包

    jxmpp-core-0.5.0-alpha7 jxmpp-util-cache-0.5.0-alpha7 smack-android-4.1.6 smack-core-4.1.6 smack-extensions-4.1.6 smack-im-4.1.6 smack-sasl-provided-4.1.6 smack-tcp-4.1.6

    smack-resolver-minidns-4.1.0-alpha3.jar

    smack4.1.0的依赖包minidns.jar。可用于smack4.1.3,亲测可用!

    smack-core-4.0.0.zip

    本压缩包"smack-core-4.0.0.zip"包含了Smack Core 4.0.0版本的源代码,这是一个著名的Java即时通讯(Instant Messaging)库,主要用于实现XMPP协议。Smack为开发者提供了丰富的API,使得构建XMPP应用变得更加便捷。 ...

    android smack源码

    **Android Smack源码解析** ...总之,Android Smack源码是一个深入了解XMPP协议和即时通讯实现的宝贵资源,对于需要构建IM应用的开发者来说,深入研究这个库将大大提升他们的专业技能和解决问题的能力。

    smack-jar Android

    总之,Smack-JAR是Android开发者构建即时通讯应用的强大工具,通过理解和熟练运用其API,可以实现丰富的通讯功能,如一对一聊天、群聊、文件传输等。同时,还需要关注Android平台的特性,确保应用的稳定性和用户体验...

    smack4.3.1

    总结,Smack 4.3.1是一个强大的Android即时通讯框架,它为开发者提供了实现XMPP协议所需的全部工具,通过合理的使用和配置,可以构建出高效、稳定的IM应用。结合Openfire等服务器,可以构建出企业级的通讯解决方案。

    android smack客户端

    implementation 'org.igniterealtime.smack:smack-android-extensions:4.4.3' implementation 'org.igniterealtime.smack:smack-tcp:4.4.3' implementation 'org.igniterealtime.smack:smack-im:4.4.3' ...

    android_smack4.1.9-demo

    自4.1.0版本起,Smack开始全面支持Android平台,使得开发者能够方便地在Android设备上构建功能丰富的聊天应用程序。在"android_smack4.1.9-demo"项目中,我们能看到如何在Android Studio环境下集成并使用Smack 4.1.9...

    smack-1.0-master

    这个"smack-1.0-master"压缩包包含的是Smack工具的源代码,主要版本为1.0,并且经过了特定的修改,能够支持`.smackcipso`、`smackload`、`smackaccess`和`smackctl`等工具的使用。下面将详细介绍这些工具和Smack系统...

    smack-extensions-4.1.0-alpha3.zip

    【标题】"smack-extensions-4.1.0-alpha3.zip" 提供的是 Smack 开源库的一个扩展包,版本为4.1.0的Alpha3版本。Smack 是一个用于XMPP(Extensible Messaging and Presence Protocol)的Java库,它允许开发者在Java...

    Android-Openfire-Smack4.1.2 (Android Studio)

    implementation 'org.igniterealtime.smack:smack-android-extensions:4.3.5' implementation 'org.igniterealtime.smack:smack-tcp:4.3.5' implementation 'org.igniterealtime.smack:smack-extensions:4.3.5' }...

    Smack源码,很有用

    通过分析和学习Smack源码,不仅可以掌握XMPP协议的实现细节,还能提升对Java网络编程、XML处理、事件驱动编程的理解,为开发实时通信应用打下坚实基础。同时,这也有助于理解其他基于XMPP的项目,如ejabberd服务器或...

    smack-im-4.3.4-sources_www.im.43_im_

    【标题】"smack-im-4.3.4-sources_www.im.43_im_" 指的是 Smack IM 的4.3.4版本的源代码,这个开源项目主要关注即时通讯(IM)功能的实现。Smack是一个用Java编写的库,允许开发者在他们的应用程序中集成XMPP...

    asmack-android-16-source-beem.zip

    asmack-android-16-beem.jar是一个编译后的Java类库,而这里的源码提供了一窥其实现细节的机会,对于开发者来说,这有助于理解Beem如何利用Asmack在Android平台上实现其功能。 标签“asmack”,“android 16”,...

Global site tag (gtag.js) - Google Analytics