美文网首页
websocket 消息推送

websocket 消息推送

作者: 不想明明 | 来源:发表于2019-10-12 17:04 被阅读0次

    实现web端的推送目前有几种方式:

    * 轮询

    客户端定时向服务器发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接。

    优点:后端程序编写简单

    缺点:请求中有大多是无用的,浪费带宽和服务器资源。

    示例:适用于小型应用

    * websocket

    WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    优点:节省服务器资源和带宽,实时进行通信

    缺点:少部分浏览器不支持,且不同浏览器支持的程度和方式有区别

    image.png

    那么接下来说明一下自己写的一个超简单的demo,关于接收消息的一些逻辑控制未写入代码,此处只做简单的推送功能展示。

    1、服务端

    * 引入jar包:

    敲重点:注意scope作用域, provided--在编译和测试的过程有效,最后生成war包时不会加入

    <!-- 引入websocket -->
    
    <dependency>
    
        <groupId>javax.websocket</groupId>
    
        <artifactId>javax.websocket-api</artifactId>
    
        <version>1.1</version>
    
        <scope>provided</scope>
    
    </dependency>
    
    <dependency>
    
        <groupId>javax</groupId>
    
        <artifactId>javaee-api</artifactId>
    
        <version>7.0</version>
    
        <scope>provided</scope>
    
    </dependency>
    

    * 消息处理类(注意前后端websocket对象是同一个)

    
    import javax.websocket.*;
    
    import javax.websocket.server.ServerEndpoint;
    
    import java.io.IOException;
    
    @ServerEndpoint("/websocket/endpoint")
    
    public class WebsocketHandler {
    
        private static Map<String, WebsocketHandler> clients = new ConcurrentHashMap<String, WebsocketHandler>();
    
        @OnOpen
    
        public void onOpen(Session session) throws IOException {
    
            //如果有用户信息,可以将用户编码之类的唯一标识作为clients的key,这样可以保证一个用户只有一个websocket client有效(此处的“1”仅仅作为demo的测试例子)
    
            //如果同一个用户可以拥有多个websocket client,可以将session.getId()作为key,根据实际业务需求来设置即可
    
            clients.put("1", this);
    
            System.out.println("已连接");
    
        }
    
        @OnMessage
    
        public void onMessage(String message) {
    
            //以下代码省略...
    
            System.out.println(message);
    
            for (WebsocketHandler client : clients.values()) {
    
                client.session.getBasicRemote().sendText(message);
    
            }
    
        }
    
        @OnError
    
        public void onError(Throwable t) {
    
            //以下代码省略...
    
            t.printStackTrace();
    
        }
    
        @OnClose
    
        public void onClose(Session session, CloseReason reason) {
    
            //以下代码省略...
    
            System.out.println(String.format("Session %s closed because of %s", session.getId(), reason));
    
            System.out.println("已关闭连接");
    
        }
    
        public static void pushMsg(String message){
    
            // “1”只是测试用的key
    
            WebsocketHandler client = clients.get("1");
    
            try {
    
                if(client != null){
    
                    client.session.getBasicRemote().sendText(message);
    
                }
    
            }catch (IOException e){
    
                e.printStackTrace();
    
            }
    
        }
    
    }
    

    * 后端对外消息推送接口

    
    @ResponseBody
    
    @RequestMapping(value="/sendMessage", method = RequestMethod.GET)
    
    public void sendMessage() throws IOException {
    
        WebsocketHandler.pushMsg("这是我需要发送的消息,记得给我传达,后面可以做成通用的接口");
    
    }
    

    2、客户端

    
    <!-- html -->
    
    <button onclick="sendMessage()">发送消息</button>
    
    <button onclick="closeWebSocket()">关闭</button>
    
    <div>这是显示结果的地方:
    
        <p id="message" style="color:red;"></p>
    
    </div>
    
    <!-- javascript -->
    
    <script type="text/javascript" src="../js/jquery-1.9.1.min.js"></script>
    
    <script type="text/javascript">
    
        var websocket = null;
    
        var url = "ws://localhost:8081/websocket-demo/websocket/endpoint";
    
        $(document).ready(function(){
    
            //判断当前浏览器是否支持WebSocket
    
            if ('WebSocket' in window) {
    
                alert("浏览器支持Websocket")
    
                websocket = new WebSocket(url);
    
            } else {
    
                alert('当前浏览器 Not support websocket');
    
            }
    
            if(websocket != null){
    
                //连接发生错误的回调方法
    
                websocket.onerror = function() {
    
                    alert("WebSocket连接发生错误")
    
                    setMessageInnerHTML("WebSocket连接发生错误");
    
                };
    
                //连接成功建立的回调方法
    
                websocket.onopen = function() {
    
                    alert("WebSocket连接成功")
    
                    setMessageInnerHTML("WebSocket连接成功");
    
                }
    
                //接收到消息的回调方法
    
                websocket.onmessage = function(event) {
    
                    alert("接收到消息的回调方法")
    
                    alert("这是后台推送的消息:"+event.data);
    
                    // websocket.close();
    
                    // alert("webSocket已关闭!")
    
                }
    
                //连接关闭的回调方法
    
                websocket.onclose = function() {
    
                    setMessageInnerHTML("WebSocket连接关闭");
    
                }
    
            }
    
        });
    
        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    
        window.onbeforeunload = function() {
    
            closeWebSocket();
    
        }
    
        //关闭WebSocket连接
    
        function closeWebSocket() {
    
            websocket.close();
    
        }
    
        //将消息显示在网页上
    
        function setMessageInnerHTML(innerHTML) {
    
            $("#message").text(innerHTML);
    
        }
    
    </script>
    

    相关文章

      网友评论

          本文标题:websocket 消息推送

          本文链接:https://www.haomeiwen.com/subject/fbzqmctx.html