springcloud + vue + websocket

1.前端

前端监听地址:ip:webSocket服务的端口号/webSocket/参数

mounted() {// 初始化WebSocket
    this.initWebSocket();
},
methods: {
  //======================= WebSocket相关 =======================
    initWebSocket: function() {
      if (typeof WebSocket === "undefined") {
        alert("您的浏览器不支持socket");
      } else {
        // 监听地址
        this.notifyUrl = this.notifyUrl + "webSocket/" + this.sysUser.userId;
        // 实例化socket
        this.socket = new WebSocket(this.notifyUrl);
        // 监听socket连接
        this.socket.onopen = this.openWebSocket;
        // 监听socket错误信息
        this.socket.onerror = this.errorWebSocket;
        // 监听socket消息
        this.socket.onmessage = this.getSocketMsg;
     // 路由跳转时结束websocket链接
        let testSocket = this.socket;
        this.$router.afterEach(function() {
          testSocket.close();
        });
      }
    },
    openWebSocket: function() {
      console.log("WebSocket连接成功");
    },
    errorWebSocket: function() {
      console.log("WebSocket连接发生错误");
    },
    // 监听后端获取数据
    getSocketMsg: function(msg) {
      this.payResult = msg.data;
    },
    closeWebSocket: function() {
      console.log("socket已经关闭");
    }
}
 

 

2.WebSocket所在服务Pom文件

<!--websocket-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

 

3.WebSocket配置文件

package com.ax.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketAutoConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

 

4.WebSocket服务类

package com.ax.service;


import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint(value = "/webSocket/{userId}")
public class WebSocketServer {
    //静态变量,用来记录当前在线连接数。
    private static int onlineCount = 0;

    private Session session;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private static Map<String, Session> sessionPool = new HashMap<String, Session>();

    /**
     * @方法描述: 开启socket
     * @return: void
     * @Author: carry
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        int maxSize = 200 * 1024;
        //  可以缓冲的传入二进制消息的最大长度
        session.setMaxBinaryMessageBufferSize(maxSize);
        //  可以缓冲的传入文本消息的最大长度
        session.setMaxTextMessageBufferSize(maxSize);
        this.session = session;
        //  加入set中
        webSockets.add(this);
        //  连接数加1
        addOnlineCount();
        //  把对应用户id的session放到sessionPool中,用于单点信息发送
        sessionPool.put(userId, session);
        System.out.println("【websocket消息】 有新连接加入!用户id" + userId + ",当前连接数为" + getOnlineCount());
    }

    /**
     * @方法描述: 关闭socket
     * @return: void
     * @Author: carry
     */
    @OnClose
    public void onClose() {
        webSockets.remove(this);
        subOnlineCount();           //在线数减1
        System.out.println("【websocket消息】 连接断开!当前连接数为" + getOnlineCount());
    }

    /**
     * @方法描述: 收到客户端消息
     * @return: void
     * @Author: carry
     */
    @OnMessage
    public void onMessage(String message) {
        System.out.println("【websocket消息】收到客户端消息:" + message);
    }

    /**
     * @方法描述: 广播消息全体发送
     * @return: void
     * @Author: carry
     */
    public void sendAllMessage(String message) {
        for (WebSocketServer webSocket : webSockets) {
            System.out.println("【websocket消息】广播消息:" + message);
            try {
                webSocket.session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @方法描述: 一对一单点消息
     * @return: void
     * @Author: carry
     */
    public void sendOneMessage(String userId, String message) {
        try {
            // 防止推送到客户端的信息太多导致弹窗太快
//            Thread.sleep(500);
            System.out.println("用户" + userId + "【websocket消息】单点消息:" + message);
            Session session = sessionPool.get(userId);
            if (session != null) {
                // getAsyncRemote是异步发送
                // 加锁防止上一个消息还未发完下一个消息又进入了此方法,防止多线程中同一个session多次被调用报错
                synchronized (session) {
                    session.getAsyncRemote().sendText(message);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @方法描述: 发生错误时调用
     * @return: void
     * @Author: carry
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

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

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}
View Code

 

posted @ 2019-12-20 17:29  幻月hah  阅读(1423)  评论(2编辑  收藏  举报