public static int offset(Frame frame) { int length = frame.content().readableBytes(); if (length < FrameHeaderFlyweight.FRAME_HEADER_LENGTH) { throw new IllegalStateException("invalid frame"); } return length - FrameHeaderFlyweight.FRAME_LENGTH_SIZE; } }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Frame)) { return false; } final Frame frame = (Frame) o; return content.equals(frame.content()); }
@Override public int keepAliveMaxLifetime() { return SetupFrameFlyweight.maxLifetime(setupFrame.content()); }
@Override public int keepAliveInterval() { return SetupFrameFlyweight.keepaliveInterval(setupFrame.content()); }
private BinaryWebSocketFrame toBinaryWebSocketFrame(Frame frame) { return new BinaryWebSocketFrame(frame.content().skipBytes(FRAME_LENGTH_SIZE).retain()); } }
@Override public Mono<Void> send(Publisher<Frame> frames) { return Flux.from(frames) .transform( frameFlux -> { if (frameFlux instanceof Fuseable.QueueSubscription) { Fuseable.QueueSubscription<Frame> queueSubscription = (Fuseable.QueueSubscription<Frame>) frameFlux; queueSubscription.requestFusion(Fuseable.ASYNC); return new SendPublisher<>( queueSubscription, frameFlux, connection.channel(), frame -> frame.content().retain(), ByteBuf::readableBytes); } else { return new SendPublisher<>( frameFlux, connection.channel(), frame -> frame.content().retain(), ByteBuf::readableBytes); } }) .then(); } }
/** * Returns a {@link Tuple2} of the stream id, and the frame. This strips the frame length and * stream id header from the abstraction leaking frame. * * @param abstractionLeakingFrame the abstraction leaking frame * @return a {@link Tuple2} of the stream id, and the frame * @throws NullPointerException if {@code abstractionLeakingFrame} is {@code null} */ public static Tuple2<Integer, io.rsocket.framing.Frame> fromAbstractionLeakingFrame( Frame abstractionLeakingFrame) { Objects.requireNonNull(abstractionLeakingFrame, "abstractionLeakingFrame must not be null"); FrameLengthFrame frameLengthFrame = null; StreamIdFrame streamIdFrame = null; try { frameLengthFrame = createFrameLengthFrame(abstractionLeakingFrame.content()); streamIdFrame = frameLengthFrame.mapFrameWithoutFrameLength(StreamIdFrame::createStreamIdFrame); io.rsocket.framing.Frame frame = streamIdFrame.mapFrameWithoutStreamId(FrameFactory::createFrame); return Tuples.of(streamIdFrame.getStreamId(), frame); } finally { disposeQuietly(frameLengthFrame, streamIdFrame); release(abstractionLeakingFrame); } }
@Test(timeout = 2_000) public void testStreamInitialN() { Flux<Payload> stream = rule.socket.requestStream(EmptyPayload.INSTANCE); BaseSubscriber<Payload> subscriber = new BaseSubscriber<Payload>() { @Override protected void hookOnSubscribe(Subscription subscription) { // don't request here // subscription.request(3); } }; stream.subscribe(subscriber); subscriber.request(5); List<Frame> sent = rule.connection .getSent() .stream() .filter(f -> f.getType() != KEEPALIVE) .collect(Collectors.toList()); assertThat("sent frame count", sent.size(), is(1)); Frame f = sent.get(0); assertThat("initial frame", f.getType(), is(REQUEST_STREAM)); assertThat("initial request n", RequestFrameFlyweight.initialRequestN(f.content()), is(5)); }
public static int offset(Frame frame) { int length = frame.content().readableBytes(); if (length < FrameHeaderFlyweight.FRAME_HEADER_LENGTH) { throw new IllegalStateException("invalid frame"); } return length - FrameHeaderFlyweight.FRAME_LENGTH_SIZE; } }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Frame)) { return false; } final Frame frame = (Frame) o; return content.equals(frame.content()); }
@Override public int keepAliveMaxLifetime() { return SetupFrameFlyweight.maxLifetime(setupFrame.content()); }
@Override public int keepAliveInterval() { return SetupFrameFlyweight.keepaliveInterval(setupFrame.content()); }
private BinaryWebSocketFrame toBinaryWebSocketFrame(Frame frame) { return new BinaryWebSocketFrame(frame.content().skipBytes(FRAME_LENGTH_SIZE).retain()); } }
@Override public Mono<Void> send(Publisher<Frame> frames) { return Flux.from(frames) .transform( frameFlux -> { if (frameFlux instanceof Fuseable.QueueSubscription) { Fuseable.QueueSubscription<Frame> queueSubscription = (Fuseable.QueueSubscription<Frame>) frameFlux; queueSubscription.requestFusion(Fuseable.ASYNC); return new SendPublisher<>( queueSubscription, frameFlux, connection.channel(), frame -> frame.content().retain(), ByteBuf::readableBytes); } else { return new SendPublisher<>( frameFlux, connection.channel(), frame -> frame.content().retain(), ByteBuf::readableBytes); } }) .then(); } }
/** * Returns a {@link Tuple2} of the stream id, and the frame. This strips the frame length and * stream id header from the abstraction leaking frame. * * @param abstractionLeakingFrame the abstraction leaking frame * @return a {@link Tuple2} of the stream id, and the frame * @throws NullPointerException if {@code abstractionLeakingFrame} is {@code null} */ public static Tuple2<Integer, io.rsocket.framing.Frame> fromAbstractionLeakingFrame( Frame abstractionLeakingFrame) { Objects.requireNonNull(abstractionLeakingFrame, "abstractionLeakingFrame must not be null"); FrameLengthFrame frameLengthFrame = null; StreamIdFrame streamIdFrame = null; try { frameLengthFrame = createFrameLengthFrame(abstractionLeakingFrame.content()); streamIdFrame = frameLengthFrame.mapFrameWithoutFrameLength(StreamIdFrame::createStreamIdFrame); io.rsocket.framing.Frame frame = streamIdFrame.mapFrameWithoutStreamId(FrameFactory::createFrame); return Tuples.of(streamIdFrame.getStreamId(), frame); } finally { disposeQuietly(frameLengthFrame, streamIdFrame); release(abstractionLeakingFrame); } }