![Quarkus实践指南:构建新一代的Kubernetes原生Java微服务](https://wfqqreader-1252317822.image.myqcloud.com/cover/237/40795237/b_40795237.jpg)
3.4 编写WebSocket应用
3.4.1 案例简介
本案例介绍基于 Quarkus 框架实现 WebSocket的基本功能。该功能的实现遵循 WebSocket规范,该模块引入了 Undertow WebSocket 扩展。本案例创建了一个简单的聊天应用程序,使用WebSocket接收消息并向其他连接用户发送消息。通过阅读和分析一个简单的聊天应用程序的案例代码,可以了解和掌握 Quarkus 框架的 WebSocket使用方法。本案例程序的应用场景如图3-19所示。
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_142_1.jpg?sign=1739269719-acGz79git1uBuhYQtsaRdRaz5YUAdkGJ-0-a16abe8eade0734c789ea785d0c4a0b0)
图3-19 本案例程序的应用场景
基础知识:WebSocket规范及一些相关概念。
WebSocket(架构如图3-20所示)是一种在单个TCP连接上进行全双工通信的协议,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器之间只需要完成一次握手,两者就可以直接创建持久性连接,并进行双向数据传输。为了建立一个WebSocket连接,客户端浏览器首先要向服务器发起一个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信息。WebSocket 通信协议于 2011 年被 IETF 定为标准 RFC 6455,并被 RFC 7936补充成规范。WebSocket API也被W3C定为标准。
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_143_1.jpg?sign=1739269719-CWgLtnk0cWVesyEcjRRW07oiPWDIeEn3-0-f760ee4144527a48b402773db03435fb)
图3-20 WebSocket访问架构
WebSocket规范的Java常用注解说明如表3-4所示。
表3-4 WebSocket规范的Java常用注解说明
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_143_2.jpg?sign=1739269719-5PyJNgBW47Ah4eQ9lPhheleORRtOBu4V-0-72fd51a4f37665b376585eb70fd8aeac)
3.4.2 编写程序代码
编写程序代码有 3种方式。第 1种方式是通过代码 UI来实现的,在 Quarkus 官网的生成代码页面中按照指定步骤生成脚手架代码,然后下载文件,将项目引入 IDE 工具中,最后修改程序源码。
第2种方式是通过mvn来构建程序,通过下面的命令创建Maven项目来实现:
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_143_3.jpg?sign=1739269719-z2JyeYYXccoshVQorKSkx7uZIobG2LW2-0-872e4f1a4e1f31c01406627a141f061e)
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_144_1.jpg?sign=1739269719-pOBJ5GirioJBPJwtHhBPgSL05y3dEHk9-0-97ff0724e9e2949d6375cf38851192d0)
第3种方式是直接从GitHub上获取代码,可以从GitHub上克隆预先准备好的示例代码:
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_144_2.jpg?sign=1739269719-8HGyserA7VdAoPF3Pcz19A5YrfKRV9pA-0-a7a0433879d8afb854c83d2f02d8e10b)
该程序位于“024-quarkus-sample-websockets”目录中,是一个Maven工程项目程序。在IDE工具中导入Maven工程项目程序,在pom.xml的<dependencies>下有如下内容:
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_144_3.jpg?sign=1739269719-g0B0x8rXJPj6SHa99RCnn3WE8U5m6LlV-0-99d76a3c86f278268e24d0b5dba529ee)
quarkus-undertow-websockets是Quarkus 整合了undertow-websockets的实现。
quarkus-sample-websockets 程序的应用架构(如图 3-21 所示)表明,外部访问 index.html页面,index.html 页面的 JavaScript 代码调用 ChatSocket 服务,ChatSocket 服务依赖于Undertow平台。
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_144_4.jpg?sign=1739269719-aTjscHTXhBlu6pGOytH35f5DhIji30X4-0-fc157f4229066397560d3c5d871415cb)
图3-21 quarkus-sample-websockets程序应用架构图
quarkus-sample-websockets程序的核心类和页面文件如表3-5所示。
表3-5 quarkus-sample-websockets程序的核心类和页面文件
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_144_5.jpg?sign=1739269719-FkeB31QBf1MS5zMRKWEr0GwPY4kELRkJ-0-c2e93decc281401be68a2356505bafe3)
下面讲解ChatSocket类和index.html页面中的JavaScript代码内容。
1.ChatSocket类
用IDE工具打开com.iiit.quarkus.sample.websockets.ChatSocket类文件,其代码如下:
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_145_1.jpg?sign=1739269719-UwN6XXNu3NccdDj8IZrtyvIhN7wQi6fN-0-0a294b93d42dda273663633aeabfb8ca)
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_146_1.jpg?sign=1739269719-BhNoqeiGy6BT8tccMO4VeovPg8G6zehU-0-bde9080d6eb7b4f6e8d438f8fcff81b9)
程序说明:
①@ServerEndpoint注解:声明WebSocket地址。@ServerEndpoint("/chat/{username}")表明链接地址的形式是ws://localhost:8080/chat/{username}。
②@OnOpen注解:这是有连接时的触发函数。该函数的内容是Session加入一个用户(或端点)。Session代表了两个 WebSocket端点的会话;在 WebSocket握手成功后,WebSocket就会提供一个打开的 Session,可以通过这个 Session向另一个端点发送数据;如果 Session关闭后发送数据,将会报错。
③@OnClose注解:连接关闭时调用的方法。Session关闭指定用户(或端点)。
④@OnMessage注解:收到消息时调用的方法,其中 Session是每个 WebSocket特有的数据成员。消息以广播的形式在Session中发布。
⑤@OnError注解:发生意外错误时调用的方法。
2.index.html页面
由于涉及表现层交互,故需要一个页面 index.html,而 index.html 页面的核心是采用JavaScript来编写通信内容。打开index.html文件,其JavaScript代码如下所示:
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_146_2.jpg?sign=1739269719-N15K8vEFd6YEbP5HvtQ8ExHbOWiAOqQw-0-3c716baf4c9876208593f4c8e538c8ad)
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_147_1.jpg?sign=1739269719-XuhAZO7TmWqs311dei2RJZwaw5dnazcR-0-682330b1e1645c9243b38a84b705223a)
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_148_1.jpg?sign=1739269719-JWBiRPZVsOMBIDRI1ETwfwBy3Hmoif7U-0-c157834e2aefea1e46f9a7ce26c08dc6)
程序说明:
① 定义两个变量,一个是 WebSocket的连接状态变量 connected,另一个是 WebSocket变量socket。
② 两个核心函数,一个是连接 WebSocket服务器的函数 connect,另一个是向 WebSocket服务器发送消息的函数sendMessage。
③ 展现页面时,可通过$("#connect")按钮调用连接 WebSocket服务器的 connect函数,然后就可以通过("#send")按钮调用 sendMessage函数来发表内容了。具体细节实现在 js文件的注释中已经进行了说明。
3.4.3 验证程序
通过下列几个步骤(如图3-22所示)来验证案例程序。
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_148_2.jpg?sign=1739269719-NbjxClP7H5y2ZOtznygieRdSMmL0Y78I-0-60c9f731a8d1c99dfca595fe21ab2e58)
图3-22 quarkus-sample-websockets程序验证流程图
下面对其中涉及的关键点进行说明。
1.启动quarkus-sample-websockets程序服务
启动程序有两种方式,第 1种是在开发工具(如 Eclipse)中调用 ProjectMain类的 run方法,第2种是在程序目录下直接运行命令mvnw compile quarkus:dev。
2.打开两个浏览器
分别打开两个浏览器窗口 http://localhost:8080/,在顶部文本区域输入名称(使用两个不同的名称)。单击连接按钮,连接服务器成功后,就可以进入会话界面了。在会话界面上可以发送文本信息,同时可以收到其他终端发来的信息。可以进行实时通信,如图 3-23 所示的是两个浏览器之间的通话。
![](https://epubservercos.yuewen.com/ADE0E0/21190709301168906/epubprivate/OEBPS/Images/41803_149_1.jpg?sign=1739269719-ztbeqxrtyXVL18Fs0Hl9jDoZQ1dKtZRn-0-e704e791fa4fdb1034f727c163893af3)
图3-23 两个浏览器之间的通话