使用 Grails 发送服务器端发送事件
本指南将指导您如何使用 Grails 和 RxJava 发送服务器端发送事件。
作者: Graeme Rocher
Grails 版本 5.0.1
1 Grails 培训
Grails 培训 - 由创建并积极维护 Grails 框架的人员开发和交付!
2 开始使用
在本指南中,您将构建一个通过 服务器端发送事件与 JavaScript 客户端通信的 Grails 应用程序。
2.1 所需物品
要完成本指南,您将需要以下物品
-
一些时间
-
一个合适的文本编辑器或 IDE
-
安装了 JDK 1.8 或更高版本,并正确配置了
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 and Micronaut 中的 RxJava 插件 reactivex` 的依赖
dependencies {
...
implementation "io.reactivex:rxjava"
implementation "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” 消息交替显示,因为浏览器从服务器接收事件。