博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring boot+VUE+websocket 实现消息推送
阅读量:6673 次
发布时间:2019-06-25

本文共 4871 字,大约阅读时间需要 16 分钟。

hot3.png

  • 背景:

        最近涉及消息通知功能,在管理员创建发送消息时,登陆用户可以实时接收到新增消息的提醒,避免频繁刷新,通过websocket取代轮询setInterval。

  • Spring boot部分:
  • POM.xml
org.springframework.boot
spring-boot-starter-websocket
  • 新建配置类:
package io.xcc.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configurationpublic class WebSocketConfig {     /**     * 注入ServerEndpointExporter,     * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint     */    @Bean    public ServerEndpointExporter serverEndpointExporter() {        return new ServerEndpointExporter();    }    }
  • 新建实现类:
package io.xcc.common.socket;import java.util.HashMap;import java.util.Map;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.PathParam;import javax.websocket.server.ServerEndpoint;import org.springframework.stereotype.Component;@Component@ServerEndpoint("/websocket/{userName}")//此注解相当于设置访问URLpublic class WebSocket {        private Session session;        private static CopyOnWriteArraySet
webSockets =new CopyOnWriteArraySet<>(); private static Map
sessionPool = new HashMap
(); @OnOpen public void onOpen(Session session, @PathParam(value="userName")String userName) { this.session = session; webSockets.add(this); sessionPool.put(userName, session); System.out.println(userName+"【websocket消息】有新的连接,总数为:"+webSockets.size()); } @OnClose public void onClose() { webSockets.remove(this); System.out.println("【websocket消息】连接断开,总数为:"+webSockets.size()); } @OnMessage public void onMessage(String message) { System.out.println("【websocket消息】收到客户端消息:"+message); } // 此为广播消息 public void sendAllMessage(String message) { for(WebSocket webSocket : webSockets) { System.out.println("【websocket消息】广播消息:"+message); try { webSocket.session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } // 此为单点消息 public void sendOneMessage(String userName, String message) { System.out.println("【websocket消息】单点消息:"+message); Session session = sessionPool.get(userName); if (session != null) { try { session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }
  • 新增调用类:
@GetMapping("/sendAllWebSocket")    public String test() {        	String text="你们好!这是websocket群体发送!";        webSocket.sendAllMessage(text);        return text;            }        @GetMapping("/sendOneWebSocket/{userName}")    public String sendOneWebSocket(@PathVariable("userName") String userName) {    	String text=userName+" 你好! 这是websocket单人发送!";        webSocket.sendOneMessage(userName,text);        return text;    }
  • VUE部分:
mounted () {      // WebSocket      if ('WebSocket' in window) {        this.websocket = new WebSocket('ws://localhost:8801/myproject/websocket/' + this.userName)        this.initWebSocket()      } else {        alert('当前浏览器 Not support websocket')      }    },    beforeDestroy () {      this.onbeforeunload()    },    methods: {      initWebSocket () {        // 连接错误        this.websocket.onerror = this.setErrorMessage        // 连接成功        this.websocket.onopen = this.setOnopenMessage        // 收到消息的回调        this.websocket.onmessage = this.setOnmessageMessage        // 连接关闭的回调        this.websocket.onclose = this.setOncloseMessage        // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。        window.onbeforeunload = this.onbeforeunload      },      setErrorMessage () {        console.log('WebSocket连接发生错误   状态码:' + this.websocket.readyState)      },      setOnopenMessage () {        console.log('WebSocket连接成功    状态码:' + this.websocket.readyState)      },      setOnmessageMessage (event) {        // 根据服务器推送的消息做自己的业务处理        console.log('服务端返回:' + event.data)      },      setOncloseMessage () {        console.log('WebSocket连接关闭    状态码:' + this.websocket.readyState)      },      onbeforeunload () {        this.closeWebSocket()      },      closeWebSocket () {        this.websocket.close()      }	  }
  • 测试效果:

 http://localhost:8801/myproject/app/sendOneWebSocket/admin

http://localhost:8801/myproject/app/sendOneWebSocket/czm

http://localhost:8801/myproject/app/sendAllWebSocket

用两个浏览器分别登陆两个账号,控制台结果如下图:

                          【图1】

                        【图2】

  • 参考主要来源:

            https://segmentfault.com/a/1190000017268973

  • 其他注意事项:
  1. 不要试图通过单元测试测试,因为session不同获取不到;
  2. 设置完前台没有显示链接成功,请注意修改自己的过滤器;

转载于:https://my.oschina.net/openplus/blog/3046258

你可能感兴趣的文章