Basic env info:
OS: mac os 10.15.4 JDK: openjdk8 Springboot version: 2.3.4.RELEASE
Reproduce:
I create a spring rsocket client as follows. The requesterMono object is prepared for sending data.
// prepare requester object
Mono<RSocketRequester> requesterMono = rsocketRequesterBuilder.setupRoute("conn-setup")
.setupData(new ObjectMapper().writeValueAsString(connAuthDTO))
.dataMimeType(MimeTypeUtils.parseMimeType(WellKnownMimeType.APPLICATION_JSON.getString()))
.rsocketConnector(connector -> connector.acceptor(responder)
.fragment(MTU_BYTE_SIZE)
.keepAlive(Duration.ofSeconds(KEEP_ALIVE_INTERVAL_SEC), Duration.ofSeconds(KEEP_ALIVE_MAX_TIME_SEC))
.reconnect(Retry.fixedDelay(Integer.MAX_VALUE, Duration.ofSeconds(RSOCKET_RETRY_INTERVAL_SECONDS))
.doAfterRetry(retrySignal -> log.warn("RSocket client is reconnecting to get the newest connection...."))))
.connect(TcpClientTransport.create(TcpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, TCP_CONN_TIMEOUT)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.SO_KEEPALIVE, true)
.host(clientAuthManager.acquireServerDomain())
.port(SERVER_PORT)
.secure(ssl -> ssl.sslContext(sslContext))));
//send data with requesterMono
public RSocketRequester getWorkingRequester() {
RSocketRequester requester = requesterMono.block(Duration.ofSeconds(1));
if (requester == null || requester.rsocket().isDisposed()) {
throw new RuntimeException("try to get rsocket requester ,but it is ABNORMAL....");
}
return requester;
}
The expected setup payload should be a json value of ConnAuthDTO.
public class ConnAuthDTO {
private String ak;
private String sk;
private String ip;
/**
* sidecar's unique identify
*/
private String wsn;
private long sendAuthTimeMs;
}
The rsocket client have another schedule thread periodically send rsocket request like invoke method 'updateWorkerState' to send data by rsocket . The request will invoke getWorkingRequester to get the requester and send data. The data payload's related class is :
@Data
public class WorkerUpdateDTO {
private WorkerIdentity workerIdentity;
private WorkerState workerState;
private String localIp;
private String externalIp;
private boolean needUpdateLocalIp;
private boolean needUpdateExternalIp;
private Date sendDate;
}
//WorkerIdentity definition
@Data
@Builder
public class WorkerIdentity {
@Tolerate
public WorkerIdentity(){
}
private String workerSeqNumber;
private String accessKey;
private String localIp;
}
When server is restarted, client will try to reconnect and I will see the first stream is always retrying and its payload is not what we expected. The setup payload is not complete and it is just a part of WorkerUpdateDTO's json value.
I think it is a concurrency issue. Other thread's payload data will replace the correct setup payload during reconnecting. Is it a bug of spring rsocket?
Comment From: OlegDokuka
do you have logs of what was on the sender side to ensure it is not a network corruption?
Comment From: KaimingWan
@OlegDokuka I didn't set the log level to debug in client at that time. Now I enable the debug log level in client to see whether the issue occur again. By the way, I can't see the setup payload frame's frame log in the client even when I enable the debug log and restart the client. Are there something wrong?
Comment From: KaimingWan
@OlegDokuka I got the same exception recently. I restart the server and find server receive the unexpected data as I mentioned before. This time I enable the client's debug log and find there still not exists log related to setup payload. The first frame after client's success retry is nothing to do with setup payload
Comment From: KaimingWan
The failed stream in client side is keep retrying
Comment From: wilkinsona
This doesn't appear to be a Spring Boot-specific problem. @oleg-sukhov if you agree, do you think this belongs in the Spring Framework issue tracker or RSocket's issue tracker?
Comment From: KaimingWan
@wilkinsona I think this issue have some relationship with spring-rsocket projects in my view. I have configured the setup payload and what setup data to send when connection is created. Why after connection is recreated the client didn't send setup payload as I configured in my code. Normally, the setup payload ( ConnAuthDTO's json value) should be sent. Do I miss something important?
Comment From: OlegDokuka
@wilkinsona I belive you wanted to mention me.
Yeah, I guess I can move it to rsocket-java issue tracker to do the following investigations
Comment From: wilkinsona
Oops, sorry. I did indeed. In the meantime, @bclozel's transferred this to Framework.
Comment From: OlegDokuka
actually, we already have it in our issue tracker -> https://github.com/rsocket/rsocket-java/issues/970
Comment From: bclozel
Thanks @OlegDokuka , we're going to close this one for now - we can reopen it if there's something to be done in Spring Framework.