websocet后台主动推送vue前台消息

需要的jar包依赖

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.0.4.RELEASE</version>
        </dependency>

java部分WebSocket服务接口

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * WebSocket服务接口
 *
 * @author wzw
 * @date 2022/08/23
 */
@ServerEndpoint(value = "/websocket/{userId}")
@Component
public class WebSocketServer {
    private final static Logger log = LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * 存储登录用户的 sid 以及 session
     */
    private static ConcurrentHashMap<String, Session> connections = new ConcurrentHashMap<>(32);

    /**
     * 是WebSocket的Session
     */
    private Session session;

    /**
     * 统计在线人数
     */
    private static AtomicInteger onlineCount = new AtomicInteger();

    /**
     *  事件 --登录的人当你登录之后建立连接,此方法便会执行
     * @param userId
     * @param session
     */
    @OnOpen
    public void onopen(@PathParam("userId") String  userId, Session session) {
        this.session = session;
        System.out.println("seesionId为" + session.getId());
        if (connections.containsKey(userId)) {
            connections.remove(userId);
            connections.put(userId, session);
        }else {
            onlineCount.incrementAndGet();
            connections.put(userId, session);
            System.out.println("用户:"+userId+"-"+session.getId()+"上线了-"+session);
            System.out.println("在线人数:"+onlineCount);

        }
    }

    @OnClose
    public void onClose(Session session){
        for (String userId : connections.keySet()) {
            if(connections.get(userId).equals(session)){
                System.out.println("用户:"+userId+"-关闭-"+session);
                connections.remove(session);
                onlineCount.decrementAndGet(); // 在线数减1
            }
        }
    }

    @OnMessage
    public void onMessage(String msg, Session session) {
        System.out.println("服务端收到客户端"+session.getId()+"的消息:"+msg);
        // 客户端向服务端发送消息,然后再推送给其他的用户,可以在这里进行设置
        try {
            sendMessage(msg, session);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (EncodeException e) {
            e.printStackTrace();
        }
    }
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    //推送
    public static void sendMessage(String msg, Session session) throws IOException, EncodeException {
//        for (Session session1 : webSocketSet) {
//            if (session != session1)
//                session1.getBasicRemote().sendText(msg);
//        }
        System.out.println("推送:"+msg);
        session.getBasicRemote().sendText(msg);
    }

    // 推送给指定的用户群
    public void sendMsgToUsers(List<String> ids,Map<String, Object> map) {
        ids.stream().forEach(s -> {
            System.out.println("用户:"+s+"是否能够推送:"+connections.containsKey(s));
            if (connections.containsKey(s)) {
                if (connections.get(s).isOpen()){
                    try {
                        sendMessage(new JSONObject(map).toString(),connections.get(s));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    } catch (EncodeException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    // 推送给全部在线用户
    public static void sendMsgToAll(Map<String, Object> map){
        connections.keySet().stream().forEach(s->{
            if (connections.get(s).isOpen()){
                try {
                    sendMessage(String.valueOf(map),connections.get(s));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                } catch (EncodeException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

vue前台进行用户注册,消息连接

initWebSocket() {
      // 初始化weosocket
      // 这里的wsuri是根据服务端的ip进行配置(开发环境),生产环境的话可以使用上面的Ip或者是nginx做代理
      const wsuri = `ws://127.0.0.1:8099/websocket/001`;      // 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
      this.websocket = new WebSocket(wsuri);
      this.websocket.onopen = this.websocketonopen;
      this.websocket.onerror = this.websocketonerror;
      this.websocket.onmessage = this.setOnmessageMessage;
      this.websocket.onclose = this.websocketclose;
    },

    start() {
      // 清除延时器
      this.timeoutObj && clearTimeout(this.timeoutObj);
      this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
      this.timeoutObj = setTimeout(() => {
        if (this.websocket && this.websocket.readyState == 1) {
          // this.websocket.send('检测心跳是否正常');//发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数
        } else {
          this.reconnect();
        }
        // 定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接
        // this.serverTimeoutObj = setTimeout(() => {
        //   this.websocket.close();
        // }, this.timeout)
      }, this.timeout)
    },
    resetSocket() { // 重置心跳
      // 清除时间
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      // 重启心跳
      this.start();
    },
    // 重新连接
    reconnect() {
      if (this.lockReconnect) return
      this.lockReconnect = true;
      // 没连接上会一直重连,设置延迟避免请求过多
      this.timeoutnum && clearTimeout(this.timeoutnum);
      this.timeoutnum = setTimeout(() => {
        this.initWebSocket();
        this.lockReconnect = false;
      }, 5000)
    },
    async setOnmessageMessage(event) {
      console.log(JSON.parse(event.data));
      this.$Notice.error({
        title: '错误提示',
        desc: JSON.parse(event.data).msg
      });
      this.resetSocket();
      // 自定义全局监听事件
      window.dispatchEvent(new CustomEvent('onmessageWS', {
        detail: {
          data: event.data
        }
      }))
      // //发现消息进入    开始处理前端触发逻辑
      // if (event.data === 'success' || event.data === 'heartBath') return
    },
    websocketonopen() {
      // 开启心跳
      this.start();
      console.log('WebSocket连接成功!!!' + new Date() + '----' + this.websocket.readyState);
    },
    websocketonerror(e) {
      console.log('WebSocket连接发生错误' + e);
    },
    websocketclose(e) {
      this.websocket.close();
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      console.log('WebSocket连接关闭');
      this.start();
    },
    websocketsend(messsage) {
      this.websocket.send(messsage)
    },
    closeWebSocket() { // 关闭websocket
      this.websocket.close()
    },

连接成功后效果截图

后台主动推送方法调用

 JSONObject rs = new JSONObject();
 rs.put("code","-1");
 rs.put("msg","xxxx产生异常,请联系工程师进行排查!!!");
 sendMsgToAll(rs);

以上就实现了web端主动向前端推送消息~~~

猜你喜欢

转载自blog.csdn.net/wzw_wwl/article/details/126487802