首页 > 其他分享 >若依框架整合WebSocket

若依框架整合WebSocket

时间:2024-06-05 17:34:17浏览次数:23  
标签:webSocket 框架 void 连接 若依 session WebSocket logger public

若依框架整合WebSocket

一、前端

1、定义socket对象

data(){
    return{
        webSocket: null,
    }
}

2、建立连接

//如果webSocket为null进行建立连接
if (!this.webSocket) {
    this.webSocket = new WebSocket(`ws://localhost:8081/handleData/`);
	
    //建立连接
    this.webSocket.onopen = function(event) {
        console.log('WebSocket connected');
    };
	
    //接收消息回调函数
    this.webSocket.onmessage = (event) => {
        // 处理从服务器接收的消息
        console.log(event)
    };
	
    //连接异常,设置webSocket对象为null
    this.webSocket.onerror = function(event) {
        console.error('WebSocket error:', event);
        this.webSocket = null;
    };
	
    //连接关闭,设置webSocket对象为null
    this.webSocket.onclose = function(event) {
        console.log('WebSocket connection closed');
        this.webSocket = null;
    };
}

3、向服务端发送消息

//如果webSocket已经建立连接,则进行数据发送
if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
    const msg = {
		//具体数据
    }
    this.webSocket.send(JSON.stringify(msg));
}

二、后端

1、webSocket配置

@Configuration
public class WebSocketConfig {

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

2、webSocket服务建立

@Slf4j
@Component
@ServerEndpoint("/handleData")  //socket连接切入点,即需要进行建立连接的url
@CrossOrigin
public class WebSocketServer {
    
    /** 日志对象 */
    private static Logger logger = LoggerFactory.getLogger(WebSocketServer.class);

    /** 记录当前在线连接数 */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /*这是ArrayList的线程安全的版本 读多写少比较适合*/
    private static CopyOnWriteArrayList<Session> sessionList=new CopyOnWriteArrayList<>();

    /**
     * 解决无法注入bean:定义静态service对象,通过@Autowired在系统启动时为静态变量赋值
     * @ Autowired 注解作用在方法上,如果方法没有参数,spring容器会在类加载完后执行一次这个方法,
     * 如果方法中有参数的话,还会从容器中自动注入这个方法的参数,然后执行一次这个方法。
     */
    private static DataService dataService;

    @Autowired
    public void setDeviceDataService(DataService dataService) {
        WebSocketServer.dataService = dataService;
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        String path = session.getRequestURI().getPath();
        //TODO:在此处获取路径里的传入参数进行建立连接
        
        onlineCount.incrementAndGet();
        sessionList.add(session);
        logger.info("socket连接加入:----deviceId: {},type: {},当前在线人数为:{}----", deviceId, type, onlineCount.get());
        
		
      	//TODO:为需要做业务处理的dataService增加会话
        MessageDto messageDto = new MessageDto();
        sessionMap.put(session,new SendDataDto(session,messageDto));
		
        //TODO:发送设备数据
        sendMessage(JSONObject.toJSONString(data), session);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        Iterator<Session> iterator = sessionList.iterator();
        while(iterator.hasNext()){
            Session next = iterator.next();
            if(session==next){
                sessionList.remove(session);
                //业务会话集合去除关闭的session
			   sessionMap.remove(session);
                onlineCount.decrementAndGet(); // 在线数减1
                logger.info("连接{}关闭",session);
            }
        }
    }
    /**
    *  连接出现异常调用的方法
    */
    @OnError
    public void one rror(Session session, Throwable error) {
        logger.error("系统发生错误");
	    sessionList.remove(session);
        //业务会话集合去除异常的session
        sessionMap.remove(session);
        error.printStackTrace();
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     * 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
        //服务端转发消息给所有的客户端
        MessageDto messageDto = JSONObject.parseObject(message, MessageDto.class);
        //设置节点设备信息
        for (Map.Entry<Session, SendDataDto> entry : sessionMap.entrySet()) {
            if (entry.getKey() == session) {
                MessageDto dto = entry.getValue().getMessageDto();
                //TODO:设置接收到的消息给session的MessageDto
                break;
            }
        }
        //TODO:调用业务处理的service做处理
        
        //发送数据
        sendMessage(JSONObject.toJSONString(data), session);
    }

    /**
     * 服务端发送消息给客户端
     */
    public static synchronized void sendMessage(String message, Session toSession) {
        try {
            logger.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
            logger.error("服务端发送消息给客户端失败:{}",e.getMessage());
        }
    }
}

3、处理socket消息业务类

@Component
public class DataService {
    
    public static final Logger logger = LoggerFactory.getLogger(DataService.class);

    //需要业务处理的会话集合
    public static ConcurrentHashMap<Session, Object> sessionMap = new ConcurrentHashMap<>();

