websoket服務端主動推進消息客戶端

WebSocket是HTML5開始提供的一種瀏覽器與服務器間進行全雙工通信的網絡技術。依靠這種技術能夠實現客戶端和服務器端的長鏈接,雙向實時通訊。
特色:
事件驅動
異步
使用ws或者wss協議的客戶端socketjava

可以實現真正意義上的推送功能web

缺點:數組

少部分瀏覽器不支持,瀏覽器支持的程度與方式有區別。瀏覽器

3、WebSocket客戶端

websocket容許經過JavaScript創建與遠程服務器的鏈接,從而實現客戶端與服務器間雙向的通訊。在websocket中有兩個方法:  
    一、send() 向遠程服務器發送數據
    二、close() 關閉該websocket連接
  websocket同時還定義了幾個監聽函數    
    一、onopen 當網絡鏈接創建時觸發該事件
    二、onerror 當網絡發生錯誤時觸發該事件
    三、onclose 當websocket被關閉時觸發該事件
    四、onmessage 當websocket接收到服務器發來的消息的時觸發的事件,也是通訊中最重要的一個監聽事件。msg.data
  websocket還定義了一個readyState屬性,這個屬性能夠返回websocket所處的狀態:
    一、CONNECTING(0) websocket正嘗試與服務器創建鏈接
    二、OPEN(1) websocket與服務器已經創建鏈接
    三、CLOSING(2) websocket正在關閉與服務器的鏈接
    四、CLOSED(3) websocket已經關閉了與服務器的鏈接安全

  websocket的url開頭是ws,若是須要ssl加密可使用wss,當咱們調用websocket的構造方法構建一個websocket對象(new WebSocket(url))的以後,就能夠進行即時通訊了。服務器

<script type="text/JavaScript">
    function init() {
         var websocket = null;
          var loginuserid=$("#userid").val();
          console.log(loginuserid);
          var strs= new Array(); //定義一數組
          //判斷當前瀏覽器是否支持WebSocket
          if('WebSocket' in window){
              websocket = new WebSocket("ws://110.56.17.4/websocket?"+loginuserid);
          }
          else{
              alert('Not support websocket');
          }
     
          //鏈接發生錯誤的回調方法
          websocket.onerror = function(){
              setMessageInnerHTML("error");
          };
     
          //鏈接成功創建的回調方法
          websocket.onopen = function(event){
              setMessageInnerHTML("open");
          };
     
          //接收到消息的回調方法
          websocket.onmessage = function(event){
              setMessageInnerHTML(event.data);
          };
     
          //鏈接關閉的回調方法
          websocket.onclose = function(){
              setMessageInnerHTML("close");
          };
     
          //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket鏈接,防止鏈接還沒斷開就關閉窗口,server端會拋異常。
          window.onbeforeunload = function(){
              websocket.close();
          };
     
          //將消息顯示在網頁上
          function setMessageInnerHTML(innerHTML){
              //document.getElementById('message').innerHTML += innerHTML + '<br/>';
              if(innerHTML=="一級告警")
                {
                   $("#soundid1").empty();              
                   var div = document.getElementById('soundid1');
                   div.innerHTML = '<audio src="'+"<%= path %>/jsp/sound/ALARM1.WAV"+'"  hidden="true" autoplay="true" loop="false"></audio>';
                }
                else if(innerHTML=="二級告警")
                {
                    $("#soundid1").empty(); 
                      var div = document.getElementById('soundid1');
                      if(div!=null)
                      {
                       div.innerHTML = '<audio src="'+"<%= path %>/jsp/sound/ALARM3.WAV"+'"  hidden="true" autoplay="true" loop="false"></audio>';             
                      }
                }
          }
     
          //關閉鏈接
          function closeWebSocket(){
              websocket.close();
          }
     
          //發送消息
          function send(){
              var message = document.getElementById('text').value;
              websocket.send(message);
          }    
    }
  </script>

WebSocket服務器端

package com.maven.websocket;

import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
 
@ServerEndpoint(value = "/websocket")
public class MyWebSocket{
    //與某個客戶端的鏈接會話,須要經過它來給客戶端發送數據
    private Session session;
    //靜態變量,用來記錄當前在線鏈接數。應該把它設計成線程安全的。
    private static int onlineCount = 0;
    /**
     * 鏈接創建成功調用的方法
     * @param session  可選的參數。session爲與某個客戶端的鏈接會話,須要經過它來給客戶端發送數據
     * @throws Exception 
     */
    @OnOpen
    public void onOpen(Session session) throws Exception{
        this.session = session;
        WebSocketMapUtil.put(session.getQueryString(),this);
        addOnlineCount();           //在線數加1
        System.out.println("有新鏈接加入!當前在線人數爲" + getOnlineCount());
    }
 
    /**
     * 鏈接關閉調用的方法
     * @throws Exception 
     */
    @OnClose
    public void onClose() throws Exception{
        //從map中刪除
        WebSocketMapUtil.remove(session.getQueryString());
        subOnlineCount();           //在線數減1
        System.out.println("有一鏈接關閉!當前在線人數爲" + getOnlineCount());
    }
 
    /**
     * 收到客戶端消息後調用的方法
     * @param message 客戶端發送過來的消息
     * @param session 可選的參數
     * @throws IOException 
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        String sendUserID = message.split("[|]")[1];
        String sendMessage = message.split("[|]")[0];
        try {
            if (WebSocketMapUtil.get(sendUserID) != null) {
                WebSocketMapUtil.get(sendUserID).sendMessage(sendMessage);
            } else {
                System.out.println("當前用戶不在線!"+WebSocketMapUtil.get(sendUserID)+sendUserID);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        /*try {
            MyWebSocket myWebSocket= ((MyWebSocket) WebSocketMapUtil.get(session.getQueryString().replace("service","client")));
            if(myWebSocket != null){
                myWebSocket.sendMessage(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }*/
    }
 
    /**
     * 發生錯誤時調用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        error.printStackTrace();
    }
 
 
    /**
     * 發送消息方法。
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException{
        this.session.getBasicRemote().sendText(message);
    }
 
    /**
     * 羣發消息方法。
     * @param message
     * @throws IOException
     */
    public void sendMessageAll(String message) throws IOException{
        for(MyWebSocket myWebSocket : WebSocketMapUtil.getValues()){
            myWebSocket.sendMessage(message);
        }
    }
    
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        MyWebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        MyWebSocket.onlineCount--;
    }

}
package com.maven.websocket;

import java.io.IOException;
import java.net.URI;
 
import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
 
@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{
    }
 
    /**
     * 關閉連接方法
     * @param message
     * @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();
        }
    }

}
package com.maven.websocket;

import java.io.IOException;

 
public class MyClientApp {
 
 
    public static void main(String[] args){
        MyClient client = new MyClient();
        client.start(new WebSocketMapUtil().url);
        try {
            client.sendMessage("一級告警|12132313");
            client.closeSocket();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

 

package com.maven.websocket;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
 
public class WebSocketMapUtil {
    public  String url = "ws://110.56.17.4/websocket?service123";
    public static ConcurrentMap<String, MyWebSocket> webSocketMap = new ConcurrentHashMap<String, MyWebSocket>();
    public static void put(String key, MyWebSocket myWebSocket){
        webSocketMap.put(key, myWebSocket);
    }
 
    public static MyWebSocket get(String key){
         return webSocketMap.get(key);
    }
 
    public static void remove(String key){
         webSocketMap.remove(key);
    }
 
    public static Collection<MyWebSocket> getValues(){
        return webSocketMap.values();
    }
}
相關文章
相關標籤/搜索