我需要使用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]
提前致谢, 克里斯汉考克
答案 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