问题描述
我需要得到服务器发送的事件与Grails一起工作。我觉得我很接近,但不是那样。 JavaScript请求成功到达控制器,但每次都会引发错误。它会每2秒左右重试一次(可能是由于错误)。
当服务器的会话计时器低于5分钟时,我需要向用户发送一个事件。我试图使用HTML5的EventSource,因为我只想发送一个请求到服务器(多个请求将重置会话计时器每次)。根据,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]
收到的消息:数据
错误[对象事件]
打开[对象事件]
收到的消息:数据
错误[对象事件]
打开[对象事件]
收到的消息:数据
错误[对象事件]
更多详细信息,请参阅。
更新
可能有不同的原因对于错误例如:网络超时。在我们的例子中,这是由于服务器和浏览器之间的连接关闭。
在浏览器获取数据
后,服务器和浏览器之间的连接关闭。所以浏览器会在每次连接关闭后大概3秒钟重新连接。
它应该有始终与服务器连接,但不能连接一次。
只要控制器向他们发送消息,它就会收到事件。但在我们的例子中,服务器/控制器只发送 data:data \\\
并且连接已关闭。
\\\
为了接收消息不断地,你需要在控制器动作中有循环。例如:
package sessionManager
class SSETestController {
def push = {
println $请求了!
response.setContentType(text / event-stream,charset = UTF-8)
for(int i = 0; i renderdata:the data \\\
\\\
Thread.sleep(1000)
}
renderdata:finished \\\
\\\
}
}
您也可以使用 while while(true)
loop 。
如果您想详细了解 onerror
,您可以看到。
根据上述链接,
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
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.
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.
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,
这篇关于Grails服务器发送事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!