使用Java接口调用websocket

WebSocket 接口调用指南

概述

本文档提供通过 RESTful 接口调用 WebSocket 服务的完整解决方案,包含接口定义、实现逻辑、配置说明及注意事项。


快速开始

1.接口调用示例

POST /getWebSocketData
请求参数:
- data: 需要发送的文本数据
- url: WebSocket 服务地址(ws:// 或 wss:// 开头)

响应示例:
{
    "code": 200,
    "message": "success",
    "data": { /* 处理后的JSON数据 */ }
}

2. 前置条件

  • Spring Boot 2.x+
  • 添加依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

代码详解

1. Controller 层

@PostMapping("/getWebSocketData")
@ApiOperation("根据路径参数获取ws数据")
public Result connectWS(
        @RequestParam String data, 
        @RequestParam String url) {
    try {
        String result = envResultService.connectWebSocket(data, url);
        //处理返回结果
        JSONObject jsonObject = processData(result);
        return Result.success(jsonObject);
    } catch (Exception e) {
        return Result.error("WebSocket连接失败: " + e.getMessage());
    }
}
  • 参数说明
    • data: 要发送的 WebSocket 消息内容
    • url: 目标 WebSocket 服务地址
  • 特性
    • 统一异常处理
    • 返回结果标准化处理

2. 服务实现层

@Override
    public String connectWebSocket(String data, String url) {
        CompletableFuture<String> responseFuture = new CompletableFuture<>();
        StandardWebSocketClient client = new StandardWebSocketClient();

        // 使用反射设置缓冲区大小
        try {
            Field containerField = StandardWebSocketClient.class.getDeclaredField("webSocketContainer");
            containerField.setAccessible(true); // 允许访问私有字段
            WebSocketContainer container = (WebSocketContainer) containerField.get(client);

            // 设置缓冲区大小
            container.setDefaultMaxTextMessageBufferSize(bufferConfig.getMaxTextMessageSize());
            container.setDefaultMaxBinaryMessageBufferSize(bufferConfig.getMaxBinaryMessageSize());
        } catch (Exception e) {
            log.error("无法设置缓冲区大小: {}", e.getMessage());
        }

        WebSocketHandler handler = new AbstractWebSocketHandler() {
            @Override
            public void afterConnectionEstablished(WebSocketSession session) throws Exception {
                log.info("WebSocket 连接已建立: {}", session.getId());
                session.sendMessage(new TextMessage(data));
            }

            @Override
            protected void handleTextMessage(WebSocketSession session, TextMessage message) {
                log.info("收到 WebSocket 响应: {}", message.getPayload());
                responseFuture.complete(message.getPayload());
                try {
                    session.close();
                } catch (IOException e) {
                    log.error("关闭 WebSocket 会话时出错", e);
                }
            }

            @Override
            public void handleTransportError(WebSocketSession session, Throwable exception) {
                log.error("WebSocket 传输错误", exception);
                responseFuture.completeExceptionally(exception);
            }
        };

        ListenableFuture<WebSocketSession> handshakeFuture = client.doHandshake(handler, url);

        handshakeFuture.addCallback(
                session -> CompletableFuture.runAsync(() -> {
                    log.info("WebSocket 握手成功: {}", session.getId());
                }, executorService),
                ex -> CompletableFuture.runAsync(() -> {
                    log.error("WebSocket 握手失败", ex);
                    responseFuture.completeExceptionally(ex);
                }, executorService)
        );

        try {
            return responseFuture.get(60, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            log.error("等待 WebSocket 响应超时", e);
            throw new RuntimeException("等待响应超时");
        } catch (InterruptedException | ExecutionException e) {
            log.error("请求中断或执行异常", e);
            throw new RuntimeException("内部错误");
        }
    }

    @PreDestroy
    public void destroy() {
        if (!executorService.isShutdown()) {
            executorService.shutdown();
        }
    }

关键点

  • 使用 CompletableFuture 实现异步响应处理
  • 反射修改 WebSocket 缓冲区大小(需处理安全检查)
  • 60秒超时控制机制
  • 自动关闭连接设计

3. WebSocket 配置类

@Configuration
@ConfigurationProperties(prefix = "websocket.buffer")
public class WebSocketBufferConfig {
    private int maxTextMessageSize;  // 文本消息最大尺寸
    private int maxBinaryMessageSize; // 二进制消息最大尺寸
    
    // Getter/Setter 省略
}

配置说明

application.yml

websocket:
  buffer:
    max-text-message-size: 104857600  # 100MB
    max-binary-message-size: 104857600 # 100MB

参数说明

  • max-text-message-size: 文本消息缓冲区最大值
  • max-binary-message-size: 二进制消息缓冲区最大值

注意事项

  1. 安全警告
    • 反射修改私有字段 webSocketContainer 可能带来兼容性问题
    • 生产环境建议通过正规方式配置 WebSocketContainer
  2. 性能建议
    • 根据实际需求调整缓冲区大小
    • 超时时间(60s)可根据网络状况优化
  3. 异常处理
    • 捕获 TimeoutException 防止线程阻塞
    • 使用 @PreDestroy 确保优雅关闭线程池
  4. 使用限制
    • 仅支持单次请求-响应模式
    • 不支持长连接保持

常见问题

Q1: 出现 403 Forbidden 错误
A: 检查目标 WebSocket 服务的跨域配置

Q2: 缓冲区设置不生效
A: 确保配置前缀正确,检查容器是否被其他配置覆盖

Q3: 收到消息不完整
A: 检查缓冲区大小是否足够,适当增加 max-text-message-size

Q4: 如何支持二进制消息?
A: 重写 handleBinaryMessage 方法并配置二进制缓冲区大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值