当谈到 SSE 时,我一直在寻求回答同样的问题,这是我的研究:
我有一个基本的 javax HttpServlet,它将每隔随机秒将数据打印到 PrintWriter。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
System.out.println("You just entered the doGetMethod");
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
PrintWriter printWriter = null;
while(true){
try{
System.out.println("You just entered the while loop");
double randomNumber = Math.random()*10000;
printWriter = response.getWriter();
printWriter.print("data: " + "[next server time check event in " +
Math.round(randomNumber/1000) + " seconds]\n");
printWriter.print("data: " + "Time: " + Calendar.getInstance().getTime() + "\n\n");
response.flushBuffer();
Thread.sleep((long)randomNumber);
} catch (IOException | InterruptedException e){
e.printStackTrace();
break;
}
}
System.out.println("Connection was aborted");
}
这是填充 {textarea id="displayTextArea} 元素的脚本
<script>
var eventSource = null;
function start(){
eventSource = new EventSource('http://localhost:8080/SSEServlet');
eventSource.onopen = function(){displayTextArea.value+='Connected ..' + '\n';};
eventSource.onmessage = function(message){displayTextArea.value+=message.data + '\n\n';};
eventSource.onerror = function(){displayTextArea.value+='Error Occurred...' + '\n';};
}
function stop(){
eventSource.close();
}
function clearText(){
displayTextArea.value = '';
}
</script>
-回答您的第一个问题:
如果您在运行应用程序时观察控制台,您会注意到控制台不会打印“您刚刚输入 doGetMethod”,直到您向 servlet 路径发送 HTTP GET 请求。这证实了在有人调用 servlet 之前不会创建 Servlet 实例和 req/resp 对象的理解。servlet 是如何工作的?
-第二和第三个问题:
默认情况下,Tomcat 会为每个连接分配一个线程(Source)。在我当前的配置中,我的程序最多可以连接 6 个连接。每个连接都将创建自己的 servlet 实例,并且当连接打开时,将停留在 while 循环中。当我运行服务器并打开单独的连接,看到不同的时间和随机间隔序列时,这一点得到了证明。虽然我的while循环不是无限的,它一直等到连接关闭,然后抛出异常并中断while循环。连接关闭后,servlet 将关闭。
我这样做的方式是非常业余的 SSE 方式。如果您想为此学习高级库,我会查看jeaSSE
如果有人想要完整的代码