【问题标题】:SpringBoot + WebFlux + Reactjs Server Sent Events onmessage not fire upSpringBoot + WebFlux + Reactjs Server Sent Events onmessage not fire up
【发布时间】:2020-12-15 12:23:05
【问题描述】:

我在网络上看到 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>;
};

【问题讨论】:

  • 试着写 eventSource.addEventListener(”open”, ) 值是”open”, ”message”, ”error” 等。看看这里的例子部分 developer.mozilla.org /zh-CN/docs/Web/API/EventSource 看看是否可行
  • 您正在设置事件名称,因此请尝试“periodic-event”
  • @ThomasAndolf 你是对的,事件必须是“消息”而不是“周期性事件”。Thx。

标签: reactjs spring-boot kotlin spring-webflux server-sent-events


【解决方案1】:

只需输入produce(MediaType.TEXT_EVENT_STREAM_VALUE) 您的反应应用程序无法识别您的事件。

【讨论】:

    【解决方案2】:

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

          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();
    

    【讨论】:

      猜你喜欢
      • 2021-08-19
      • 2017-03-02
      • 1970-01-01
      • 2013-08-06
      • 2012-08-18
      • 2015-08-05
      • 1970-01-01
      • 2020-05-26
      相关资源
      最近更新 更多