Grails服务器发送事件

时间:2015-04-10 17:03:31

标签: javascript grails server-sent-events

我需要使用Grails处理服务器发送事件。我觉得我很亲近,但就在那里。 JavaScript请求成功到达控制器,但每次都会抛出错误。它每2秒钟左右重试一次(可能是由于错误)。

当服务器的会话计时器低于5分钟时,我需要向用户发送一个事件。我正在尝试使用HTML5的EventSource,因为我只想向服务器发送一个请求(多次请求每次都会重置会话计时器)。根据{{​​3}},HTML5符合我的需要。

- 的的Javascript -

console.log("Starting eventSource");
var eventSource = new EventSource("SSETest/push");
console.log("Started eventSource");
eventSource.onmessage   = function(event) { console.log("Message received: " + event.data); };
eventSource.onopen      = function(event) { console.log("Open " + event); };
eventSource.onerror     = function(event) { console.log("Error " + event); };
console.log("eventState: " + eventSource.readyState);
// Stop trying after 10 seconds of errors
setTimeout(function() {eventSource.close();}, 10000);

- Grails控制器 -

package sessionManager
class SSETestController {
    def push = {
        println "$request made it!"
        response.setContentType("text/event-stream, charset=UTF-8")
        response << "data: the data"
        render "HI"
    }
}

- Grails控制台 -

org.apache.catalina.core.ApplicationHttpRequest@4f889fad made it!
org.apache.catalina.core.ApplicationHttpRequest@13f78b8c made it!
org.apache.catalina.core.ApplicationHttpRequest@4b50734c made it!
org.apache.catalina.core.ApplicationHttpRequest@4c4bde24 made it!

- JavaScript控制台 -

Starting eventSource
Started eventSource
eventState: 0
Open [object Event] 
Error [object Event] 
Open [object Event] 
Error [object Event]
Open [object Event] 
Error [object Event]
Open [object Event]
Error [object Event]

提前致谢, 克里斯汉考克

2 个答案:

答案 0 :(得分:3)

在Grails控制器中,您需要更改为以下内容:

package sessionManager
class SSETestController {
    def push = {
        println "$request made it!"
        response.setContentType("text/event-stream, charset=UTF-8")
        //response << "data: the data\n\n"
        render "data: the data\n\n"
    }
}

在基本形式中,响应应包含“data:”行,后跟您的消息,后跟两个“\ n”字符以结束流:

data: My message\n\n

现在控制台中的响应是:

Starting eventSource
Started eventSource
eventState: 0
Open [object Event]
Message received: the data
Error [object Event]
Open [object Event]
Message received: the data
Error [object Event]
Open [object Event]
Message received: the data
Error [object Event]
Open [object Event]
Message received: the data
Error [object Event]

有关详细信息,请查看http://www.html5rocks.com/en/tutorials/eventsource/basics/

<强>更新

  

为什么每次都会抛出错误?

例如,可能有不同的错误原因:网络超时。在我们的例子中,这是由于服务器和浏览器之间的连接关闭。

  

为什么它会不断ping服务器?

浏览器获取the data后,服务器和浏览器之间的连接将关闭。因此,浏览器会在每次连接关闭后大约3秒钟重新连接。

  

我认为当JavaScript运行时,HTML5应该连接一次   第一次,只要控制器发送就接收事件   它们。

它应该始终与服务器连接但不能连接一次 是的,只要控制器发送消息,它就会收到事件。但在我们的例子中,服务器/控制器只发送data: the data\n\n并关闭连接 为了连续接收消息,您需要在控制器操作中进行循环。例如:

package sessionManager
class SSETestController {
    def push = {
        println "$request made it!"
        response.setContentType("text/event-stream, charset=UTF-8")
        for(int i = 0 ; i < 10 ; i++){
            render "data: the data\n\n"
            Thread.sleep(1000)
        }
        render "data: finished\n\n"
    }
}

您也可以使用while(true)循环。

如果您想了解onerror的更多信息,可以看到此链接http://www.htmlgoodies.com/beyond/reference/receive-updates-from-the-server-using-the-eventsource.html 根据以上链接,

  

有一个onerror()事件处理程序,但它没有你那么有用   可能会想。然而,它可以告诉我们一些关于什么的事情   发生了,感谢EventSource的readyState属性。对于   例如,EventSource.CONNECTING的值表示连接   丢失了,EventSource正在尝试重新连接。如果有的话   非常错误,EventSource.CLOSED的值会让你知道。   除此之外,由于没有错误,您无法获得更多信息   要查询的对象。相反,它是传递的事件对象本身   到处理程序。可以通过eventSource或访问EventSource   eventTarget属性,因为它们都指向同一个对象。

答案 1 :(得分:0)

请注意,在Grails 3.2中,通过RxJava插件对服务器发送事件进行本机支持 - https://grails.org/plugins.html#plugin/rxjava

example application也可用。

相关问题