首页 > 解决方案 > SpringBoot + WebFlux + Reactjs Server Sent Events onmessage not fire up

问题描述

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

在此处输入图像描述

/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", accept(MediaType.APPLICATION_JSON), personRouteHandler::paramsTest)
            POST("posttest", accept(MediaType.APPLICATION_JSON), 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>;
};

标签: reactjsspring-bootkotlinspring-webfluxserver-sent-events

解决方案


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

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

并记得将事件参数更改为“消息”如下

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

推荐阅读