0

アプリケーションの任意のオブジェクトがクライアントにメッセージを送信できる一般的な方法でServer-Sent Eventsのサーバー コードを実装しようとしているので、SSE 専用の特定のサーブレットを実装することにしました。最初のテスト コードは魅力的に機能しましたが、アプリケーションのさまざまな部分からメッセージを送信できるほど柔軟ではありませんでした。そこで、サーブレット オブジェクトへの参照を持つすべてのオブジェクトがクライアントにメッセージを送信できるように、コードを書き直しました。

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;
    }
}

ご覧のとおり、"enviarMensagem" が呼び出されるまでサーブレット スレッドを一時停止します。このコードはテストしていません。基本的に、このサーブレット オブジェクトを取得する方法がわからないためです。このサーブレットオブジェクトを任意のオブジェクトから取得する方法を誰かに説明してもらえますか?? もう 1 つの重要な質問ですが、これはこの種の問題に対する理想的なアプローチですか??

4

1 に答える 1

0

最後に、一般的な方法で実装しました。サーブレット クラスは、10 秒ごとにキープアライブを送信するか、共有キュー内のメッセージを送信するようになりました。

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();
        }
    }
}

イベントをクライアントに送信したいオブジェクトは、単に共有キューに書き込みます。

于 2012-10-09T20:01:07.247 に答える