• 【转】java中使用WebSocket


    传统的请求,都是从客服端到服务端,表现在web应用上就是,消息都只能由浏览器发起请求,调用客户端的方法。

    webSocket可以从服务器端推送消息给浏览器。

    使用场景:

      当客户端发起缴费请求时,由服务端发起请求给第三方,跳转到第三方完成支付后,第三方支付回调服务器的接口。在服务端的接口中,推送缴费状态消息给客户端。

    页面前台:

    var websocket = null;
    var host = document.location.host; 
    var username = "${loginUsername}"; // 获得当前登录人员的userName 
     // alert(username)
    //判断当前浏览器是否支持WebSocket 
    if ('WebSocket' in window) { 
        alert("浏览器支持Websocket")
        websocket = new WebSocket('ws://'+host+'/mm-dorado/webSocket/'+username); 
    } else { 
        alert('当前浏览器 Not support websocket') 
    } 
     
    //连接发生错误的回调方法 
    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) {
            document.getElementById('message').innerHTML += innerHTML + '<br/>';
        }

    后端:

    先引包

    <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-api</artifactId>
          <version>7.0</version>
          <scope>provided</scope>
    </dependency>

    代码:

    package com.mes.util;
     
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
     
    import javax.websocket.OnClose;
    import javax.websocket.OnError;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
     
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
     
    import com.google.gson.JsonObject;
     
    import net.sf.json.JSONObject;
    @ServerEndpoint("/webSocket/{username}")  
        public class WebSocket { 
            private static int onlineCount = 0; 
            private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>(); //这里感觉是取巧的方法,用静态的对象来保存连接,然后在下面发送给单个客户端的时候,用传进来的username和To的目标进行字符串的比较
            private Session session; 
            private String username; 
               
            @OnOpen 
            public void onOpen(@PathParam("username") String username, Session session) throws IOException { 
           
                this.username = username; 
                this.session = session; 
                   
                addOnlineCount(); 
                clients.put(username, this);
                System.out.println("已连接");
            } 
           
            @OnClose 
            public void onClose() throws IOException { 
                clients.remove(username); 
                subOnlineCount(); 
            } 
           
            @OnMessage 
            public void onMessage(String message) throws IOException { 
           
                JSONObject jsonTo = JSONObject.fromObject(message); 
                String mes = (String) jsonTo.get("message");
                 
                if (!jsonTo.get("To").equals("All")){ 
                    sendMessageTo(mes, jsonTo.get("To").toString()); 
                }else{ 
                    sendMessageAll("给所有人"); 
                } 
            } 
           
            @OnError 
            public void onError(Session session, Throwable error) { 
                error.printStackTrace(); 
            } 
           
            public void sendMessageTo(String message, String To) throws IOException { 
                // session.getBasicRemote().sendText(message); 
                //session.getAsyncRemote().sendText(message); 
                for (WebSocket item : clients.values()) { 
                    if (item.username.equals(To) ) 
                        item.session.getAsyncRemote().sendText(message); 
                } 
            } 
               
            public void sendMessageAll(String message) throws IOException { 
                for (WebSocket item : clients.values()) { 
                    item.session.getAsyncRemote().sendText(message); 
                } 
            } 
           
            public static synchronized int getOnlineCount() { 
                return onlineCount; 
            } 
           
            public static synchronized void addOnlineCount() { 
                WebSocket.onlineCount++; 
            } 
           
            public static synchronized void subOnlineCount() { 
                WebSocket.onlineCount--; 
            } 
           
            public static synchronized Map<String, WebSocket> getClients() { 
                return clients; 
            } 
    }

    其他类中调用:

    WebSocket ws = new WebSocket();
    JSONObject jo = new JSONObject();
    jo.put("message", "这是后台返回的消息!");
    jo.put("To",invIO.getIoEmployeeUid());
    ws.onMessage(jo.toString());

    原地址:https://www.cnblogs.com/freud/p/8397934.html

    因为http和websocket的协议是不同的,还有一篇,可以在websocket中获取到HttpSession:

    https://www.cnblogs.com/zhuxiaojie/p/6238826.html#autoid-0-0-0

  • 相关阅读:
    python中对一个列表进行乱序
    GPU比CPU慢?可能模型太简单
    VLAN之间单臂路由通信
    数据结构_顺序栈的代码实践
    MarkDown语法学习
    【转载】给想要入门渗透的人的忠告——schiz0wcingU
    SQL注入原理及绕过安全狗
    Python学习---字符串处理
    【转载】RAID写惩罚(Write Penalty)与IOPS计算
    Kali安装使用文泉驿字体
  • 原文地址:https://www.cnblogs.com/amibandoufu/p/10821740.html
Copyright © 2020-2023  润新知