springboot下的websocket消息推送

websocket是客户端和服务端之间的通信,所以我们需要实现websocket的服务端和客户端,而这里客户端我们写到Html的前端中。websocket的开发需要进行以下几个步骤:

1.引入依赖
        <!--websocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>

        </dependency>

2.对websocket进行配置

@Component
public class WebSocketConfig {

    //把你要实例化的对象转化成一个Bean,放在IoC容器中
    @Bean
    public ServerEndpointExporter serverEndpointExporter () {
        return new ServerEndpointExporter();
    }
}

注意:上面这种配置有个缺点,就是服务端的类里面无法使用@Value或@Autowired之类的Spring注入。修改的方法,痛过百度,在后面有写到。

3.编写服务端实现类。

websocket与普通controller不太一样,但也不是service。这里,笔者把它写在service目录下

该类应该有一下几个功能。@OnOpen有新的连接。@OnClose连接关闭。@OnMeesage收到信息。sendMessage发送信息。

package com.wechat.order.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint("/webSocket")//调用websocket的url
@Slf4j
public class WebSocket {

    private static int onlineCount = 0;//记录总连接数

    //定义一个websocket的容器,用来储存这些session
    private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();//注意这里不能直接使用Set集合。

    private Session session;

    /**
     * 有新的连接
     * @param session
     * @throws IOException
     */
    @OnOpen
    public void onOpen(Session session) throws IOException{
        this.session = session;
        webSocketSet.add(this);
        incrOnlineCount();//连接数+1
        log.info("【websocket消息】有新的连接,当前总连接数: {}", getOnlineCount());
    }

    /**
     * 连接关闭
     * @throws IOException
     */
    @OnClose
    public void onClose() throws IOException{
        webSocketSet.remove(this);
        decOnlineCount();//连接数-1
        log.info("【websocket消息】有连接断开,当前总连接数:: {}", getOnlineCount());
    }

    /**
     * 收到信息
     * @param message 收到的信息内容
     * @param session
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        log.info("【websocket消息】收到客户端发来的消息: {}", message);
        // broadcast received message
        for(WebSocket item : webSocketSet){
            item.sendMessage(message);
        }
    }

    /**
     * 使用广播发送消息
     * @param message
     */
    public void sendMessage(String message) {
        log.info("【websocket消息】广播消息: {}", message);

        for(WebSocket webSocket : webSocketSet){
            //发送消息这类不是特别重要,不影响程序运行的异常可以直接try,catch
            try {
                webSocket.session.getBasicRemote().sendText(message);
            }catch (Exception e) {
                log.error("websocket消息】广播消息异常: {}", e.getStackTrace());
            }
        }
    }

    /**
     * 当前连接数
     * @return
     */
    public static synchronized int getOnlineCount(){
        return WebSocket.onlineCount;
    }

    /**
     * 连接记录+1
     */
    public static synchronized void incrOnlineCount(){
        WebSocket.onlineCount++;
    }

    /**
     * 连接记录-1
     */
    public static synchronized void decOnlineCount(){
        WebSocket.onlineCount--;
    }
}

4.客户端,这里使用html的js和vue来实现

    <!DOCTYPE html>  
    <html>  
    <head>  
        <meta charset="UTF-8">  
        <title>My WebSocket</title>  
      
        <script src="js/vue.js"></script>  
    </head>  
    <body>  
    Welcome To My WebSocket.<br/><br/>  
        <div id="ws">  
        <input id="text" type="text"/>  
        <button οnclick="sendMsg()">Send</button>  
        <button οnclick="closeWS()" :disabled="!opened">Close</button>  
        <button οnclick="openWS()"  :disabled="opened">Open</button>  
        <div v-html="msg"></div>  
        </div>  
    </body>  
      
    <script type="text/javascript">  
        var websocket = null;  
      
        var wsVue = new Vue({  
            el: '#ws',  
            data: {  
                msg: "welcome to my websocket...<br/>",  
                opened: false  
            },  
            mounted: function(){  
                initWs();  
            }  
        });  
      
        function initWs() {  
            //check if your browser supports WebSocket  
            if ('WebSocket' in window) {  
                websocket = new WebSocket("ws://localhost:8080/webSocket");  
            }  
            else {  
                alert('Sorry, websocket not supported by your browser.')  
            }  
      
            //Error callback  
            websocket.onerror = function () {  
                setMessageContent("error!");  
                wsVue.opened = false;  
            };  
      
            //socket opened callback  
            websocket.onopen = function (event) {  
                setMessageContent("websocket opened");  
                wsVue.opened = true;  
            }  
      
            //message received callback  
            websocket.onmessage = function (event) {  
                setMessageContent(event.data);  
            }  
      
            //socket closed callback  
            websocket.onclose = function () {  
                setMessageContent("websocket closed");  
                wsVue.opened = false;  
            }  
      
            //when browser window closed, close the socket, to prevent server exception  
            window.onbeforeunload = function () {  
                websocket.close();  
            }  
        }  
      
        //update message to vue and then in div  
        function setMessageContent(content) {  
            wsVue.msg += content  + '<br/>';  
        }  
      
        //click to close the websocket  
        function closeWS() {  
            websocket.close();  
            wsVue.opened = false;  
        }  
      
        //click to open the websocket  
        function openWS() {  
            initWs();  
        }  
      
        //click to send message  
        function sendMsg() {  
            var message = document.getElementById('text').value;  
            websocket.send(message);  
        }  
    </script>  
    </body>  
    </html>  

下面讲解配置websocket的第二种方法:

    @Configuration  
    @EnableWebSocket  
    public class WebSocketConfig implements WebSocketConfigurer {  
        @Override  
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
            registry.addHandler(CmdHandler(), "/webSocket"); //url和handler的mapping  
        }  
      
        @Bean  
        public WebSocketHandler WebSocket() {  
            return new WebSocket();  
        }  
    }  


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值