Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现通用服务器发送事件Servlet_Java_Jakarta Ee_Servlets - Fatal编程技术网

Java 如何实现通用服务器发送事件Servlet

Java 如何实现通用服务器发送事件Servlet,java,jakarta-ee,servlets,Java,Jakarta Ee,Servlets,我正在尝试以一种通用的方式实现的服务器代码,我的应用程序的任何对象都可以向客户端发送消息,所以我决定只为SSE实现一个特定的Servlet。最初的测试代码很有魅力,但不够灵活,无法从应用程序的不同部分发送消息。因此,我重写了代码,使所有引用Servlet对象的对象都可以向客户端发送消息: public class PushServlet extends HttpServlet { private Thread threadServlet; private boolean pro

我正在尝试以一种通用的方式实现的服务器代码,我的应用程序的任何对象都可以向客户端发送消息,所以我决定只为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线程,直到有人调用“EnviarmEnsagement”。我没有测试这段代码,基本上是因为我不知道如何获得这个Servlet对象。有人能告诉我如何从任何对象获取这个Servlet对象吗??另一个重要的问题是,这是解决此类问题的理想方法吗???

最后,我以一种通用的方式实现了它。servlet类现在每10秒发送一次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();
        }
    }
}
想要向客户端发送事件的对象只需写入共享队列