幻想的世界 2019-12-05 15:48 采纳率: 0%
浏览 1672

websocket频繁发送大数据。

springboot项目,使用websocket持续给前端(vue)发送数据。但是会经常中断,不发数据了,记录在线人数的功能正常,如果有新的登录或者登出,后台正常显示。就是不发数据了,需要重启项目才会发数据。

package com.smart.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Description: websocket工具类,
 *  flag表示身份标识:
 *  bigScreen:大屏
 *  backSys:后台系统
 */
@ServerEndpoint("/websocket/{flag}")
@Component
public class WebSocketUtils {
    private Logger logger = LoggerFactory.getLogger(getClass());

    public static final String BIGSCREEN = "bigScreen"; //大屏
    public static final String BACKSYS = "backSys"; //后台

    //静态变量,用来记录当前在线连接数
    private static int onlineCount = 0;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketUtils> webSocketSet = new CopyOnWriteArraySet<>();

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

    /**
     * 身份标识
     */
    private String flag;

    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("flag") String flag, Session session){
        this.session = session;
        this.flag = flag;
        webSocketSet.add(this);
        addOnlineCount();        //在线数加1
        logger.info("有新连接加入!当前在线人数为" + getOnlineCount()+",上线用户为:"+this.flag);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(){
        webSocketSet.remove(this);
        subOnlineCount();           //在线数减1
        logger.info("有一连接关闭!当前在线人数为" + getOnlineCount()+",下线用户为:"+this.flag);
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        //解析message
        if(message==null){
            session.getAsyncRemote().sendText("发送的消息不能为空");
        }else{

        }
    }


    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        logger.info("发生错误:"+error.getMessage());
        error.printStackTrace();
    }


    /**
     * 群发消息
     * @param message
     * @throws IOException
     */
    public void sendMessageToFlag(String message){
        for (WebSocketUtils ws : webSocketSet){
            try{
                ws.sendMessage(message);
            }catch (Exception e){
                logger.error("sendMessageToFlag: "+e.toString());
            }

        }
    }

    /**
     * 给指定身份发送消息
     * @param message
     * @param flag
     * @throws IOException
     */
    public void sendMessageToFlag(String message,String flag){
        try{
            boolean online = true;
            for (WebSocketUtils ws : webSocketSet){
                if (flag.equals(ws.flag)){
                    ws.sendMessage(message);
                    online = false;
                }
            }
            if (online){
                logger.info(flag+"不在线");
            }
        }catch (Exception e){
            logger.error("sendMessageToFlag: "+e.toString());
        }

    }

    public boolean isonline(){
        boolean online = false;
        for (WebSocketUtils ws : webSocketSet){
            if (BIGSCREEN.equals(ws.flag)){
                online = true;
            }
        }
        return online;
    }

    public void sendMessageToBigScreen(String message){
        sendMessageToFlag(message,BIGSCREEN);
    }

    public void snedMessage2BackSys(String message){
        sendMessageToFlag(message,BACKSYS);
    }

    /**
     * 服务器主动推送消息到客户端
     * @param message
     * @throws IOException
     */
    private void sendMessage(String message) throws IOException {
        synchronized(this.session){
            this.session.getBasicRemote().sendText(message);
        }
        System.out.println("发送数据给:"+this.flag+":"+message);
    }

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

    private static synchronized void addOnlineCount() {
        WebSocketUtils.onlineCount++;
    }

    private static synchronized void subOnlineCount() {
        WebSocketUtils.onlineCount--;
    }

}

  • 写回答

1条回答

  • 红恩 2023-03-20 17:39
    关注

    前端有做心跳和关闭事件记录吗?

    评论

报告相同问题?

悬赏问题

  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)