【问题标题】:text/event-stream render in grails from scratch(without plugin)从头开始在 grails 中呈现文本/事件流(无插件)
【发布时间】:2014-01-28 10:14:14
【问题描述】:

要使用push方法,我们使用著名的JS对象EventSource:

这是很容易开发的客户端部分:

        var eventSource = new EventSource("controller/action");

        eventSource.onmessage = function(event) {

            document.getElementById('foo').innerHTML = event.data;

        };

但是,我很难在服务器部分(Grails)中配置推送方法。

当我查看由 Servlets 开发的 JEE 应用程序时,我可以看到服务器部分如下:

http://viralpatel.net/blogs/html5-server-sent-events-java-servlets-example/

public class TestServlet extends HttpServlet {


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //content type must be set to text/event-stream
        response.setContentType("text/event-stream");  

        //encoding must be set to UTF-8
        response.setCharacterEncoding("UTF-8");

        PrintWriter writer = response.getWriter();

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

            writer.write("data: "+ System.currentTimeMillis() +"\n\n");

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

将此 servlet 转换为动作控制器:

def push(){

        render(contentType:'text/event-stream',characterEncoding:'UTF-8'){
              [dt:"data: "+ System.currentTimeMillis() +"\n\n"]             
        }
}

在客户端部分:

 var eventSource = new EventSource(baseURL+"external/push");
 eventSource.onmessage=function(e){
     console.log(e.data.dt);
 }

不幸的是,我在控制台没有得到任何结果。

【问题讨论】:

    标签: servlets grails controller push


    【解决方案1】:

    我不确定渲染方法是否能正确处理'text/event-stream',但您可以直接访问操作中的response 对象:

    def push() {
      //content type must be set to text/event-stream
      response.setContentType("text/event-stream");  
    
      //encoding must be set to UTF-8
      response.setCharacterEncoding("UTF-8");
    
      for(int i=0; i<10; i++) {
    
        response.outputStream.write("data: "+ System.currentTimeMillis() +"\n\n");
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      response.outputStream.flush()
    }
    

    【讨论】:

    • 我知道这个方法并且我已经使用它了,但是,我想使用优雅的 render 语法 render(contentType:'text/event-stream'){}
    【解决方案2】:
    def push = {
        response.setContentType("text/event-stream");
        for(def i=0;i<10;i++) {
            render("data $i: ${System.currentTimeMillis()}\n");
            sleep(1000)
        }
    }
    

    【讨论】:

    • 您可能需要解释您的答案,以便提问者了解问题所在
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 2022-01-25
    • 2012-04-06
    相关资源
    最近更新 更多