SpringBoot + WebFlux + Reactjs服务器已发送事件onmessage无法启动

问题描述

我在网络上看到了EventStream,但是我的clientSource.onmessage没有在客户端上启动。我没有发现很多示例将WebFlux功能端点用于SSE。我在做什么错了?

enter image description here

其中/ sseget是我的SSE端点的路由器:

@Component
class PersonRouter {

    @Bean
    fun personRoutes(personRouteHandler: PersonRouteHandler) = coRouter {
        "/person".nest {
            GET("/",personRouteHandler::getTest)
           // GET("findById",accept(MediaType.APPLICATION_JSON),personRouteHandler::)
            GET("paramstest",personRouteHandler::paramsTest)
            POST("posttest",personRouteHandler::postTest)
        }

        "/sse".nest {
            GET("/sseget",personRouteHandler::sseGet)
        }
    }
}

处理程序:

 suspend fun sseGet(request: ServerRequest): ServerResponse {
        val result = Flux.interval(Duration.ofSeconds(3))
                .map{
                    ServerSentEvent.builder<String>()
                            .id(it.toString())
                            .event("periodic-event")
                            .data("SSE - " + LocalTime.Now())
                            .comment("nejaky comment")
                            .retry(Duration.ofSeconds(10))
                            .build()
                }

        return ServerResponse
                .ok()
                .body(BodyInserters.fromServerSentEvents(result)).awaitSingle()
    }

ReactJs客户:

const ServerSideEventExample: React.FC<IProps> = (props) => {
  const [listening,setListening] = useState(false);

  useEffect(() => {
    let eventSource: EventSource | undefined = undefined;

    debugger;
    if (!listening) {
      debugger;
      eventSource = new EventSource("http://localhost:8085/sse/sseget");
      eventSource.onopen = (event) => {
        debugger;
        console.log(event);
      };
      eventSource.onmessage = (event) => {
        debugger;
        console.log(event);
      };
      eventSource.onerror = (err) => {
        debugger;
        console.error("EventSource Failed:",err);
      };
      setListening(true);
    }
    return () => {
      if (eventSource) {
        eventSource.close();
        console.log("event closed");
      }
    };
  },[]);

  return <div>a</div>;
};

解决方法

仅放置produce(MediaType.TEXT_EVENT_STREAM_VALUE)您的react应用程序无法识别您的事件。

,

将内容类型添加到您的服务器响应中,如下所示:

      return ServerResponse
         .ok()
         .contentType(MediaType.TEXT_EVENT_STREAM)
         .body(BodyInserters.fromServerSentEvents(result)).awaitSingle()

记得把事件参数改成“message”如下

                  .id("Your ID")
                  .event("message") //<=== HERE
                  .data({your event here})
                  .comment("any comment")
                  .build();