提交 e6a0b39d 编写于 作者: S Sebastien Deleuze

Remove SseHttpMessageConverter

CodecHttpMessageConverter is now suitable for SSE since it now
handles default content type.
上级 59d3721a
...@@ -112,11 +112,14 @@ public class SseEventEncoder extends AbstractEncoder<Object> { ...@@ -112,11 +112,14 @@ public class SseEventEncoder extends AbstractEncoder<Object> {
} }
} }
// Keep the SSE connection open even for cold stream in order to avoid
// unexpected browser reconnection
return Flux.concat( return Flux.concat(
encodeString(sb.toString(), bufferFactory), encodeString(sb.toString(), bufferFactory),
dataBuffer, dataBuffer,
encodeString("\n", bufferFactory), encodeString("\n", bufferFactory),
Mono.just(FlushingDataBuffer.INSTANCE) Mono.just(FlushingDataBuffer.INSTANCE),
Flux.never()
); );
}); });
......
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.converter.reactive;
import java.util.Arrays;
import java.util.List;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.Encoder;
import org.springframework.http.codec.SseEventEncoder;
import org.springframework.http.MediaType;
import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.web.reactive.sse.SseEvent;
/**
* Implementation of {@link HttpMessageConverter} that can stream Server-Sent Events
* response.
*
* It allows to write {@code Flux<ServerSentEvent>}, which is Spring Web Reactive equivalent
* to Spring MVC {@code SseEmitter}.
*
* Sending {@code Flux<String>} or {@code Flux<Pojo>} is equivalent to sending
* {@code Flux<SseEvent>} with the {@code data} property set to the {@code String} or
* {@code Pojo} value.
*
* @author Sebastien Deleuze
* @see SseEvent
* @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommandation</a>
*/
public class SseHttpMessageConverter extends CodecHttpMessageConverter<Object> {
/**
* Constructor that creates a new instance configured with the specified data encoders.
*/
public SseHttpMessageConverter(List<Encoder<?>> dataEncoders) {
super(new SseEventEncoder(dataEncoders), null);
}
@Override
public Mono<Void> write(Publisher<?> inputStream, ResolvableType type,
MediaType contentType, ReactiveHttpOutputMessage outputMessage) {
outputMessage.getHeaders().add("Content-Type", "text/event-stream");
// Keep the SSE connection open even for cold stream in order to avoid unexpected Browser reconnection
return super.write(Flux.from(inputStream).concatWith(Flux.never()), type, contentType, outputMessage);
}
}
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package org.springframework.web.reactive.sse; package org.springframework.web.reactive.sse;
import org.springframework.http.converter.reactive.SseHttpMessageConverter; import org.springframework.http.codec.SseEventEncoder;
import org.springframework.util.MimeType; import org.springframework.util.MimeType;
/** /**
...@@ -26,7 +26,7 @@ import org.springframework.util.MimeType; ...@@ -26,7 +26,7 @@ import org.springframework.util.MimeType;
* {@code SseEmitter} type. It allows to send Server-Sent Events in a reactive way. * {@code SseEmitter} type. It allows to send Server-Sent Events in a reactive way.
* *
* @author Sebastien Deleuze * @author Sebastien Deleuze
* @see SseHttpMessageConverter * @see SseEventEncoder
* @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommandation</a> * @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommandation</a>
*/ */
public class SseEvent { public class SseEvent {
...@@ -95,9 +95,9 @@ public class SseEvent { ...@@ -95,9 +95,9 @@ public class SseEvent {
/** /**
* Set {@code data} SSE field. If a multiline {@code String} is provided, it will be * Set {@code data} SSE field. If a multiline {@code String} is provided, it will be
* turned into multiple {@code data} field lines by as * turned into multiple {@code data} field lines by as
* defined in Server-Sent Events W3C recommandation. * defined in Server-Sent Events W3C recommendation.
* *
* If no {@code mediaType} is defined, default {@link SseHttpMessageConverter} will: * If no {@code mediaType} is defined, default {@link SseEventEncoder} will:
* - Turn single line {@code String} to a single {@code data} field * - Turn single line {@code String} to a single {@code data} field
* - Turn multiline line {@code String} to multiple {@code data} fields * - Turn multiline line {@code String} to multiple {@code data} fields
* - Serialize other {@code Object} as JSON * - Serialize other {@code Object} as JSON
...@@ -117,7 +117,7 @@ public class SseEvent { ...@@ -117,7 +117,7 @@ public class SseEvent {
/** /**
* Set the {@link MimeType} used to serialize the {@code data}. * Set the {@link MimeType} used to serialize the {@code data}.
* {@link SseHttpMessageConverter} should be configured with the relevant encoder to be * {@link SseEventEncoder} should be configured with the relevant encoder to be
* able to serialize it. * able to serialize it.
*/ */
public void setMimeType(MimeType mimeType) { public void setMimeType(MimeType mimeType) {
...@@ -147,8 +147,8 @@ public class SseEvent { ...@@ -147,8 +147,8 @@ public class SseEvent {
/** /**
* Set SSE comment. If a multiline comment is provided, it will be turned into multiple * Set SSE comment. If a multiline comment is provided, it will be turned into multiple
* SSE comment lines by {@link SseHttpMessageConverter} as defined in Server-Sent Events W3C * SSE comment lines by {@link SseEventEncoder} as defined in Server-Sent Events W3C
* recommandation. * recommendation.
*/ */
public void setComment(String comment) { public void setComment(String comment) {
this.comment = comment; this.comment = comment;
......
...@@ -33,7 +33,6 @@ import org.springframework.core.convert.support.DefaultConversionService; ...@@ -33,7 +33,6 @@ import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.io.buffer.support.DataBufferTestUtils; import org.springframework.core.io.buffer.support.DataBufferTestUtils;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.reactive.CodecHttpMessageConverter; import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
import org.springframework.http.converter.reactive.HttpMessageConverter; import org.springframework.http.converter.reactive.HttpMessageConverter;
......
...@@ -29,6 +29,7 @@ import reactor.core.test.TestSubscriber; ...@@ -29,6 +29,7 @@ import reactor.core.test.TestSubscriber;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.codec.Encoder;
import org.springframework.core.codec.support.ByteBufferDecoder; import org.springframework.core.codec.support.ByteBufferDecoder;
import org.springframework.core.codec.support.JacksonJsonDecoder; import org.springframework.core.codec.support.JacksonJsonDecoder;
import org.springframework.core.codec.support.JacksonJsonEncoder; import org.springframework.core.codec.support.JacksonJsonEncoder;
...@@ -36,8 +37,9 @@ import org.springframework.core.codec.support.JsonObjectDecoder; ...@@ -36,8 +37,9 @@ import org.springframework.core.codec.support.JsonObjectDecoder;
import org.springframework.core.codec.support.StringDecoder; import org.springframework.core.codec.support.StringDecoder;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorHttpClientRequestFactory; import org.springframework.http.client.reactive.ReactorHttpClientRequestFactory;
import org.springframework.http.codec.SseEventEncoder;
import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
import org.springframework.http.converter.reactive.HttpMessageConverter; import org.springframework.http.converter.reactive.HttpMessageConverter;
import org.springframework.http.converter.reactive.SseHttpMessageConverter;
import org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests; import org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests;
import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -165,7 +167,8 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests { ...@@ -165,7 +167,8 @@ public class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
@Override @Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) { protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new SseHttpMessageConverter(Arrays.asList(new JacksonJsonEncoder()))); Encoder<Object> sseEncoder = new SseEventEncoder(Arrays.asList(new JacksonJsonEncoder()));
converters.add(new CodecHttpMessageConverter<>(sseEncoder));
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册