    @PostConstruct
    public void getAllDevicesList(){
        //TODO:业务处理需要初始化加载的数据
    }

    @Scheduled(fixedRate = 10000)
    public void fetchDataAndSendToFrontend() {
		//TODO:定时给不同的会话发送各自的消息
        for (Map.Entry<Session, Object> entry : sessionMap.entrySet()) {
            logger.info("--------------------------------------------------------------------------------");
            Object value = entry.getValue();
            
            logger.info("--------------------------------------------------------------------------------");
        }
    }

//    @Scheduled(fixedRate = 15000)
    public void getRealTimeData(){
		//业务处理
    }
}

标签:webSocket,框架,void,连接,若依,session,WebSocket,logger,public
From: https://www.cnblogs.com/jundong2177/p/18233447

相关文章

  • 2024流行的前端框架
     随着技术的进步,一些前端框架的设计是为了让开发人员获得最高的效率。所有框架都有其独特的功能,使得开发人员很难选择一个。由于每个企业都有不同的需求和目标,因此其网站和应用程序的开发也应根据其需求和梦想进行管理。市场上最好的前端框架一直存在争议。然而,最近的......
  • Java—集合框架、时间和空间复杂度
    一、集合框架Java集合框架(JavaCollectionFramework),又称为容器(container),是定义在java.util包下的一组接口(interfaces)和其实现类(classes)其主要表现为将多个元素(element)置于一个单元中,用于对这些元素进行快速、便捷的存储(store)、检索(retrieve)、管理(manipulate......
  • python自动化测试框架,封装方法方式
    第一种:静态方法封装,接口调用入参定义一个(默认json),直接执行接口请求接口封装代码如下:classOrderTransactionService:@staticmethoddefgetComboProductList(body):url=http_host+'/service?serialize=7'headers={'Content-Type':'applic......
  • STEEL ——首个利用 LLM 检测假新闻的框架算法解析
    1.概述近年来,假新闻的泛滥确实对政治、经济和整个社会产生了深远的负面影响。为了解决这一问题,人们开发了各种假新闻检测方法,这些方法试图通过分析新闻内容、来源和传播方式来识别虚假信息。然而,正如你所提到的,现有的假新闻检测方法存在一些局限性。其中一个主要问题是它......
  • RFC 6455-websocket协议 -- 中文翻译
    英文文档的在源地址:RFC6455-TheWebSocketProtocol中文翻译如下:(未格式化整理)///互联网工程任务组(IETF)请求评论:6455作者:I.Fette公司:Google,Inc.类别:标准轨道ISSN:2070-1721A.Melnikov公司:IsodeLtd.2011年12月WebSocket协议摘要WebSocket协议允许在受......
  • 京东零售数仓的发展过程以及建设框架
    参考:地址1.1发展过程业务驱动数据技术发展,业务野蛮生长,以解决业务痛点为核心,导致烟囱式诞生了一些小数据平台。业务精细化运营,数据平台将多业务线条、多场景的能力进行沉淀,形成数据资产。数据中台化建设已完成,数据驱动业务,通过数据挖掘、分析和人工智能,规模化的赋能业......
  • java框架-日志-体系与级别-技巧
     体系一是提供了统一的日志门面API,即图中紫色部分,实现了中立的日志记录API。二是桥接功能,即图中蓝色部分,用来把各种日志框架的API(图中绿色部分)桥接到SLF4JAPI。这样一来,即便你的程序中使用了各种日志API记录日志,最终都可以桥接到SLF4J门面API。三是适配功能,即图......
  • java-框架-lombok
    1.@Data@Data注解在类上,会为类的所有属性自动生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter@DatapublicclassUser{privateIntegerid;privateStringusername;privateDatebirthday;priva......
  • 一款WPF的精简版MVVM框架——stylet框架(MVVM绑定、依赖注入等)
    今天偶然知道一款叫做stylet的MVVM框架,挺小巧的,特别是它的命令触发方式,简单粗暴,让人感觉很巴适,现在我做一个简单的demo来顺便来分享给大家。本地创建一个WPF项目,此处我使用.NET8来创建。然后引用stylet最新的nuget包。 然后删掉App.xaml里面自带的启动项删掉以后: sty......
  • 一款WPF的精简版MVVM框架——stylet框架的初体验(包括MVVM绑定、依赖注入等操作)
    今天偶然知道一款叫做stylet的MVVM框架,挺小巧的,特别是它的命令触发方式,简单粗暴,让人感觉很巴适,现在我做一个简单的demo来顺便来分享给大家。本地创建一个WPF项目,此处我使用.NET8来创建。然后引用stylet最新的nuget包。 然后删掉App.xaml里面自带的启动项删掉以后: styl......