You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

rsocket-js与Spring-rsocket传输超65536字节数据时解码异常

RSocket-WebSocket大体积数据传输在Chrome/Edge中反序列化失败问题

问题场景

使用rsocket-websocket-client(浏览器端)与Spring Boot构建的RSocket服务端通信,当客户端通过requestResponse返回包含100万元素数组的JSON数据时,Firefox可正常运行,但Chrome和Edge会触发服务端JSON反序列化错误,提示输入不完整。

客户端代码(浏览器)

async function initRequest() {
  const transportOpts = {
    url: 'ws://127.0.0.1:6565',
    debug: true
  }

  const setup = {
    dataMimeType: APPLICATION_JSON.string,
    keepAlive: 10000,
    lifetime: 90000,
    metadataMimeType: MESSAGE_RSOCKET_ROUTING.string,
  }

  const responder = {
    requestResponse: function (request) {
      console.log('get req from server');
        return new Single((subscriber) => {
          subscriber.onSubscribe(() => {});
          // 返回大体积数据
          subscriber.onComplete({
            data: {
              "data": new Array(1000000).fill(0),
            }
          })
        })
    }
  }

  const serializers = {
    data: JsonSerializer,
    metadata: IdentitySerializer,
  }

  const errorHandler = (e) => {
    console.log(e);
  }

  const transport = new RSocketWebSocketClient(transportOpts);
  const client = new RSocketClient({setup, transport, responder, serializers, errorHandler});
  rSocket = await client.connect();
  console.log('init client');
  rSocket.requestResponse({
    data: '3434',
    metadata: String.fromCharCode('hello'.length) + 'hello'
  }).subscribe({
    onComplete: (response) => {
      console.log(response);
    },
    onError: (error) => {
      console.log(error);
    }
  })
  return rSocket;
}

服务端代码(Spring Boot)

private RSocketRequester requester;

@ConnectMapping
public void handleMessage(RSocketRequester requester) {
    System.out.println("connected");
    this.requester = requester;
    requester.rsocketClient().source().doOnError(Throwable::printStackTrace).subscribe(r -> r.onClose().doFinally(v -> {
        System.out.println("closed");
        this.requester = null;
    }).subscribe());
}

@Scheduled(fixedRate = 5000)
public void schedule() {
    if (requester == null) {
        return;
    }
    // 向客户端发送requestResponse请求
    requester.route("ddd").data("{}").retrieveMono(HashMap.class).doOnNext(System.out::println).subscribe();
}

服务端错误日志

2025-04-13T00:07:56.235+08:00 ERROR 19972 --- [demo] [tor-http-nio-12] reactor.core.publisher.Operators : Operator called default onErrorDropped

reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.core.codec.DecodingException: JSON decoding error: Unexpected end-of-input within/between Array entries
Caused by: org.springframework.core.codec.DecodingException: JSON decoding error: Unexpected end-of-input within/between Array entries
at org.springframework.http.codec.json.AbstractJackson2Decoder.processException(AbstractJackson2Decoder.java:282) ~[spring-web-6.2.5.jar:6.2.5]
at org.springframework.http.codec.json.AbstractJackson2Decoder.decode(AbstractJackson2Decoder.java:218) ~[spring-web-6.2.5.jar:6.2.5]
at org.springframework.messaging.rsocket.DefaultRSocketRequester$DefaultRequestSpec.lambda$retrieveMono$8(DefaultRSocketRequester.java:299) ~[spring-messaging-6.2.5.jar:6.2.5]
...(后续堆栈信息省略)

解决方案

1. 配置客户端WebSocket帧大小限制

修改客户端传输配置,设置合理的maxFrameSize,让RSocket自动拆分大帧:

const transportOpts = {
  url: 'ws://127.0.0.1:6565',
  debug: true,
  maxFrameSize: 1024 * 1024 // 设置为1MB,根据实际数据调整
}

2. 升级RSocket-JS版本

旧版本的rsocket-websocket-client存在WebSocket分片处理的bug,升级到最新稳定版可修复该问题。

3. 调整服务端RSocket最大帧大小

在Spring Boot配置文件(如application.yml)中增加以下配置,允许服务端接收更大的帧:

spring:
  rsocket:
    server:
      max-frame-size: 16MB # 根据实际数据体积调整

4. 优化数据传输方式

若业务允许,避免一次性返回超大体积数据:

  • 使用RequestStream流式传输替代RequestResponse,分批次返回数据
  • 对数据进行压缩后再传输

内容的提问来源于stack exchange,提问作者linkser lin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:48:11