我正在尝试使用 Spring SseEmitter实现服务器发送事件,如本Youtube 视频中所述。
我能够启动事件流并从服务器发送事件接收数据。
但是,我可以看到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>";
});
});
Bellow 是来自 chrome 的客户端网络选项卡屏幕截图
这是服务器端日志
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