利用AndroidPN,搭建自己的Android推送平台

来源:互联网 发布:如何做淘宝优惠券推广 编辑:程序博客网 时间:2024/04/30 02:43

引言

第一次写博客,本身是小白,也不敢说什么精通了解,只是把自己新学到的东西通过博客作为笔记,以便以后忘记以及作为参考。也把自己的学习心得分享给大家,写的好于不好大家不要见怪,毕竟是新手小白,理解难免会有错误。也请大家取其精华,去其糟粕。举一反三,通过自己的理解再变成自己的技能。废话少说,下面进入正文吧!!!


本文是由郭霖视频见证Android消息推送时刻 学习后的梳理与笔记对于想学习推送的同学可以帮助大家更好的理解视频中的内容,由于视频内容过长,在这里针对每个模块和代码进行简单的解析。和整个流程的概括,帮助大家即使不开视频也能简单的理解和搭建子的消息推送。


通过学习会学到什么

  • 推送的基本原理
  • socket
  • mina框架
  • XMPP协议
  • 心跳、断线、重连
  • 别名和标签消息推送
  • 富媒体消息推送


推送的基本原理

学习推送要简单的理解几个概念:

什么是推送?
推送就是指服务器定向将信息实时发送至客户端的功能

长连接短连接?
长连接就是指客户端与服务器始终建立一个通信连接,在连接没有中断之前,客户端和服务器之间可是随时进行通信。典型例子:socket
短连接是指通讯双方在有数据交互时,就建立一个连接,数据发送完后则断开此连接。典型例子:http

长连接实现及时通讯:推送
短连接实现及时通讯:轮询


推送工作原理图:

推送工作原理图

其实推送和IM有很大的相似,但却比IM要简单一些,毕竟推送只相当于IM的一半流程嘛!
既然讲到了与服务器建立联系那就少不了socket通信,我将简单的利用socket通信的方式发出来大家参考

客户端:

在需要高亮的代码块的前一行及后一行使用三个反引号“`”,同时第一行反引号后面表面代码块所使用的语言,如下:

客户端:

public class SocketClient {    public static final int PORT=9898;    public static void main(String[] args) {        SocketClient client=new SocketClient();        client.run();    }    public void run(){        Socket socket=null;        BufferedReader reader=null;        BufferedReader inputReader=null;        BufferedWriter writer=null;        try {            socket=new Socket(InetAddress.getLocalHost().getHostAddress(),PORT);            reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));            writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));            inputReader=new BufferedReader(new InputStreamReader(System.in));            startServerReplyLinstener(reader);            String inputCountent;            int count=0;            while(!(inputCountent=inputReader.readLine()).equals("bye")){                writer.write(inputCountent);                if (count % 2==0) {                    writer.write("\n");                }                count++;                writer.flush();            }        } catch (UnknownHostException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            try {                socket.close();                writer.close();                reader.close();                inputReader.close();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    public void startServerReplyLinstener(final BufferedReader reader){        new Thread(new Runnable() {            @Override            public void run() {                try {                    String response;                    while((response=reader.readLine())!=null){                        System.out.println(response);                    }                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }).start();    }}

服务器端:

/* * 服务器类 */public class SocketServer {    BufferedWriter writer;    BufferedReader reader;    public static void main(String[] args) {        SocketServer server=new SocketServer();        server.run();    }    public void run(){        ServerSocket serverSocket=null;        Socket socket=null;        try {            serverSocket=new ServerSocket(8181);            System.out.println("server start...");            while(true){                socket=serverSocket.accept();                manageConnection(socket);            }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            try {                serverSocket.close();                socket.close();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    /**     * 管理客户端和服务器的连接     */    public void manageConnection(final Socket socket){        new Thread(new Runnable() {            public void run() {                try {                    System.out.println("client"+socket.hashCode()+"connedted");                    reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));                    writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));                    String receiveMsg;                    while((receiveMsg=reader.readLine())!=null){                        System.out.println("client"+socket.hashCode()+"says: "+receiveMsg);                        writer.write("server says: "+receiveMsg+"\n");                        writer.flush();                    }                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }finally{                    try {                        writer.close();                        reader.close();                    } catch (IOException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }               }        }).start();    }}

mina框架通过Java nio(jdk1.4)技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。帮助我们更方便的去处理服务器与客户端的连接,也是我们本文推送消息中用的框架,针对mina框架的使用主要分4步,下面就举出利用mina框架进行客户端与服务器建立通信

public class MinaClient {    public static void main(String[] args) {        NioSocketConnector connector=new NioSocketConnector();        connector.setHandler(new MyServerHandle());        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));        ConnectFuture future=connector.connect(new InetSocketAddress("127.0.0.1", 9898));        future.awaitUninterruptibly();        IoSession session=future.getSession();        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));        try {            String content;            while(!(content=reader.readLine()).equals("bye")){                session.write(content);            }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

mina框架中,通信的状态与接受消息都是通过Handle(),然后调用connector.setHandler(new MyServerHandle()); 其中MyServerHandle()需要继承IoHandlerAdapter,然后调用 connector.getFilterChain()去设置一个过滤器来处理消息。这里只是简单的创建一个文本过滤器也可以自定义自己的过滤器,最后通过ConnectFuture future=connector.connect(new InetSocketAddress(“127.0.0.1”, 9898));制定服务器的地址和端口号。

服务器端这里问了节省篇幅在这里我就不写了 具体的逻辑代码可以去我的github上去参考下


XMPP协议的简单理解

相信大家通过简单了解,大家对socket和mina框架都有了简单了解(其实我也不写什么,具体看代码,代码中重要的部分也有注释,有过有时间的也可以去看看视频,连我这么笨的都一看都懂,相信大家学起来也不会浪费太多时间),那么接下来就简单的了解下XMPP协议。

对于理解xmpp的人来说这里也不用看了,我本身也是一点不懂的,通过视频的学习,我对xmpp也有了简单的理解,这里只是把我笔记分享个大家

XMPP协议解析

概念:
可扩展消息和展示协议。是一种以XML为基础的开放式实时通信的协议。它将需要实时通信的消息嵌入到XML结构体当中,不仅具有很好的可扩展性,还有较强的可读性。

  • XMPP的优点
    • 开放性
    • 可扩展
    • 跨平台
    • 标准性
  • 缺点:
    • 数据冗余
    • 不支持二进制数据

XMPP 传输 是通过 XML Stanzas
XMPP的身份标识 每个客户端是使用JID来作为身份标识的:
[user”@”]domain[“/”resource]

一写简单的理解请访问我的学习笔记,这里就不浪费过多的篇幅了。笔记地址


本来是想发个AndroidPN的源码解析的流程图的但是想想既然都看到这里了,说明大家都是真的想学习,那么估计都去看视频了,那我就不在这里班门弄斧了,我把我整个完成的客户端和服务器的代码地址发出来,不管你是学习,参考找错误,还是直接开发集成项目都是可以的,项目地址AndroidPN-XMPP 项目介绍里面会有简单的简介和流程图分析,这里就不发流程图了。