Grails服务器发送事件 [英] Grails Server Sent Event

查看:111
本文介绍了Grails服务器发送事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要得到服务器发送的事件与Grails一起工作。我觉得我很接近,但不是那样。 JavaScript请求成功到达控制器,但每次都会引发错误。它会每2秒左右重试一次(可能是由于错误)。

当服务器的会话计时器低于5分钟时,我需要向用户发送一个事件。我试图使用HTML5的EventSource,因为我只想发送一个请求到服务器(多个请求将重置会话计时器每次)。根据精益Java工程,HTML5符合我的需求。


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);
//在10秒的错误后停止尝试
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:data
renderHI
}
}

- Grails控制台 -

  org.apache.catalina.core.ApplicationHttpRequest@4f889fad made它! 
org.apache.catalina.core.ApplicationHttpRequest@13f78b8c做到了!
org.apache.catalina.core.ApplicationHttpRequest@4b50734c做到了!
org.apache.catalina.core.ApplicationHttpRequest@4c4bde24做到了!

- JavaScript控制台 -

 启动eventSource 
启动eventSource
eventState:0
打开[object Event]
错误[object Event]
打开[object Event]
Error [object Event]
打开[object Event]
Error [object Event]
打开[object Event]
Error [object Event ]

预先感谢,
Chris Hancock



 <$ c $ 

c> package sessionManager $ b $ class class SSETestController {
def push = {
println$ request made it!
response.setContentType(text / event-stream,charset = UTF-8)
//响应<< data:data \\\
\\\

renderdata:the data \\\
\\\

}
}

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

  data:My message \\\
\\\

现在控制台中的响应是:

 启动eventSource 
启动eventSource
eventState:0
打开[object Event]
收到的消息:数据
Error [object Event]
打开[object Event]
收到的消息:数据
错误[对象事件]
打开[对象事件]
收到的消息:数据
错误[对象事件]
打开[对象事件]
收到的消息:数据
错误[对象事件]

更多详细信息,请参阅 http://www.html5rocks .com / en / tutorials / eventsource / basics /

更新


为什么每次都会抛出一个错误,但是?

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


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


在浏览器获取数据后,服务器和浏览器之间的连接关闭。所以浏览器会在每次连接关闭后大概3秒钟重新连接。


我认为HTML5应该在JavaScript运行时连接一次
第一次,并且只要控制器发送
他们就会收到事件。

它应该有始终与服务器连接,但不能连接一次。

只要控制器向他们发送消息,它就会收到事件。但在我们的例子中,服务器/控制器只发送 data:data \\\
\\\
并且连接已关闭。

为了接收消息不断地,你需要在控制器动作中有循环。例如:

  package sessionManager 
class SSETestController {
def push = {
println $请求了!
response.setContentType(text / event-stream,charset = UTF-8)
for(int i = 0; i <10; i ++){
renderdata:the data \\\
\\\

Thread.sleep(1000)
}
renderdata:finished \\\
\\\

}
}

您也可以使用 while while(true) loop 。



如果您想详细了解 onerror ,您可以看到 http://www.htmlgoodies.com/beyond/reference/receive - 从服务器使用-the-eventsource.html


根据上述链接,


有一个onerror()事件处理函数,但它不如
想象的那么有用。但是,由于EventSource的readyState属性,它可以告诉我们关于
发生了什么的一些事情。对于
实例,EventSource.CONNECTING的值意味着连接
丢失,并且EventSource正试图重新连接。如果某些
变得非常错误,那么EventSource.CLOSED的值会让你知道。
除此之外,您不能获取太多的信息,因为没有错误
对象可供查询。相反,事件对象本身是通过
传递给处理程序的。可以通过eventSource或
eventTarget属性访问EventSource,因为它们都指向相同的对象。



I need to get Server-sent-events working with Grails. I feel like I am close, but just not quite there. The JavaScript request successfully reaches the controller, but it throws an error every time. It keeps retrying once every 2 seconds or so (probably due to the error).

I need to send an event to the user when the server's session timer gets below 5 minutes. I am trying to use HTML5's EventSource because I only want to send a single request to the server (multiple requests will reset the session timer each time). According to Lean Java Engineering, HTML5 meets my need.

-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 Controller-

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 Console-

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 Console-

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]

Thanks in advance, Chris Hancock

解决方案

In Grails controller, you need to change to something like this :

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

In its basic form, the response should contain a "data:" line, followed by your message, followed by two "\n" characters to end the stream:

data: My message\n\n

Now the response in console is :

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]

For more details you can look on http://www.html5rocks.com/en/tutorials/eventsource/basics/.

UPDATE

Why does it throw an error every time, though?

There can be different reason for error for example : network timeout. In our case, it is due to connection being closed between server and browser.

Why does it continually ping the server?

The connection between server and browser is closed after browser gets the data. So the browser tries to reconnect roughly 3 seconds after each connection is closed.

I thought HTML5 was supposed to connect once when the JavaScript ran the first time, and receive events as long as the controller sent them.

It is supposed to have always connection with server but not connect once.
Yes, it receives events as long as the controller sent them message. But in our case the server/controller just send data: the data\n\n and connection is closed.
In order to receive message continuously, you need to have loop in the controller action. For example :

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

You can also use while(true) loop.

If you want to more about onerror, you can see this link http://www.htmlgoodies.com/beyond/reference/receive-updates-from-the-server-using-the-eventsource.html.
According to above link,

There is an onerror() event handler, but it's not as useful as you might think. It can however tell us some things about what's happening, thanks to the EventSource's readyState property. For instance, a value of EventSource.CONNECTING means that the connection was lost and the EventSource is attempting to reconnect. If something goes very wrong, a value of EventSource.CLOSED will let you know. Other than that, you can't get much information as there is no error object to query. Instead, it is the event object itself that is passed to the handler. The EventSource may be accessed via the eventSource or eventTarget properties, since both point to the same object.

这篇关于Grails服务器发送事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