我正在以通用的方式尝试实现Server-Sent Events的服务器代码,我的应用程序的任何Object都可以向客户端发送消息,所以我决定为SSE实现一个特定的Servlet。初始测试代码就像一个魅力,但不是灵活的,应该从我的应用程序的不同部分发送消息。所以我以一种方式重写代码,所有引用Servlet对象的对象都可以向客户端发送消息:
public class PushServlet extends HttpServlet {
private Thread threadServlet;
private boolean processando=true;
private MensagemSSEBean mensagem;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
threadServlet=Thread.currentThread();
response.setContentType("text/event-stream; charset=utf-8");
while (processando){
if(!pausarThread())
break;
enviarMensagemParaOCliente(response.getWriter());
}
enviarMensagemDeFechamento(response.getWriter());
}
private void enviarMensagemParaOCliente(PrintWriter saida) {
ConversorMensagemSSE conversor = new ConversorMensagemSSE();
saida.print(conversor.converter(mensagem));
saida.flush();
}
private synchronized void enviarMensagemDeFechamento(PrintWriter saida) {
mensagem.setMensagem("#FECHAR_CONEXAO#");
enviarMensagemParaOCliente(saida);
saida.close();
}
public synchronized void enviarMensagem(MensagemSSEBean mensagem) throws IOException {
this.mensagem=mensagem;
threadServlet.notifyAll();
}
public synchronized void finalizar(){
processando=false;
}
private boolean pausarThread() {
try {
threadServlet.wait();
return true;
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
}
如您所见,我暂停Servlet线程直到调用“enviarMensagem”。我没有测试过这段代码,基本上是因为我不知道怎么能得到这个Servlet对象。有人可以解释我怎么能从任何对象获取此Servlet对象?另一个重要的问题是,这是解决这类问题的理想方法吗?
答案 0 :(得分:0)
最后,我以通用的方式实现了它。 servlet类现在每隔十秒发送一次keep-alive,或者在共享队列中发送消息:
public class PushServlet extends HttpServlet {
private boolean processing = true;
private HttpServletResponse response;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.response = response;
configureAndStart();
while (processing) {
try {
sendMessages();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void configureAndStart() throws IOException {
processing = true;
response.setContentType("text/event-stream; charset=utf-8");
sendMessage(new SSEMessageBean(SSEEventType.START));
}
private void sendMessages() throws IOException, InterruptedException {
SSEMessageBean message = MessageQueueController.getInstance().getNextMessage();
while (message != null) {
sendMessage(message);
message = MessageQueueController.getInstance().getNextMessage();
if (message.getEventType() != SSEEventType.END)
return;
}
Thread.sleep(10000);
sendMessage(new SSEMessageBean(SSEEventType.KEEP_ALIVE));
}
public void sendMessage(SSEMessageBean message) throws IOException {
SSEMessageConverter converter = new SSEMessageConverter();
PrintWriter out = response.getWriter();
out.print(converter.convert(message));
out.flush();
if (message.getEventType() == SSEEventType.END) {
processing = false;
out.close();
}
}
}
希望向客户端发送事件的对象只需写入共享队列。