gpt4 book ai didi

javascript - HTML5 EventSource 发送多个请求

转载 作者:行者123 更新时间:2023-11-29 19:13:01 28 4
gpt4 key购买 nike

我正在尝试实现 Server Sent Events使用 Spring SseEmitter如本 Youtube video 中所述.

我能够启动事件流并从服务器发送的事件中接收数据。

但是,我可以看到多个 EventStream 类型的请求从客户端触发并到达服务器。按照我的理解,EventSource 应该发送单个 HTTP 请求,然后应该保持来自服务器的 half duplex 连接,使用哪个服务器发送将事件发送给客户端。

为什么它会定期发送请求?这不是像轮询而不是半双工连接吗?

下面是我正在使用的代码。

服务器代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter.SseEventBuilder;

@RestController
public class TestService {
private List<SseEmitter> subscriberList = Collections.synchronizedList(new ArrayList<>());

@RequestMapping("inbox")
public SseEmitter inbox() {
SseEmitter subscriber = new SseEmitter();
subscriberList.add(subscriber);

subscriber.onCompletion(() -> {
subscriberList.remove(subscriber);
System.out.println("Removed the completed event emitter");
});

System.out.println("Subscriber arrived");
return subscriber;
}

@RequestMapping("message")
public String message(@RequestParam("message") String message) {
System.out.println("SubscriberList size " + subscriberList.size());
for(SseEmitter subscriber : subscriberList) {
try {
SseEventBuilder eventBuilder = SseEmitter.event().name("group1").data(message);
subscriber.send(eventBuilder);
} catch (Exception e) {
e.printStackTrace();
}
};
return message;
}
}

客户端代码

$(function () {
console.log("Started");
var eventSource = new EventSource("/inbox");
eventSource.addEventListener('error', function(e) {
if (e.currentTarget.readyState == EventSource.CLOSED) {
console.log("Connection is closed")
} else {
source.close();
console.log("Closing connection");
}
});
eventSource.addEventListener("group1", function (event) {
console.log(event.data);
document.querySelector("body").innerHTML += "<div>" + event.data + "</div>";
});
});

下面是来自 chrome 的客户端网络标签截图

enter image description here

这是服务器端日志

Subscriber arrived
Removed the completed event emitter
Subscriber arrived
Removed the completed event emitter
Subscriber arrived
Removed the completed event emitter
Subscriber arrived
Removed the completed event emitter
Subscriber arrived
Removed the completed event emitter
Subscriber arrived
Removed the completed event emitter
Subscriber arrived

最佳答案

这里的问题是服务器意外地关闭了连接,而不是在保持连接打开的同时完成它的工作。当发生这种情况时,客户端重新发送请求以打开连接并开始流式传输服务器发送的事件。然后服务器一次又一次地关闭连接,导致无限循环。

确保这种情况的一种方法是设置 retry 字段以增加浏览器的等待时间(默认约为 2-3 秒)。另一种方法是在服务器端有一个 while (true) {},就在请求到达之后。

另请查看 this post关于 SSE。

关于javascript - HTML5 EventSource 发送多个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37403300/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com