您的当前位置:首页正文

SpringBoot集成WebSocket并使用

2024-11-29 来源:个人技术集锦

具体的就不多说了,不懂的可以自己搜搜看,直接上代码。 

<!-- Spring Boot Starter WebSocket -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.5.3</version>
        </dependency>

ws的配置文件 

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

/**
 * @Author HaoLinXie
 * @Date 2024/5/8 10:54
 * @ClassName: WebSocketConfig
 * @Description: 配置类
 * @Version 1.0
 */
@Configuration
public class WebSocketConfig {

    /**
     * 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     *
     * @return
     */

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

    /**
     * 通信文本消息和二进制缓存区大小
     * 避免对接 第三方 报文过大时,Websocket 1009 错误
     * @return
     */

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        // 在此处设置bufferSize
        container.setMaxTextMessageBufferSize(10240000);
        container.setMaxBinaryMessageBufferSize(10240000);
        container.setMaxSessionIdleTimeout(15 * 60000L);
        return container;
    }
}
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.core.ApplicationContext;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArraySet;


/**
 * @Author HaoLinXie
 * @Date 2024/5/7 17:06
 * @ClassName: WebSocketServer
 * @Description: WebSocket
 * @Version 1.0
 */
@Slf4j
@Component
@ServerEndpoint(value = "/WebSocketTest")//用于前端连接
public class WebSocketServer {

    //Websocket名称
    private static String NAME = "WebSocketTest";
    //与某个客户端连接会话,需要通过它来给客户端发送数据
    private Session session;
    private String ip;

    //保存所有的ws连接讯息
    private static CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();

    //心跳报文
    private static final String HEARTBEAT_PACKETS = "The heartbeat packets";

    //用于获取应用的上下文
    private static ApplicationContext applicationContext;


    //发送数据的方法
    public static void sendMapMessage(String type, Object data) {
        for (WebSocketServer webSocketServer : webSockets) {
            try {
                if (webSocketServer.session.isOpen()) {
                    JSONObject result = new JSONObject();
                    result.put("type", type);
                    result.put("date", data);
                    webSocketServer.session.getAsyncRemote().sendText(result.toString());
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        try {
            this.session = session;
            // 加入set中
            webSockets.add(this);
            System.out.println(NAME + "连接成功!");
            System.out.println(NAME + "有新的连接,当前连接数总数为:" + webSockets.size());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        try {
            // 从set中删除
            webSockets.remove(this);
            System.out.println(NAME + "有连接断开,当前连接数总数为:" + webSockets.size());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void OnMessage(String message, Session session) {
        if (HEARTBEAT_PACKETS.equals(message)) {
            log.debug("[消息订阅] - 心跳.");
            return;
        }
        // TODO 接收前端入参后的业务处理
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void OnError(Session session, Throwable error) {
        error.printStackTrace();
        log.error("[历史数据回放] - WS 异常断开", session, error);
    }

    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message, Object data) {
        for (WebSocketServer item : webSockets) {
            item.sendMapMessage(message, data);
        }
    }

    /**
     * 指定会话推送
     *
     * @param message
     */
    public static void sendInfo(Session session, String message, Object data) {
        for (WebSocketServer item : webSockets) {
            if (null != session && item.session.equals(session)) {
                item.sendMapMessage(message, data);
            }
        }
    }


    public static void setApplicationContext(ApplicationContext applicationContext) {
        WebSocketServer.applicationContext = applicationContext;
    }

    public static CopyOnWriteArraySet<WebSocketServer> getWebSockerSet() {
        return webSockets;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        WebSocketServer that = (WebSocketServer) o;
        return Objects.equals(session, that.session);
    }

    @Override
    public int hashCode() {
        return Objects.hash(session);
    }
}

使用案例 

import com.jiurong.webSocket.WebSocketServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author HaoLinXie
 * @Date 2024/5/8 23:54
 * @ClassName: TestWSController
 * @Description: 模拟使用
 * @Version 1.0
 */

@RequestMapping("testWS")
@RestController
public class TestWSController {

    @RequestMapping(value = "getWS", method = RequestMethod.GET)
    public String getWS() {
        //处理要发送的数据逻辑
        String data = "我就是要发送的数据";
        //这个key是type,如果一个通道要发送多个不同的数据,可以使用type区分
        WebSocketServer.sendMapMessage("testWebsocket", data);
        return "成功!";
    }
}

测试使用:

启动时建立ws连接:      ws://ip:端口/路径(你要连接的ws名字)

 连接成功,模拟调用http发送ws数据

三克油 

显示全文