消息推送_消息推送服务 - CSDN
精华内容
参与话题
  • 几种消息推送的方案

    千次阅读 2018-04-20 19:48:46
    首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量:现在总结下Android平台下几种推送方案的基本情况以及优缺点:一、使用GCM(Google Cloude Messaging)Android自带的推送GCM可以帮助开发人员给...

    首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量:

    现在总结下Android平台下几种推送方案的基本情况以及优缺点:

    一、使用GCM(Google Cloude Messaging)

    Android自带的推送GCM可以帮助开发人员给他们的Android应用程序发送数据。它是一个轻量级的消息,告诉Android应用程序有新的数据要从服务器获取,或者它可能是一个消息,其中包含了4KB的payload data(像即时通讯这类应用程序可以直接使用该payload消息)。GCM服务处理排队的消息,并把消息传递到目标设备上运行的Android应用程序。

    优点:Google提供的服务、原生、简单,无需实现和部署服务端。

    缺点:1.要求Android 2.2以上,对于不少2.2以前的系统没法推送;

         2.国内服务不稳定。而且不少国内的终端厂商纷纷把Google的服务去掉,替换上自己的。

         3.需要用户绑定Google账号,但不少国内用户没有Google账号。

    二、使用XMPP协议(Openfire+Spark+Smark)

    XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性,有很强的可扩展性。包括上面讲的GCM服务器底层也是采用XMPP协议封装的。

    优点:协议成熟、强大、可扩展性强、目前主要应用于许多聊天系统中,且已有开源的Java版的开发实例androidpn。

    缺点:协议较复杂、冗余(基于XML)、费流量、费电,部署硬件成本高。

    而androidpn(Android Push Notification)就是基于 XMPP 开源组件的一套整合方案,服务端基于Openfire、客户端基于Smack。到AndroidPN项目主页( http://sourceforge.net/projects/androidpn/ ) 下载2个文件: androidpn-server-0.5.0-bin.zip 和 androidpn-client-0.5.0.zip 分别是服务器和客户端的代码。详细的实现方式网上有不少文章。

      1.androidpn服务端重启后客户端不会重连,这个非常悲剧

      2.由于服务器不保存消息,造成了如果客户端当前离线就收不到消息

      3.androidpn发送完消息就不管了,所以没有消息回执报表之类,造成没法做应用后续的数据分析用户体验的改善,这对于企业级的应用是个致命伤。

    XMPP协议比较费电费流量,这个对当前智能机的消耗太大,在窄带网络和不稳定的(手机)网络都不是最优的选择。但总体来说,XMPP协议还是比较成熟的。

    三、使用MQTT协议(想了解更多可以看http://mqtt.org/)

    轻量级的、基于代理的“发布/订阅”模式的消息传输协议。

    优点:协议简洁、小巧、可扩展性强、省流量、省电,目前已经应用到企业领域(参考: http://mqtt.org/software),且已有C++版的服务端组件rsmb。

    缺点:不够成熟、实现较复杂、服务端组件rsmb不开源,部署硬件成本较高。

    四、HTTP轮循方式

    定时向HTTP服务端接口(Web Service API)获取最新消息。

    优点:实现简单、可控性强,部署硬件成本低。

    缺点:实时性差。

    五、采用第三方服务

    就是前面介绍的第三方推送,客户端只需要导入第三方提供的lib库,有第三方管理长连接,负责消息的接收/发送。同时对消息都有比较详细的报表数据,可以用于做数据分析、挖掘,改善用户体验。

    展开全文
  • WebSocket实现消息推送

    千次阅读 2019-07-02 12:12:54
    最近项目中需要实现消息推送需求,首先想到就是用webscket来实现IM,之前了解过这个东西,但是很久没有用了,所以需要来弄个demo热热身,这样在项目中使用的时候,会更靠谱些。先来看一下最后的效果: 一、...

    引言

    最近项目中需要实现消息推送需求,首先想到就是用webscket来实现IM,之前了解过这个东西,但是很久没有用了,所以需要来弄个demo热热身,这样在项目中使用的时候,会更靠谱些。先来看一下最后的效果:

            

    一、Socket简介

    Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。Socket的英文原义是“孔”或“插座”,作为UNIX的进程通信机制。Socket可以实现应用程序间网络通信。

                                         

    其余的一些想它为什么会出现,以及他和我们常用的http协议之间的区别等等,自己百度吧,网上有很多资料,这里我们就不浪费时间了,直接撸代码:

    客户端代码 index.jsp:

    <%@ page language="java" pageEncoding="UTF-8" %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Java后端WebSocket的Tomcat实现</title>
    </head>
    <body>
        Welcome<br/><input id="text" type="text"/>
        <button onclick="send()">发送消息</button>
        <hr/>
        <button onclick="closeWebSocket()">关闭WebSocket连接</button>
        <hr/>
        <div id="message"></div>
    </body>
    
    <script type="text/javascript">
        var websocket = null;
        //判断当前浏览器是否支持WebSocket
        if ('WebSocket' in window) {
            websocket = new WebSocket("ws://localhost:8080/websocket");
        }
        else {
            alert('当前浏览器 Not support websocket')
        }
    
        //连接发生错误的回调方法
        websocket.onerror = function () {
            setMessageInnerHTML("WebSocket连接发生错误");
        };
    
        //连接成功建立的回调方法
        websocket.onopen = function () {
            setMessageInnerHTML("WebSocket连接成功");
        }
    
        //接收到消息的回调方法
        websocket.onmessage = function (event) {
            setMessageInnerHTML(event.data);
        }
    
        //连接关闭的回调方法
        websocket.onclose = function () {
            setMessageInnerHTML("WebSocket连接关闭");
        }
    
        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function () {
            closeWebSocket();
        }
    
        //将消息显示在网页上
        function setMessageInnerHTML(innerHTML) {
            document.getElementById('message').innerHTML += innerHTML + '<br/>';
        }
    
        //关闭WebSocket连接
        function closeWebSocket() {
            websocket.close();
        }
    
        //发送消息
        function send() {
            var message = document.getElementById('text').value;
            websocket.send(message);
        }
    </script>
    </html>

    上面代码实现了浏览器和后端的链接和通信、;

    服务端代码:

    package me.gacl.websocket;
    
    import java.io.IOException;
    import java.net.URI;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;
    
    /**
     * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
     * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
     */
    @ServerEndpoint("/websocket")
    public class WebSocketTest {
        //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
        private static int onlineCount = 0;
    
        //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
        private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
    
        //与某个客户端的连接会话,需要通过它来给客户端发送数据
        private Session session;
    
        /**
         * 连接建立成功调用的方法
         *
         * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
         */
        @OnOpen
        public void onOpen(Session session) {
            this.session = session;
            webSocketSet.add(this);     //加入set中
            addOnlineCount();           //在线数加1
            System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose() {
            webSocketSet.remove(this);  //从set中删除
            subOnlineCount();           //在线数减1
            System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用的方法
         *
         * @param message 客户端发送过来的消息
         * @param session 可选的参数
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            System.out.println("来自客户端的消息:" + message);
    
            //群发消息
            for (WebSocketTest item : webSocketSet) {
                try {
                    item.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
    
        /**
         * 发生错误时调用
         *
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            System.out.println("发生错误");
            error.printStackTrace();
        }
    
        /**
         * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
         *
         * @param message
         * @throws IOException
         */
        public void sendMessage(String message) throws IOException {
            this.session.getBasicRemote().sendText(message);
            //this.session.getAsyncRemote().sendText(message);
        }
    
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        public static synchronized void addOnlineCount() {
            WebSocketTest.onlineCount++;
        }
    
        public static synchronized void subOnlineCount() {
            WebSocketTest.onlineCount--;
        }
    
        public void sends() {
            MyClient client = new MyClient();
            String uri = "ws://localhost:8080/websocket";
            client.start(uri);
            int num = 0;
            try {
                while (true) {
                    Thread.sleep(3 * 1000);
                    num++;
                    client.sendMessage("消息测试" + num);
                    client.closeSocket();
                }
            } catch (Exception e) {
                e.printStackTrace();
    
            }
        }
    }
    

    有这两部分就可以实现消息的发送和接受了,也就是我们发送消息,多个客户端都可以接收到信息

     

    这样实现了基本的交互,但是我们在使用中通常,需要在在另一个服务端生产消息,然后推送给前端页面,下面看一下生产du端代码

    client代码:

    package com.zqf.common.websockt;
    
    import java.io.IOException;
    import java.net.URI;
    
    import javax.websocket.*;
    
    @ClientEndpoint
    public class MyClient {
    
        private Session session;
        @OnOpen
        public void onOpen(Session session) throws IOException {
            this.session = session;
        }
    
        @OnMessage
        public void onMessage(String message) {
        }
    
        @OnError
        public void onError(Throwable t) {
            t.printStackTrace();
        }
        /**
         * 连接关闭调用的方法
         * @throws Exception 
         */
        @OnClose
        public void onClose() throws Exception{
        }
    
        /**
         * 关闭链接方法
         * @throws IOException
         */
        public void closeSocket() throws IOException{
            this.session.close();
        }
    
        /**
         * 发送消息方法。
         * @param message
         * @throws IOException
         */
        public void sendMessage(String message) throws IOException{
            this.session.getBasicRemote().sendText(message);
        }
        //启动客户端并建立链接
        public void start(String uri) {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            try {
                this.session = container.connectToServer(MyClient.class, URI.create(uri));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

     上面代码需要我们引入jar

     <dependency>
                <groupId>javax.websocket</groupId>
                <artifactId>javax.websocket-api</artifactId>
                <version>1.1</version>
                <scope>provided</scope>
            </dependency>

    生产消息代码:

    public void websocket(){
    		MyClient client = new MyClient();
    		String uri = "ws://localhost:8080/websocket";
    		client.start(uri);
    		int num=0;
    		while (true) {
    			try {
    				Thread.sleep(2*1000);
    				num++;
    				client.sendMessage("消息测试" + num);
    
    				System.out.println(num);
    			} catch (Exception e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}

    注意:这里我们需要注意一个坑,就是我们在生产消息的时候,可能我们都习惯直接在main方法中来模拟消息的生产,如果用main方法我们会遇到下面错误:

    如果我们将同样的代码部署在tomcat上就没有问题,查询了一些资料,是因为tomcat中有一个支持websocket的jar,需要导入tomcat bin 目录下的tomcat-juli.jar 到Bootstrap 类加载器对应的实体中,看下面文章

    http://blog.sina.com.cn/s/blog_145f07e7b0102xa7a.html

    小编是直接将生产的代码部署到了tomcat上,毕竟也是非常简单的,在这个阶段先实现功能,不能被这个小问题阻挡,最后顺利实现开始的效果:

      源代码已经放在github上:https://github.com/zhenghaoxiao/java-web-socket

     

    展开全文
  • 【原创】EAWorld2019-03-21 08:31:00 转载本文需注明出处:微信公众号EAWorld,违者必究。 引言: ...而随着各大厂商浏览器版本的迭代,前端技术的不断革新,消息推送用到的场景也越来越多了。 ...

    【原创】 EAWorld 2019-03-21 08:31:00

    浅析web端的消息推送原理

     

    转载本文需注明出处:微信公众号EAWorld,违者必究。

    引言:

    在互联网高速发展的时代里,web应用大有取代桌面应用的趋势,不必再去繁琐的安装各种软件,只需一款主流浏览器即可完成大部分常规操作,这些原因都在吸引着软件厂商和消费者。而随着各大厂商浏览器版本的迭代,前端技术的不断革新,消息推送用到的场景也越来越多了。

    收发邮件提醒,在线IM聊天,自动化办公提示等等,web系统里总是能见到消息推送的应用。消息推送用好了能增强用户体验,用不好则会起相反的效果。在司空见惯的使用过程中,有没有对其中的原理产生兴趣呢?实现消息推送有N种解决方案,本文针对其中的几种,进行原理性的讲解并附有简单的代码实现。

    目录:

    一、什么是消息推送

    二、web端的消息推送

    三、实现个性化的推送

    一、什么是消息推送

    • 经典场景1

    浅析web端的消息推送原理

     

    当我在官网观望犹豫时,突然看到了上面消息,一位神秘的徐老板竟然爆出了麻痹戒指!!我的天,于是我果断开始了游戏!这消息很及时!

    • 经典场景2

    浅析web端的消息推送原理

     

    当我拿起手机不知干嘛时收到了这条招女婿的消息.......瞬间来了精神

    上述两种场景,是生活中很常见的场景,通过图文描述,应该已经清楚了推送的场景,也引出了两大推送种类,web端消息推送和移动端消息推送。接下来对消息推送进行具体的解释。

    • 概念:

    消息推送(Push)指运营人员通过自己的产品或第三方工具对用户当前网页或移动设备进行的主动消息推送。用户可以在网页上或移动设备锁定屏幕和通知栏看到push消息通知。以此来实现用户的多层次需求,使得用户能够自己设定所需要的信息频道,得到即时消息,简单说就是一种定制信息的实现方式。我们平时浏览邮箱时突然弹出消息提示收到新邮件就属于web端消息推送,在手机锁屏上看到的微信消息等等都属于APP消息推送。

    二、web端的消息推送

    这一章节主要对几种消息推送的方式进行原理性的讲解,并贴出简单实现的代码。

    主要介绍其中的五种实现方式:短轮询、Comet、Flash XMLSocket、Server-sent、WebSocket。

    1、短轮询

    指在特定的的时间间隔(如每10秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。浏览器做处理后进行显示。无论后端此时是否有新的消息产生,都会进行响应。字面上看,这种方式是最简单的。这种方式的优点是,后端编写非常简单,逻辑不复杂。但是缺点是请求中大部分中是无用的,浪费了带宽和服务器资源。总结来说,简单粗暴,适用于小型(偷懒)应用。

    基于Jquery的ajax前端代码:

    <body>
     <div id="push"></div>
     <script>
     $(function () {
     setInterval(function () {
     getMsg(function (res) {
     $("#push").append("<p>" + res +"</p>");
     })
     },10000);
     });
    ​
     function getMsg(handler){
     $.ajax({
     url:"/ShortPollingServlet",
     type:"post",
     success:function (res) {
     handler(res)
     }
     });
     }
    </script>
    </body>
    

    servlet简单实现后端代码:

    public class ShortPollingServlet extends HttpServlet {
    ​
     public static int count = 0;
    ​
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     //模拟业务代码
     count++;
     response.getWriter().print("msg:" + count );
     }
    ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     doPost(request,response);
     }
    }
    

    2、Comet

    包括了长轮询和长连接,长轮询是客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求;长连接是在页面中的iframe发送请求到服务端,服务端hold住请求并不断将需要返回前端的数据封装成调用javascript函数的形式响应到前端,前端不断收到响应并处理。Comet的实现原理和短轮询相比,很明显少了很多无用请求,减少了带宽压力,实现起来比短轮询复杂一丢丢。比用短轮询的同学有梦想时,就可以用Comet来实现自己的推送。

    长轮询的优点很明显,在无消息的情况下不会频繁的请求,耗费资小并且实现了服务端主动向前端推送的功能,但是服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。WebQQ(好像挂了)就是这样实现的。

    基于Jquery的ajax前端代码:

    <body>
     <div id="push"></div>
     <script>
     $(function () {
     getMsg();
     });
    ​
     function getMsg() {
     $.ajax({
     url:"/LongPollingServlet",
     type:"post",
     success:function (res) {
     $("#push").append("<p>" + res +"</p>");
     getMsg();
     }
     });
     }
    </script>
    </body>
    

    servlet简单实现后端代码:

    public class LongPollingServlet extends HttpServlet {
    ​
     public static int count = 0;
    ​
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     count++;
     //睡眠时间模拟业务操作等待时间
     double random = Math.round(Math.random()*10);
     long sleepTime = new Double(random).longValue();
     try{
     Thread.sleep(sleepTime*1000);
     response.getWriter().print("msg:" + count + " after " + sleepTime + "seconds servicing");
     }catch (Exception e){
     e.printStackTrace();
     }
    ​
     }
    ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     doPost(request,response);
     }
    }
    

    长连接优点是消息即是到达,不发无用请求,管理起来也相对方便。缺点是服务端维护一个长连接会增加开销。比如Gmail聊天(没用过)就是这样实现的。

    基于Jquery的ajax前端代码:

    <head>
     <title>pushPage</title>
     <script type="text/javascript">
     function loadData(msg) {
     var newChild = document.createElement("p");
     newChild.innerHTML = msg;
     document.getElementById("push").appendChild(newChild);
     }
    </script>
    </head>
    <body>
    <div id="push"></div>
    <iframe src="/LongConnServlet" frameborder="0" name="longConn"></iframe>
    </body>
    

    servlet简单实现后端代码:

    public class LongConnServlet extends HttpServlet {
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     boolean flag = true;
     int i = 0;
     while (flag){
     try {
     //模拟每1秒查询一次数据库,看是否有新的消息可以推送
     Thread.sleep(1*1000);
     }catch (Exception e){
     e.printStackTrace();
     }
    ​
     String pushMsg = "push msg : " + i;
     response.setContentType("text/html;charset=GBK");
     response.getWriter().write("<script type='text/javascript'>parent.loadData('" + pushMsg + "')</script>");
     response.flushBuffer();
     i++;
     if(i==5){
     flag = false;
     }
     }
     }
    ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     doPost(request,response);
     }
    }
    

    3、Flash XMLSocket

    在 HTML 页面中内嵌入一个使用了 XMLSocket 类的 Flash 程序。JavaScript 通过调用此 Flash 程序提供的socket接口与服务器端的socket进行通信。JavaScript 在收到服务器端以 XML 格式传送的信息后可以很容易地控制 HTML 页面的内容显示。

    浅析web端的消息推送原理

    原理示意图(引用http://t.cn/Ex6CYHk)

    利用Flash XML Socket实现”服务器推”技术前提:

    (1)Flash提供了XMLSocket类,服务器利用Socket向Flash发送数据;

    (2)JavaScript和Flash的紧密结合JavaScript和Flash可以相互调用。

    优点是实现了socket通信,不再利用无状态的http进行伪推送。但是缺点更明显:

    1.客户端必须安装 Flash 播放器;

    2.因为 XMLSocket 没有 HTTP 隧道功能,XMLSocket 类不能自动穿过防火墙;

    3.因为是使用套接口,需要设置一个通信端口,防火墙、代理服务器也可能对非 HTTP 通道端口进行限制。

    这种方案在一些网络聊天室,网络互动游戏中已得到广泛使用。不进行代码示例。(可参考http://t.cn/aezSch)

    4、Server-sent

    服务器推指的是HTML5规范中提供的服务端事件EventSource,浏览器在实现了该规范的前提下创建一个EventSource连接后,便可收到服务端的发送的消息,实现一个单向通信。客户端进行监听,并对响应的信息处理显示。该种方式已经实现了服务端主动推送至前端的功能。优点是在单项传输数据的场景中完全满足需求,开发人员扩展起来基本不需要改后端代码,直接用现有框架和技术就可以集成。

    基于HTML5的Server-sent事件:

    <head>
     <title>Title</title>
     <script>
     var source = new EventSource("/ServerSentServlet");//创建一个新的 EventSource对象,
     source.onmessage = function (evt) {//每接收到一次更新,就会发生 onmessage事件
     var newChild = document.createElement("p");
     newChild.innerHTML = evt.data;
     document.getElementById("push").appendChild(newChild);
     }
    </script>
    </head>
    <body>
     <div id="push"></div>
    </body>
    

    servlet简单实现后端代码:

    public class ServerSentServlet extends HttpServlet {
    ​
     public static int count = 0;
    ​
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     count++;
     response.setCharacterEncoding("UTF-8");
     response.setHeader("Content-Type", "text/event-stream");//设置服务器端事件流
     response.setHeader("Cache-Control","no-cache");//规定不对页面进行缓存
     response.setHeader("Pragma","no-cache");
     response.setDateHeader("Expires",0);
     PrintWriter pw = response.getWriter();
     pw.println("retry: 5000"); //设置请求间隔时间
     pw.println("data: " + "msg:" + count +"
    
    ");
     }
    ​
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     doPost(request,response);
     }
    }
    

    5、WebSocket

    WebSocket是HTML5下一种新的协议,是基于TCP的应用层协议,只需要一次连接,便可以实现全双工通信,客户端和服务端可以相互主动发送消息。客户端进行监听,并对响应的消息处理显示。这个技术相信基本都听说过,就算没写过代码,也大概知道干嘛的。通过名字就能知道,这是一个Socket连接,一个能在浏览器上用的Socket连接。是HTML5标准中的一个内容,浏览器通过javascript脚本手动创建一个TCP连接与服务端进行通讯。优点是双向通信,都可以主动发送消息,既可以满足“问”+“答”的响应机制,也可以实现主动推送的功能。缺点就是编码相对来说会多点,服务端处理更复杂(我觉得当一条有情怀的咸鱼就应该用这个!)。

    前端代码:

    <body>
     <div id="push"></div>
    </body>
    <script>
     $(function () {
     var webSocket = new WebSocket("ws://localhost:8080/ws");
     webSocket.onmessage = function (ev) {
     $("#push").append("<p>" + ev.data +"</p>");
     }
     })
    </script>
    

    基于注解简单实现后端代码:

    @ServerEndpoint("/ws")
    public class MyWebSocket {
    ​
     private Session session;
    ​
     public MyWebSocket() {
    ​
     }
    ​
     @OnOpen
     public void onOpen(Session session) {
     this.session = session;
     System.out.println("someone connect");
     int count = 1;
     while (count<=5){
     //睡眠时间模拟业务操作等待时间
     double random = Math.round(Math.random()*10);
     long sleepTime = new Double(random).longValue();
     try {
     Thread.sleep(sleepTime*1000);
     session.getBasicRemote().sendText("msg:" + count +" from server after" + sleepTime + " seconds");
     }catch (Exception e){
     e.printStackTrace();
     }
     count++;
     }
    ​
     }
    ​
     @OnError
     public void onError(Throwable t){
     System.out.println("something error");
     }
    }
    

    以上是对五种推送方式原理的简单讲解和代码的实现。

    三、实现个性化的推送

    上面说了很多原理,也给出了简单的代码实现,但是在实际生产过程中,肯定不能用上面的代码,针对自己系统的应用场景选择合适的推送方案才是合理的,因此最后简单说一下实现个性化推送的两种方式。第一种很简单,直接使用第三方实现的推送,无需复杂的开发运维,直接可以使用。第二种就是自己封装,可以选择如今较为火热的WebSocket来实现系统的推送。

    浅析web端的消息推送原理

     

    1、第三方

    在这里推荐一个第三方推送平台,GoEasy。

    推荐理由是GoEasy的理念符合我们的选择(可参考http://t.cn/Ex6jg3q):

    (1)更简单的方式将消息从服务器端推送至客户端

    (2)更简单的方式将消息从各种客户端推送至客户端

    GoEasy具体的使用方式这里不再赘述,详见官网。对于后端后端开发者,可直接使用Rest方式调用推送,对于前端或web开发者,可以从web客户端用javascript脚本进行调用推送。

    2、封装自己的推送服务

    如果是一个老系统进行扩展,那么更推荐使用Server-sent,服务端改动量不会很大。如果是新系统,更推荐websocket,实现的功能功能更全面。

    我们以websocket为例,不再贴出具体的代码实现。

    我们如果需要使用websocket技术实现自己的推送服务,需要注意哪些点,或者说需要踩哪些坑呢,本文最后列出几点供大家参考:

    长连接的心跳处理;

    从WebSocket中获取HttpSession进行用户相关操作;

    服务端调优实现高并发量client同时在线;

    服务端维持多用户的状态;

    群发消息;

    等等等….

    最后贴出上述代码的git库地址,所有demo均可运行。环境为jdk1.8+tomcat8。

    http://t.cn/Ex6TRVZ

    浅析web端的消息推送原理

     

    关于作者:徐晓明,普元开发工程师,毕业于辽宁科技大学,专注于使用移动开发平台开发app,负责中国邮政集团移动平台项目邮我行app开发和后台开发运维工作。

    关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。

    展开全文
  • 浅谈消息推送功能

    千次阅读 2018-08-06 09:40:39
    消息推送(Push)指运营人员通过自己的产品或第三方工具对用户移动设备进行的主动消息推送。用户可以在移动设备锁定屏幕和通知栏看到push消息通知,通知栏点击可唤起APP并去往相应页面。我们平时在锁屏上看到的微信...

     

    什么是消息推送

    消息推送(Push)指运营人员通过自己的产品或第三方工具对用户移动设备进行的主动消息推送。用户可以在移动设备锁定屏幕和通知栏看到push消息通知,通知栏点击可唤起APP并去往相应页面。我们平时在锁屏上看到的微信消息等等都属于APP消息推送行列。

     

    根据产品形态和业务类型,从大的层面看,可以将消息类型拆分为“IM类”和“非IM类”,非IM类又可以根据其在实际场景中的应用细分以下不同类型:
    IM即时通讯 类

    包括微信、陌陌、qq等。

    非 IM 即时通讯

    新闻资讯类:如网易新闻、今日头条、天天快报等新闻资讯;

    营销活动类:如天猫 APP 预售、大促、满返满减等营销活动信息;

    产品推荐类:如天猫、京东关联产品推荐、新品推荐等基于大数据和算法的个性化推荐;

    系统功能类:如天猫发货到货物流通知、生日祝福提醒、优惠券过期提醒等与个人信息特征或行为属性相关联的系统内消息push。

    消息推送机制运用得好不好,往往会在用户体验,产品功能上对用户形成较大影响。具体说来,消息推送的好坏影响,有以下几点参考:

    好处

    1.信息告知与提醒

    消息推送充当着信息分发渠道的角色,平台方有关产品更新、内容更新、活动消息等内容发布,均可以通过消息推送渠道 push 给用户,能够让用户第一时间知晓此类消息。

    如果是线上活动类、电商大促等促销活动,用户也能第一时间知晓并参与进来。

    2.促进活跃,增强粘性

    消息推送也是用户运营的一块阵地,很多产品把它当作和用户交流与沟通的一道窗口。运用得当的推送消息,能够有效的促进用户活跃,提高用户粘性,让用户时不时打开你的 APP 玩起来。

    3.唤醒沉默用户,提高留存

    有些用户可能玩着玩着就流失了,几个月也不打开一次 APP。通过有趣的推送消息,也许能够唤醒起一部分流失掉的用户。甚至,在用户将要流失之际,作为流失预警机制的一道门阀,防止用户过早流失。

    4.提高功能模块使用率

    当产品更新版本时,可以通过推送消息第一时间提醒用户,引导用户打开并使用新功能,可以提高特定功能模块的使用率。

    坏处

    1.骚扰用户,提高卸载率

    有些运营同学或者是单纯因为 KPI 的压力,或者是对于消息推送没有建立有效的运营策略,也不了解用户的行为习惯,只是单纯地从己方利益出发——只想要更多地提高用户打开 APP 的频率。

    于是,频繁地给用户推送消息,打扰用户,很多时候往往得不偿失,加快用户流失速度,甚至导致用户直接卸载 APP。

    1. 透支信任

    有些运营同学为了吸引用户的注意力,从推送标题上下功夫,想了很多歪门邪道,常常用虚假标题吸引用户,当用户打开 APP 一看内容,发现跟标题描述得相差甚远。

    用户经常会有一种“被骗”的感觉,久而久之,他们明白了你的套路,便不再信任你,当你有真实的内容想要告诉用户时,他们也不再打开了。因为他们潜意识里已经认定——妈的一定又是骗我的!

    3.过多无价值内容,造成用户反感与麻木

    消息推送能够吸引一部分用户打开APP,但是怎样让用户在 APP 内开心地玩起来,并喜欢上你的APP,这是值得思考的问题。

    当然,这取决于很多因素,产品功能层面的,内容价值层面的,视觉美感层面的,交互体验层面的……等等各种因素。

    但有一点很重要,既然是内容的push,那么推送的内容当然得是用户喜闻乐见的,如果大部分内容对用户来说毫无价值,很容易导致用户反感。

    消息推送的时机与场景时机

    这里的时机是指每一天的推送时间段。一般情况下,有这样几个时间段可供参考:

    上午9点–10点:人们刚到公司,一般不会太忙,此时推送消息打开率比较高;中午12点–14点:这个时间段是午休时间,人们一般都会看看资讯啊、新闻啊、玩玩微信啊啥的,在 APP 的使用高峰时段推送消息,打开率也比较高;下午5点–6点:这个时间段人们处于准备下班的状态,比较懒散放松,有时间的话一般会选择玩玩手机,此时推送消息会吸引到用户注意力,不至于被忽略;晚上21点–22点:结束了一天的工作,吃完晚饭终于可以休息了,在人们看新闻资讯、处理聊天内容或者玩游戏的间隔,推送一条消息,打开率妥妥的。

    当然,这些时间段也不是绝对的,肯定也存在例外,这个时间仅做参考。还有一种方法就是——我们可以根据用户的真实使用场景去反推 push 时机。

    什么意思呢,也就是说,将自己代入真实的用户使用场景,比如中午吃饭的时候,你一般会做些什么呢?打开微信处理一下一上午没来得及回复的私信?看看群里面都聊了些啥?打开新闻 APP 看看今天都发生了哪些大事?或者偷偷匹配一下旗鼓相当的对手

    借助真实自己的使用场景,来反推 push 时机,或许能达到不错的效果。

    场景

    这个是什么意思呢,其实是说我们要根据用户的历史行为去分析,在什么样的场景下去进行消息推送是比较合理的。

    举个栗子,某宝的发货到货通知。比如你昨天晚上在某宝上买了个东西,今天早上你想知道这个东西有没有发货,一般情况下你是不是得打开APP去自己查看,但是如果此时,或者发货时APP 给你推送了一条消息“您购买的XXXXXX商品已发货”,就会觉得这个APP用的很舒服

    其他可能的应用场景,比如优惠券到期提醒,生日祝福提醒等,也是一样的道理。

     

    问:IM类和非IM类有什么区别

    答:一个是即时通讯,一个是非即时通讯,简单来说就是一个主要功能是聊天,另一个则不是

    问:如何分辨IM类产品和非IM类产品

    答:从产品的核心功能出发,是否属于即时通讯类产品

    问:为什么说反推用户使用时间比较好

    答:如果你自己也是此类软件的用户,那么更能直观展现出这类产品的一类人群的使用时间

     

    PPT:https://it-xzy.github.io/PM-NEW/2018.8.1.PM-9.html#/

    视频:https://v.qq.com/x/page/e0747roz2li.html

     

    展开全文
  • App消息推送的原理

    千次阅读 2019-04-29 16:19:44
    Android消息推送原理3.1 操作系统有自身的消息推送功能(系统级别)3.2 三种基本的推送方式:Push、Pull 和 SMS3.3 七种主流的Android消息推送方式 1. 基本概念 目的: 在用户未打开App时,App主动向用户推送...
  • 消息推送方案

    千次阅读 2018-11-09 17:20:29
    对于需要即使通知用户的业务,例如告警等,需要消息推送功能,保证通知的及时性。   应用场景需求 消息推送涉及到消息的发送和接收,即方案既要能在后端中使用,也要能在前端和移动端使用,所以需要能适配java 和...
  • 消息推送(一)Comet介绍
  • Android App消息推送 实现原理

    万次阅读 2018-05-14 22:26:33
    https://www.jianshu.com/p/b61a49e0279f1.消息推送的实质实际上,是当服务器有新消息需推送给用户时,先发送给应用App,应用App再发送给用户2. 作用产品角度:功能需要,如:资讯类产品的新闻推送、工具类产品的...
  • 什么是消息推送

    万次阅读 2018-05-09 10:45:08
    今天给大家分享一下,修真院官网pm task9的知识点——什么是消息推送?一.背景介绍1.推送基础移动互联网蓬勃发展的今天,大部分手机 APP 都提供了消息推送功能,如新闻客户端的热点新闻推荐,IM 工具的聊天消息提醒...
  • 消息推送机制原理

    千次阅读 2016-04-22 18:55:47
    在现在的android开发中,为了提高用户 的体验,我们会经常使用到消息推送这样一个功能,但是在一般的开发中我们通常采用极光推送等第三方的框架,来进行推送,那么google本身的推送的原理是什么呢? 首先我们可以定义一个...
  • Android消息推送:第三方消息推送平台详细解析

    万次阅读 多人点赞 2019-04-26 14:04:37
    消息推送在Android开发中应用的场景是越来越多了,比如说电商产品进行活动宣传、资讯类产品进行新闻推送等等,如下图: 本文将介绍Android中实现消息推送的第三方推送的详细解决方案 阅读本文前,建议先阅读我的写...
  • 前几天遇到这样一场景:某一订阅号用户关注后向用户对送这样一提醒,欢迎关注某某订阅号公众号,...当时觉得挺好玩,微信官方提示是禁止向用户主动发送消息的,订阅号每天可向关注用户推送一则文章,服务号则每月可...
  • 最近好像有不少朋友关注Android客户端消息推送的实现,我在之前的项目中用到过Java PC客户端消息推送,从原理讲上应该是一致的,在这里分享一下个人的心得。 消息推送实现原理  这里的消息推送,通常是指由...
  • APP消息推送后端java实现

    万次阅读 2018-08-27 14:43:22
    Java后端实现安卓/IOS移动端消息推送(百度云推送): 转载地址:https://blog.csdn.net/xj80231314/article/details/50338719 极光推送经验之谈-Java后台服务器实现极光推送的两种实现方式: 转载地址:...
  • H5+个推实现消息推送服务

    万次阅读 2020-08-06 15:51:33
    网上看了几篇教程都是比较老的版本了,根据前人的智慧,然后自己摸索了下,简单几步实现了在手机上推送自定义的消息。 首先,在个注册个账号,开发阶段使用个人注册即可,个推注册地址 注册完进入配置页面,对应用...
  • 钉钉消息推送教程

    万次阅读 2017-05-27 17:23:53
    简介在企业里面,消息推送是经常用的技术。比如日志报错、告警列表及时发送消息给相关的负责人,从而快速解决问题,将线上问题尽早解决,那钉钉推送消息,它有什么好处呢?手机钉钉可以及时收到消息,方便处理问题。...
  • 消息推送的几种实现方式

    万次阅读 2017-09-08 15:34:18
    2>通过Internet发送请求消息和响应消息; 3>使用端口接收和发送消息,默认为80端口;但是底层 还是使用Socket完成。...HTTP协议决定了服务器与客户端之间的连接方式,无法直接实现消息推送。 所以就有
  • Java Web 服务器的消息推送 几种方案

    万次阅读 2018-09-29 18:44:31
    简单实现 轮询 前端使用ajax不停的发起请求获取想要的数据(最简单也是最容易耗尽服务器资源) 长连接 ...代码片段:Springboot使用Websocket进行消息推送 DWR ...
  • 根据客户的需求,需要做一个类似淘宝消息推送的功能,客户下订单、订单付款、订单商品已发货,以及客户完成评论,都需要以消息推送提示的方式告知商家和卖家这么一个功能,由于之前没有实现过这方面的功能,所以一时...
  • Android:最全面解析Android消息推送解决方案

    万次阅读 多人点赞 2019-04-26 11:24:00
    鉴于现在运营需求的增强,消息推送在Android开发中应用的场景是十分常见 如电商的活动宣传、资讯类产品进行新闻推送等等 今天,我将全面介绍Android中实现消息推送的7种主流解决方案 目录 1....
1 2 3 4 5 ... 20
收藏数 152,218
精华内容 60,887
关键字:

消息推送