zoukankan      html  css  js  c++  java
  • 手机上的消息推送

    最近在找android手机上的消息推送的解决方案。目前看来有以下几种常用的方式:

    1.定期查询:按照指定的时间间隔连接服务器查询获取最新的消息。实现起来简单,非实时,查询时间过短则流量耗费多,耗电量大。下面是一个爱立信的测试结果:

    2.短信方式:需要及时发送消息给客户端时也可以通过这种方式,但大家都懂的,这个很花钱。

    3.长轮询:基本上与目前很多网站使用的方式一样(WEB阿里旺旺、微博、人人等等)。客户端发起一个很长超时时间的请求,然后服务器端在没有消息的时候阻塞这个请求(一直不给返回值)直到快要超时为止,有消息到来再返回响应。客户端收到响应或超时后立即再发起请求。

    这种算是比较好的方式了,消息能够及时地到达客户端。但考虑到移动互联网的特点(网络不稳定、设备内存小)这种方式不能保证重要的消息一定能推送到客户端,另外anroid在手机内存小的情况下可能会杀这个在等待PUSH消息不怎么活动的进程。

    4.C2DM:GOOGLE提供了消息的PUSH功能,需要和GOOGLE账号绑定,目前看来这种方式在国内是没戏的。

    5.XMPP:在客户端集成asmack,服务器端使用ejabberd或openfire等开源的XMPP服务器软件也是一种可行的方式。

    缺点就是先要有注册、登陆等过程,无线网络环境下连接的效果不怎么样。重要消息的PUSH需要自己实现确认逻辑。

    6.MQTT:基于代理发布/订阅 模式的消息传输协议,适用于受限环境:

        网络代价昂贵、带宽低、不可靠;

        在嵌入设备中运行、处理器和内存资源有限。

    特点是:

       使用发布/订阅模式,解除应用程序耦合;

       对负载内容屏蔽的消息传输;

       使用TCP/IP;

       提供“至多一次”、“至少一次”、“有且仅有一次”三种级别的消息传输;

       小型传输、流量开销少;

       使用LAST WILL 和TESTAMENT特性通知有关各方客户端异常中断机制。

    听起来简直就是为移动互联网设计的

    下面是基于MQTT的简单实现方案:

    服务器:

    可以采用IBM的MQTT服务器RSMB;

    开源的Mosquitto

    客户端:

    IBM的wmqtt.jar 适用于JAVA客户端。

    1.下载安装运行Mosquitto服务器。

    2.在anroid客户端集成以下代码:

    import com.ibm.mqtt.IMqttClient;
    import com.ibm.mqtt.MqttClient;
    import com.ibm.mqtt.MqttException;
    import com.ibm.mqtt.MqttPersistence;
    import com.ibm.mqtt.MqttPersistenceException;
    import com.ibm.mqtt.MqttSimpleCallback;

    public class MQTTConnection implements MqttSimpleCallback{
        IMqttClient mqttClient = null;    
        private static int MQTT_PORT =1883; 
        private static MqttPersistence MQTT_PERSISTENCE=null;
        public static String MQTT_CLIENT_ID ="";
        private static boolean MQTT_CLEAN_START = true;
        private static short MQTT_KEEP_ALIVE = 60 * 15;
        private static int[] MQTT_QUALITIES_OF_SERVICE = { 0 } ;
        private long mStartTime;
            
        public MQTTConnection(String brokerHostName, String initTopic) throws MqttException {
            String mqttConnSpec = "tcp://" + brokerHostName + "@" + MQTT_PORT;
            // Create the client and connect
            mqttClient = MqttClient.createMqttClient(mqttConnSpec, MQTT_PERSISTENCE);
            String clientID = MQTT_CLIENT_ID;
            mqttClient.connect(clientID, MQTT_CLEAN_START, MQTT_KEEP_ALIVE);

            // register this client app has being able to receive messages
            mqttClient.registerSimpleHandler(this);
            
            // Subscribe to an initial topic, which is combination of client ID and device ID.
            subscribeToTopic(initTopic);

            // Save start time
            mStartTime = System.currentTimeMillis();
            // Star the keep-alives
            
    //startKeepAlives();            
        }
        
        private void subscribeToTopic(String topicName) throws MqttException {
            
            if ((mqttClient == null) || (mqttClient.isConnected() == false)) {
                // quick sanity check - don't try and subscribe if we don't have
                
    //  a connection
                System.out.println("subscribe to topic fail");
            } else {                                    
                String[] topics = { topicName };
                mqttClient.subscribe(topics, MQTT_QUALITIES_OF_SERVICE);
            }
        }    
        
        public void disconnect() {
            try {            
                mqttClient.disconnect();
            } catch (MqttPersistenceException e) {
                System.out.println("disconnection to server error");
            }
        }

        
        @Override
        public void connectionLost() throws Exception {
            // TODO Auto-generated method stub
            System.out.println("connection to server closed");
        }

        @Override
        public void publishArrived(String topicName, byte[] payload, int qos, boolean retained)
                throws Exception {
            // TODO Auto-generated method stub
            String s = new String(payload);
            System.out.println("push message recived :"+s);
        }
    }

    3.运行客户端程序,在命令窗口中使用Mosquitto_pub.exe -q [Qos级别] -t [主题] -m [发布的内容] 进行测试。

    另:Mosquitto由于使用socket select 模型,能支持的客户端连接数量有限。

    如果要支持更高并发量,一方面可以考虑采用“策略服务器+Mosquitto集群”的方式,另一方面可以考虑erlang实现的一些MQTT服务器替换Mosquitto(上次见到的一个类似的发布/订阅系统每秒可以完成向40K订阅用户广播的任务,够牛逼了吧)。

  • 相关阅读:
    jmeter主要函数助手功用说明
    性能测试的分类
    monkey基础
    读《复盘-对过去的事情做思维演练—陈中(著)》感知
    关于postman各功能的说明及用法以及批量执行
    python接口测试-认识POST请求
    关于python3.6上传文件时报错:HTTPSConnectionPool(host='***.org', port=443): Max retries exceeded with url: /post (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAIL解决办法
    [Tips] Mobaxterm添加本地python使用
    [Tips] docker run时运行shell命令
    [Tips] shell 输入输出重定向
  • 原文地址:https://www.cnblogs.com/yjl49/p/2506819.html
Copyright © 2011-2022 走看看