websoket服务端主动推动消息客户端

WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
特点:
事件驱动
异步
使用ws或者wss协议的客户端socket

能够实现真正意义上的推送功能

缺点:

少部分浏览器不支持,浏览器支持的程度与方式有区别。

三、WebSocket客户端

websocket允许通过JavaScript建立与远程服务器的连接,从而实现客户端与服务器间双向的通信。在websocket中有两个方法:  
    1、send() 向远程服务器发送数据
    2、close() 关闭该websocket链接
  websocket同时还定义了几个监听函数    
    1、onopen 当网络连接建立时触发该事件
    2、onerror 当网络发生错误时触发该事件
    3、onclose 当websocket被关闭时触发该事件
    4、onmessage 当websocket接收到服务器发来的消息的时触发的事件,也是通信中最重要的一个监听事件。msg.data
  websocket还定义了一个readyState属性,这个属性可以返回websocket所处的状态:
    1、CONNECTING(0) websocket正尝试与服务器建立连接
    2、OPEN(1) websocket与服务器已经建立连接
    3、CLOSING(2) websocket正在关闭与服务器的连接
    4、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();
    }
}

 

posted @ 2018-10-29 08:52  散落人间  阅读(273)  评论(0编辑  收藏  举报
interface food{} class A implements food{} class B implements food{} class C implements food{} public class StaticFactory { private StaticFactory(){} public static food getA(){ return new A(); } public static food getB(){ return new B(); } public static food getC(){ return new C(); } } class Client{ //客户端代码只需要将相应的参数传入即可得到对象 //用户不需要了解工厂类内部的逻辑。 public void get(String name){ food x = null ; if ( name.equals("A")) { x = StaticFactory.getA(); }else if ( name.equals("B")){ x = StaticFactory.getB(); }else { x = StaticFactory.getC(); } } }