websocket 消息推送

2019-10-12  本文已影响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>
上一篇下一篇

猜你喜欢

热点阅读