栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Springboot使用websocket服务端+客户端(断线重连)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot使用websocket服务端+客户端(断线重连)

文章目录
  • 前言
  • 一、先创建好SpringBoot框架
  • 二、使用步骤
    • 1.使用maven引入依赖
    • 2.创建服务端
      • 创建WebSocketServer
      • 创建WebSocketConfig
    • 3.创建客户端-web版本
      • web版连接演示
    • 4.SpringBoot作为客户端 带断线重连
      • 1.创建MyWebSocketClient
      • 2.新建工具类解析ByteBuffer 数据 ByteUtils
      • 新建WebSocketConfig
      • 4.演示
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

SpringBoot中使用Websocket


提示:以下是本篇文章正文内容,下面案例可供参考

一、先创建好SpringBoot框架

二、使用步骤 1.使用maven引入依赖

代码如下:



    org.springframework.boot
    spring-boot-starter-websocket


    org.projectlombok
    lombok

 
 org.apache.commons
     commons-lang3
     3.8.1
 
2.创建服务端 创建WebSocketServer
package com.panbl.websocketdemo.websocket;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.List;
import java.util.concurrent.ConcurrentHashMap;


@Component
@Slf4j
@ServerEndpoint("/ws/{userId}")
public class WebSocketServer {

    
    private static int onlineCount = 0;
    
    private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap> devWebSocketMap = new ConcurrentHashMap<>();
    
    private Session session;
    
    private String userId = "";

    
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        //userId = session.getId()+"_"+userId; //拼接
        this.userId=userId;
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //加入set中
            webSocketMap.put(userId,this);
        }else{
            //加入set中
            webSocketMap.put(userId,this);
            //在线数加1
            addOnlineCount();
        }
        log.info("用户连接:"+userId+",当前在线用户为:" + getOnlineCount());
        sendMessage("{"status":0,"msg":"连接成功"}");
    }

    
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:"+userId+",当前在线用户为:" + getOnlineCount());
    }

    
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:"+userId+",报文:"+message);
        //可以群发消息
        //消息保存到数据库、redis
        if(StringUtils.isNotBlank(message)){
            try {

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }


    
    @OnError
    public void onError(Session session, Throwable error) {

        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
        error.printStackTrace();
    }

    
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    
    public static void sendInfo(String message, String userId) {
        log.info("发送消息到:"+userId+",报文:"+message);
        if(StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendMessage(message);
        }else{
            log.error("用户"+userId+",不在线!");
        }
    }

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

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

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

}


创建WebSocketConfig
package com.lst.cabinet.config;

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


@Configuration
public class WebSocketConfig {

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

以上为服务端代码。


3.创建客户端-web版本



    
    websocket通讯




【socket开启者的ID信息】:

【客户端向服务器发送的内容】:

【操作】:

【操作】:

web版连接演示

在这里插入图片描述

4.SpringBoot作为客户端 带断线重连

新建SpringBoot项目



    org.projectlombok
    lombok
    true


    cn.hutool
    hutool-all
    5.7.22


    org.java-websocket
    Java-WebSocket
    1.5.2

1.创建MyWebSocketClient
package com.panbl.springbootwebsocketclient.websocket;

import com.panbl.springbootwebsocketclient.tool.ByteUtils;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Map;


@Slf4j
public class MyWebSocketClient extends org.java_websocket.client.WebSocketClient {



    public MyWebSocketClient(URI serverUri) {
        super(serverUri);
    }

    public MyWebSocketClient(URI serverUri, Draft protocolDraft) {
        super(serverUri, protocolDraft);
    }

    public MyWebSocketClient(URI serverUri, Draft protocolDraft, Map httpHeaders, int connectTimeout) {
        super(serverUri, protocolDraft, httpHeaders, connectTimeout);
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        log.info("[websocket] 连接成功");
        //devOrder.subscribeDev("33255773800487108280");
    }

    @Override
    public void onMessage(String message) {
        log.info("[websocket] 收到消息={}", message);
    }

    @Override
    public void onMessage(ByteBuffer bytes) {
        log.info("[websocket] 收到消息={}", ByteUtils.getString(bytes));

    }

    @Override
    public void onClose(int i, String s, boolean b) {
        log.info("[websocket] 退出连接");
    }

    @Override
    public void onError(Exception e) {
        e.printStackTrace();
        log.info("[websocket] 连接错误={}", e.getMessage());
    }
}

2.新建工具类解析ByteBuffer 数据 ByteUtils
package com.cw.devsocket.Tool;

import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;


public class ByteUtils {

    
    public static ByteBuffer getByteBuffer(String str)
    {
        return ByteBuffer.wrap(str.getBytes());
    }

    
    public static String getString(ByteBuffer buffer)
    {
        Charset charset = null;
        CharsetDecoder decoder = null;
        CharBuffer charBuffer = null;
        try
        {
            charset = Charset.forName("UTF-8");
            decoder = charset.newDecoder();
            // charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空
            charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
            return charBuffer.toString();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return "";
        }
    }
}

新建WebSocketConfig
package com.panbl.springbootwebsocketclient.config;

import com.panbl.springbootwebsocketclient.websocket.MyWebSocketClient;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;


@Component
@Slf4j
public class WebSocketConfig {

    @Autowired
    private Environment env;

    @Bean
    public WebSocketClient webSocketClient() {
        //String ws=env.getProperty("dev.webSocket")+ UUID.randomUUID().toString();
        String ws="ws://localhost:8080/ws/"+ UUID.randomUUID().toString();
        //String ws="ws://127.0.0.1:8181/ws/v1/cabinet/status/"+ UUID.randomUUID().toString();
        try {
            WebSocketClient webSocketClient = new MyWebSocketClient(new URI(ws));
            webSocketClient.connect();
            Timer t = new Timer();
            t.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("进入定时器");
                    if(webSocketClient.isClosed()){
                        log.error("断线重连");
                        webSocketClient.reconnect();
                    }
                }
            },1000,5000);
            return webSocketClient;
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }

}

4.演示


总结

源码码云地址:https://gitee.com/panbanglin/spring-boot-websocket-usage.git

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/839244.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号