使用Grails发送服务器发送事件
本指南将指导您如何使用Grails和RxJava发送服务器发送事件。
作者:Graeme Rocher
Grails版本 3.3.1
1 Grails培训
Grails培训 - 由创建并积极维护Grails框架的人们开发和提供的!
2入门
在本指南中,您将构建一个Grails应用程序,该应用程序通过服务器发送事件与JavaScript客户端通信。
2.1您将需要
要完成本指南,您将需要以下内容
-
一些时间
-
一个合适的文本编辑器或IDE
-
已安装JDK 1.7或更高版本,并已正确配置
JAVA_HOME
2.2如何完成指南
要开始,请执行以下操作
-
下载并解压源代码
或
-
克隆Git存储库
git clone https://github.com/grails-guides/server-sent-events.git
Grails指南存储库包含两个文件夹
-
initial
初始项目。通常是一个简单的Grails应用程序,其中包含一些其他代码,让您领先一步。 -
complete
一个完整的示例。这是完成指南中介绍的步骤并将这些更改应用到initial
文件夹的结果。
要完成该指南,请转到initial
文件夹
-
cd
进入grails-guides/server-sent-events/initial
并按照下一部分中的说明进行操作。
cd 到 grails-guides/server-sent-events/complete 中,你可以直接转到完成的示例 |
3 编写应用程序
3.1 添加 RxJava 依赖项
第一步是配置必要的 Gradle 依赖项。这主要意味着在 build.gradle
文件中添加对用于 Grails 的RxJava 插件的依赖项
dependencies {
...
compile "org.grails.plugins:rxjava"
}
RxJava 用于促进将事件发送到 JavaScript 客户端的响应式编程模型。
3.2 创建控制器
接下来创建一个名为 TickTock
的新控制器。如果安装了 Grails,可以通过运行 grails create-controller
命令来执行此操作,否则可以使用内置的 grailsw
包装器
$ ./grailsw create-controller TickTock
第一次运行 grails 命令时,应用程序依赖项将从互联网下载。后续调用会快得多。 |
该命令的输出将类似于
| Created grails-app/controllers/example/TickTockController.groovy | Created src/test/groovy/example/TickTockControllerSpec.groovy
如你所见,一个新控制器在 grails-app/controllers/example
目录中创建。Grails 将使用定义在 grails-app/conf/application.yml
中 grails.codegen.defaultPackage
值的值来决定使用哪个程序包。
3.3 实现控制器
现在你有一个控制器,你需要修改它以利用 RxJava 特性。为此,添加必要的导入并使控制器实现 grails.rx.web.RxController
性状
import rx.Observer
import rx.Observable
import grails.rx.web.RxController
import java.util.concurrent.TimeUnit
import groovy.transform.CompileStatic
/**
* Demo Server Sent Events Controller
*/
@CompileStatic
class TickTockController implements RxController {
下一步是实现 index
动作。如果没有指定显式动作,那么这将是控制器执行的默认动作。
RxController
性状添加了一个名为 rx
的帮助器,它允许你从控制器控制发送给客户端的响应。
为了开始发送服务器发送事件,我们将使用 rx.stream(..)
方法
def index() {
rx.stream { Observer observer ->
}
}
stream
方法接受一个闭包,该闭包接收 rx.Observer 实例,当你准备通过 rx.Observer 接口发送数据时,可以使用该实例向客户端发送事件。
通过使用 rx
帮助器的各种方法,你可以向 Observer 的 onNext 方法传递值。例如
for (i in (0 .. 5)) {
if (i % 2 == 0) {
observer.onNext(
rx.render('Tick')
)
}
else {
observer.onNext(
rx.render('Tock')
)
}
sleep 1000
}
在此示例中,我们在 0 和 5 之间的值的循环并针对奇数和偶数值调用 rx.render(..)
,分别输出“Tick”或“Tock”。对 sleep(..)
的调用是为了模拟一个慢请求,例如,如果从外部 Web 服务获取值时。
一旦你完成发送事件,便可以使用 Observer 的 onCompleted 事件结束
observer.onCompleted()
最终完成的逻辑如下所示
def index() {
rx.stream { Observer observer ->
for (i in (0 .. 5)) {
if (i % 2 == 0) {
observer.onNext(
rx.render('Tick')
)
}
else {
observer.onNext(
rx.render('Tock')
)
}
sleep 1000
}
observer.onCompleted()
}
}
请注意,如果对 sleep(1000)
的调用实际上是应用程序的具体要求,那么用 interval
方法编写应用程序的习惯性方式将是更合适的
@SuppressWarnings('DuplicateNumberLiteral')
def example() {
int i = 0
rx.stream(Observable
.interval(1, TimeUnit.SECONDS)
.map {
i++
if (i % 2 == 0) {
rx.render('Tick')
}
else {
rx.render('Tock')
}
})
}
3.4 实现客户端
要实现客户端,首先打开 grails-app/views/index.gsp
文件,并在“Welcome to Grails”<h1>
标记下面添加一个附加头
<h1>Welcome to Grails</h1>
<h2 style="text-align:center;font-size:50px" id="message"></h2>
我们将使用此标头放置从服务器发送事件中收到的内容。
然后在页面底部添加以下 <script>
块
<script type="text/javascript">
(function() {
var eventSource = new EventSource("tickTock");
eventSource.onmessage = function(event) {
console.log("data: "+event.data)
document.getElementById('message').innerHTML = event.data;
};
})();
</script>
以上 JavaScript 代码使用服务器发送事件规范的 EventSource
对象开始接收来自控制器的事件
var eventSource = new EventSource("tickTock");
您需要一个 现代浏览器 才能使用 EventSource 对象 |
然后,它注册一个侦听器,该侦听器将使用服务器的响应更新之前定义的 <h2>
标头
eventSource.onmessage = function(event) {
console.log("data: "+event.data)
document.getElementById('message').innerHTML = event.data;
};
就是这样!您现在可以运行应用程序了!
4 运行应用程序
要运行应用程序,请使用 ./gradlew bootRun
命令,该命令将在端口 8080 上启动应用程序。
然后,您可以导航到 http://localhost:8080
,您将看到“Welcome to Grails!” 消息下方消息“Tick”和“Tock”交替出现,因为浏览器从服务器接收到事件。