美文网首页
2018-08-07 websocket通信

2018-08-07 websocket通信

作者: 胡袁强先生 | 来源:发表于2018-08-07 15:46 被阅读0次

    websocket是一种通信协议,和http、tcp/ip协议是一样的,建立在浏览器和服务器之间的长链接应用;

    首先要说到的就是在spring boot 框架上使用websocket功能,进行通信。发送消息与接收消息功能;

    一、群发消息功能

         1.群发消息,也就是一个发送方,发送消息,所有链接用户都能接收消息,如果要做离线消息处理的话,需要其他功能;

     a.java 代码部分

    核心类,与浏览器的websocket进行交互

    import java.io.IOException;

    import java.util.concurrent.CopyOnWriteArraySet;

    import javax.websocket.OnClose;

    import javax.websocket.OnMessage;

    import javax.websocket.OnOpen;

    import javax.websocket.Session;

    import javax.websocket.server.ServerEndpoint;

    import org.springframework.stereotype.Component;

    @ServerEndpoint(value = "/sendMessage")

    @Component

    public class MyWebSocket{ 

     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。

     private static int onlineCount = 0; 

     //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。

     private static CopyOnWriteArraySetwebSocketSet = new CopyOnWriteArraySet();

        //与某个客户端的连接会话,需要通过它来给客户端发送数据

        private Session session;

        @Autowired

        private MessageService messageService;

        /*** 连接建立成功调用的方法*/

        @OnOpen

        public void onOpen(Session session)

        {

            this.session = session;

            webSocketSet.add(this); //加入set中

            addOnlineCount(); //在线数加1

            System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());

            try

            {

                sendMessage(CommonConstant.CURRENT_WANGING_NUMBER);

            }

            catch (IOException e)

            {

                System.out.println("IO异常");

            }

        }

        /**

        * 连接关闭调用的方法

        */

        @OnClose

        public void onClose()

        {

            webSocketSet.remove(this); //从set中删除

            subOnlineCount(); //在线数减1

            System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());

        }

        /**

        * 收到客户端消息后调用的方法

        *

        * @param message 客户端发送过来的消息*/

        @OnMessage

        public void onMessage(String message, Session session)

        {

            System.out.println("来自客户端的消息:" + message);

            //群发消息

            for (MyWebSocket item : webSocketSet)

            {

                try

                {

                    item.sendMessage(message);

                }

                catch (IOException e)

                {

                    e.printStackTrace();

                }

            }

        }

        /**

        * 群发自定义消息

        * */

        public static void sendInfo(String message) throws IOException

        {

            for (MyWebSocket item : webSocketSet)

            {

                try

                {

                    item.sendMessage(message);

                }

                catch (IOException e)

                {

                    continue;

                }

            }

        }

        private void sendMessage(String message) throws IOException

        {

            System.out.println("hello");

        }

        public static synchronized int getOnlineCount()

        {

            return onlineCount;

        }

        public static synchronized void addOnlineCount()

        {

            MyWebSocket.onlineCount++;

        }

        public static synchronized void subOnlineCount()

        {

            MyWebSocket.onlineCount--;

        }

    }

    上下文监听

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

    import org.springframework.web.socket.server.standard.ServerEndpointExporter;

    @Configuration

    public class WebSocketConfig

    {

        @Bean

        public ServerEndpointExporter serverEndpointExporter()

        {

            return new ServerEndpointExporter();

        }

    }

    如果此时需要引入service接口,通过自动装载的方式注入接口,则需要加入一个类,以便于引用

    import org.springframework.beans.BeansException;

    import org.springframework.context.ApplicationContext;

    import org.springframework.context.ApplicationContextAware;

    import org.springframework.context.annotation.Lazy;

    import org.springframework.stereotype.Component;

    @Component

    @Lazy(false)

    public class ApplicationContextRegister implements ApplicationContextAware

    {

        private static ApplicationContext APPLICATION_CONTEXT;

        /**

        * 设置spring上下文  *  * @param applicationContext spring上下文  *

        */

        @Override

        public void setApplicationContext(ApplicationContext applicationContext)

                throws BeansException

        {

            APPLICATION_CONTEXT = applicationContext;

        }

        public static ApplicationContext getApplicationContext()

        {

            return APPLICATION_CONTEXT;

        }

    }

    用法:

    //webSocket不能使用自动装载方式,使用spring反射

    ApplicationContext act = ApplicationContextRegister.getApplicationContext();

    MessageService messagelogService = act.getBean(MessageService.class);

    这样就能引用service中方法

    b.前段代码部分

    <!docment html>

    <html>

    <head>

    <title>My WebSocket</title>

    </head>

    <body>

    welcome<br/>

    <input id="text" type="text"/> <button onclick = "send()">Send</button> <button onclick="closeWebSocket">Close</button>

    <div id="message">

    </div>

    </body>

    <script type="text/javascript">

    var websocket = null;

    //判断当前浏览器是否支持WebSocket

    if('WebSocket' in window){

    websocket = new WebSocket("ws://10.200.9.165:8088/bales/websocket/90950");

    }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 + ' '; }

    //关闭连接

    function closeWebSocket(){ websocket.close(); }

    //发送消息

    function send(){ var message = document.getElementById('text').value; websocket.send(message); }

    </script>

    </html>

    相关文章

      网友评论

          本文标题:2018-08-07 websocket通信

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