启动服务端
自动装配:
public class RSocketServerAutoConfiguration {
@ConditionalOnProperty(prefix = "spring.rsocket.server", name = "port")
static class EmbeddedServerAutoConfiguration {
@Bean
@ConditionalOnMissingBean
RSocketServerBootstrap rSocketServerBootstrap(RSocketServerFactory rSocketServerFactory,
RSocketMessageHandler rSocketMessageHandler) {
return new RSocketServerBootstrap(rSocketServerFactory, rSocketMessageHandler.responder());
}
}
}
RSocketServerFactory:
- 管理RSocket服务的配置,比如端口。
- 创建RSocket服务,需要参数SocketAcceptor。
SocketAcceptor:
接收创建连接的消息(payload),返回处理远程请求的响应者(responder)。
RSocketMessageHandler:
- 管理消息编解码RSocketStrategies。
- 管理消息处理器(AbstractMethodMessageHandler.handlerMethods)。
RSocketServerBootstrap:
管理RSocket服务启动和关闭。
连接服务端
示例代码:
public RSocketRequester connect(RSocketRequester.Builder rsocketRequesterBuilder, RSocketStrategies strategies) {
String client = UUID.randomUUID().toString();
log.info("Connecting using client ID: {}", client);
SocketAcceptor acceptor = RSocketMessageHandler.responder(strategies, new ClientHandler());
RSocketRequester rsocketRequester = rsocketRequesterBuilder.setupRoute("shell-client")
.setupData(client)
.rsocketStrategies(strategies)
.rsocketConnector(connector -> connector.acceptor(acceptor).resume(new Resume()))
.connectTcp("localhost", 7000)
.block();
rsocketRequester.rsocket()
.onClose()
.doOnError(er -> log.error("connection closed.", er))
.doFinally(c -> log.info("connection disconnected"))
.subscribe();
return rsocketRequester;
}
RSocketMessageHandler.responder:
- RSocketMessageHandler的工厂方法,提供消息编解码器、消息处理器,构造SocketAcceptor。
- SocketAcceptor需要实现accept接口,返回responder,responder通过RSocketMessageHandler.createResponder构建。
RSocketMessageHandler.createResponder:
创建MessagingRSocket,MessagingRSocket.handle()调用消息处理器处理消息。
rsocketRequesterBuilder.setupRoute().setupData():
创建连接时附加的信息
connector.resume(new Resume()):
连接断开后,自动恢复
RSocketRequester:
负责发送消息
发送消息
示例代码:
private RSocketRequester rsocketRequester;
public void requestResponse() throws InterruptedException {
this.rsocketRequester
.route("request-response")
.data(new Message())
.retrieveMono(Message.class)
.subscribe(m -> {
log.info("\nResponse was: {}", m);
});
}
- 四种交互模式:Request-Response、Request-Stream、Channel、Fire-and-Forget。示例中演示的是Request-Response。
- RSocketRequester的实现类为DefaultRSocketRequester,通过持有的rsocketClient:RSocketClientAdapter来发送消息。 RSocketClientAdapter:
class RSocketClientAdapter implements RSocketClient {
private final RSocket rsocket;
public Mono<Payload> requestResponse(Mono<Payload> payloadMono) {
return payloadMono.flatMap(rsocket::requestResponse);
}
}
RSocket的实现类为RSocketRequester。
RSocketRequester:
class RSocketRequester implements RSocket {
public Mono<Payload> requestResponse(Payload payload) {
return new RequestResponseRequesterMono(payload, this);
}
}
RequestResponseRequesterMono:
final class RequestResponseRequesterMono extends Mono<Payload> implements Subscription {
public final void request(long n) {
sendFirstPayload(this.payload, n);
}
void sendFirstPayload(Payload payload, long initialRequestN) {
int streamId = = sm.addAndGetNextStreamId(this);
sendReleasingPayload(streamId, FrameType.REQUEST_RESPONSE, this.mtu, payload, connection, allocator, true);
}
static void sendReleasingPayload(
int streamId,
FrameType frameType,
int mtu,
Payload payload,
DuplexConnection connection,
ByteBufAllocator allocator,
boolean requester) {
boolean fragmentable = isFragmentable(mtu, data, metadata, false);
if (fragmentable) {
ByteBuf first = FragmentationUtils.encodeFirstFragment(
allocator, mtu, frameType, streamId, hasMetadata, slicedMetadata, slicedData);
connection.sendFrame(streamId, first);
while (slicedData.isReadable() || slicedMetadata.isReadable()) {
final ByteBuf following =
FragmentationUtils.encodeFollowsFragment(
allocator, mtu, streamId, complete, slicedMetadata, slicedData);
connection.sendFrame(streamId, following);
}
} else {
...
}
}
}
数据包太大的时候,会分成多个Frame发送。
接收消息
处理消息的两种形式:
- 请求-响应式,发送请求后在Subscriber中处理,比如发送消息中给出的示例。
- 通过@MessageMapping或@ConnectMapping注册处理函数。
所以,我们分析一下接收消息到处理消息的流程。
DuplexConnection:
- RSocketRequester和RSocketResponder构造时需要提供参数DuplexConnection。
- tcp连接的实现为TcpDuplexConnection,如果开启自动重连,实现为ResumableDuplexConnection,持有activeConnection:TcpDuplexConnection。
ResumableDuplexConnection:
public class ResumableDuplexConnection extends Flux<ByteBuf> implements DuplexConnection, Subscription {
void initConnection(DuplexConnection nextConnection) {
final FrameReceivingSubscriber frameReceivingSubscriber =
new FrameReceivingSubscriber(tag, resumableFramesStore, receiveSubscriber);
nextConnection.receive().subscribe(frameReceivingSubscriber);
}
}
FrameReceivingSubscriber:
class FrameReceivingSubscriber implements CoreSubscriber<ByteBuf> {
final CoreSubscriber<? super ByteBuf> actual;
private FrameReceivingSubscriber(
String tag, ResumableFramesStore store, CoreSubscriber<? super ByteBuf> actual) {
this.tag = tag;
this.resumableFramesStore = store;
this.actual = actual;
}
@Override
public void onNext(ByteBuf frame) {
actual.onNext(frame);
}
}
FrameReceivingSubscriber包装了CoreSubscriber actual,actual的类型为ClientServerInputMultiplexer。
ClientServerInputMultiplexer:
class ClientServerInputMultiplexer implements CoreSubscriber<ByteBuf> {
private final InternalDuplexConnection serverReceiver;
private final InternalDuplexConnection clientReceiver;
private final DuplexConnection serverConnection;
private final DuplexConnection clientConnection;
private final DuplexConnection source;
private final boolean isClient;
public void onNext(ByteBuf frame) {
int streamId = FrameHeaderCodec.streamId(frame);
final Type type;
if (streamId == 0) {
switch (FrameHeaderCodec.frameType(frame)) {
case LEASE:
case KEEPALIVE:
case ERROR:
type = isClient ? Type.CLIENT : Type.SERVER;
break;
default:
type = isClient ? Type.SERVER : Type.CLIENT;
}
} else if ((streamId & 0b1) == 0) {
type = Type.SERVER;
} else {
type = Type.CLIENT;
}
switch (type) {
case CLIENT:
clientReceiver.onNext(frame);
break;
case SERVER:
serverReceiver.onNext(frame);
break;
}
}
}
clientReceiver和serverReceiver应该对应了开始提到了处理消息的两种形式。
回到RSocketRequester的构造逻辑:
class RSocketRequester extends RequesterResponderSupport implements RSocket {
RSocketRequester(DuplexConnection connection, ...) {
connection.receive().subscribe(this::handleIncomingFrames, e -> {});
}
private void handleIncomingFrames(ByteBuf frame) {
int streamId = FrameHeaderCodec.streamId(frame);
FrameType type = FrameHeaderCodec.frameType(frame);
if (streamId == 0) {
handleStreamZero(type, frame);
} else {
handleFrame(streamId, type, frame);
}
}
private void handleFrame(int streamId, FrameType type, ByteBuf frame) {
FrameHandler receiver = this.get(streamId);
switch (type) {
case NEXT_COMPLETE:
receiver.handleNext(frame, false, true);
break;
case NEXT:
boolean hasFollows = FrameHeaderCodec.hasFollows(frame);
receiver.handleNext(frame, hasFollows, false);
break;
...
}
}
}
class FireAndForgetResponderSubscriber implements CoreSubscriber<Void>, ResponderFrameHandler {
@Override
public void handleNext(ByteBuf followingFrame, boolean hasFollows, boolean isLastPayload) {
final CompositeByteBuf frames = this.frames;
ReassemblyUtils.addFollowingFrame(
frames, followingFrame, hasFollows, this.maxInboundPayloadSize);
if (!hasFollows) {
this.requesterResponderSupport.remove(this.streamId, this);
this.frames = null;
Payload payload = this.payloadDecoder.apply(frames);
frames.release();
Mono<Void> source = this.handler.fireAndForget(payload);
source.subscribe(this);
}
}
}
- FrameHandler实现包括FireAndForgetResponderSubscriber、RequestResponseResponderSubscriber等等,可以看出和交互方式有对应关系。
- NEXT和NEXT_COMPLETE表明一个消息会拆成多个Frame,在接收端完成组装。