2018年2月3日 星期六

「HTML5][Java] Server-Sent Events

Server-Sent Events

W3Schools上的說明:

server-sent event is when a web page automatically gets updates from a server.
This was also possible before, but the web page would have to ask if any updates were available. With server-sent events, the updates come automatically.
Examples: Facebook/Twitter updates, stock price updates, news feeds, sport results, etc.


簡單來說SSE的特點為"One Way Messaging" ,也就是Client端被動接收Server端訊息。

過去HTTP 都是一個單一回合結束,如果要取得新的資料,必須重新發送一次

HTTP Request,而SSE則是可以持續接收Server資訊,無須主動發送Request ,

但Client端無法透過SSE與Server端進行溝通,這是與webSocket不同的地方。

以下有一個範例,利用Java Servlet 透過SSE的方式與Client端JavaScript溝通.

當下按Start Button後,JavaScript會開始接收由Server端傳送過來的SSE資料,並更新

在網頁上。

Client端程式碼
<!DOCTYPE HTML>
<html>
    <head>
        <title>Server-Sent Events Servlet example</title>
        <script>
            function start() {
                var eventSource = new EventSource("Server");
                eventSource.onmessage = function (event) {
                    document.getElementById('myDiv').innerHTML = event.data;
                }
            }
            ;

        </script>
        <style>
            body {
                font-family: sans-serif;
            }
        </style>
    </head>
    <body>

        Time: <span id="myDiv"></span>

        <br><br>
        <button onclick="start()">Start</button>


    </body>
</html>


Server端Servlet程式碼
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author boywhychen
 */
public class Server extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");

        PrintWriter writer = response.getWriter();

        for (int i = 0; i < 20; i++) {

            writer.write("data: " + getTime() + "\n\n");
            writer.flush();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        writer.close();
    }

    private String getTime() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        return sdf.format(cal.getTime());
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}


參考資料來源:

https://gist.github.com/viralpatel/7007662

沒有留言:

張貼留言