01_tomcat 通过websocket 实现一个简易聊天室功能-项目-教程(一)
ztj100 2024-12-11 18:24 15 浏览 0 评论
01_tomcat 通过 websocket 实现一个简易的聊天室功能-项目-教程(一)
## 一、Tomcat专题 - WebSocket - 介绍
### 1、Tomcat 附加功能:websocket 介绍
1)websocket :是 HTML5 新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,
比如说,服务器可以在任意时刻发送消息给浏览器。
2)为什么传统的 HTTP 协议不能做到 websocket 实现的功能?
- 这是因为 HTTP 协议是一个请求-响应协议,请求必须先由浏览器发给服务器服务器才能响应这个请求,再把数据发送给浏览器。
换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的,
- 这样一来,要在浏览器中搞一个实时聊天,或者在线多人游戏的话就没法实现了,只能借助 Elash 这些插件,
3)也有人说,HTTP 协议其实也能实现啊,比如用轮询或者 comet。
- 轮询:是指浏览器通过 Javascript 启动一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息。
这个机制的缺点一是实时性不够,二是频繁的请求会给服务器带来极大的压力。
- comet 本质上也是轮询,但是在没有消息的情况下,服务器先拖一段时间,等到有消息了再回复,这个机制暂时地解决了实时性问题,
但是它带来了新的问题:
以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源。
另外,一个 HTTP 连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,
而网关是我们不可控的,这就要求 comet 连接必须定期发一些 ping 数据表示连接“正常工作"。
### 2、以上两种机制都治标不治本,所以,HTML5 推出了 websocket 标准,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。websocket 并不是全新的协议,而是利用了 HTTP 协议来建立连接。
### 3、websocket 连接是如何创建的。
1)首先,websocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:
2)该请求和普通的HTTP请求有几点不同:
- 1.GET请求的地址不是类似 http://,而是以 ws:// 开头的地址;
- 2.请求头 connection:upgrade 和 请求头 upgrade:websocket 表示这个连接将要被转换为 websocket 连接;
- 3.sec-websocket-Key 是用于标识这个连接, 是一个BASE64编码的密文,要求服务端响应一个对应加密的sec-websocket-Accept头信息作为应答。
- 4.sec-websocket-version 指定了 websocket 的协议版本;
- 5.HTTP101 状态码表明服务端已经识别并切换为 Websocket 协议,sec-websocket-Accept 是服务端与客户端一致的秘钥计算出来的信息。
## 二、Tomcat专题 - WebSocket - Tomcat的支持
### 1、Tomcat 的 Websocket
Tomcat 的 7.0.5 版本开始支持 websocket,并且实现了 Java websocket 规范(JSR356),而在7.0.5版本之前(7.0.2之后)则采用自定义 API,即 websocketservlet 实现。
### 2、Java websocket 应用由一系列的 nebsocketEndpoint 组成。Endpoint 是一个 Java 对象,代表 websocket 链接的一端,对于服务端,可以视为处理具体 websocket 消息的接口,就像 servlet 之与 http 请求一样。
### 3、可以通过两种方式定义 Endpoint:
1)第一种是编程式,即继承类 javax.websocket.Endpoint 并实现其方法。
2)第二种是注解式,即定义一个POJO,并添加 @serverEndpoint 相关注解。
### 4、Endpoint 实例在 websocket 握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束,在 Endpoint 接口中明确定义了与其生命周期相关的方法, 规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:
| 方法 | 含义描述 | 注解 | |
|--|--|--|--|
| onOpen | 当开启一个新的会话时调用,该方法是客户端与服务端握手成功后调用的方法。 | @onopen | |
| onClose | 当会话关闭时调用。 | @onClose | |
| onError | 当连接过程中异常时调用。 | @onError | |
| | | | |
### 5、编程式 和 注解式 接收和发送消息。
- 编程式通过为 session 添加 Messagexandler 消息处理器来接收消息。
- 采用注解方式定义 Endpoint 时,可以通过 @onMessage 注解指定接收消息的方法。发送消息则由 RemoteEndpoint 完成,其实例由 session 维护。
- 根据使用情况, 可以通过 session.getBasicRemote 获取同步消息发送的实例,然后调用其 sendxxx() 方法就可以发送消息,可以通过 session.getAsyncRemote 获取异步消息发送实例。
### 6、...\apache-tomcat-8.5.42-src\java\javax\websocket\Endpoint.java 类,源码:
```bash
package javax.websocket;
public abstract class Endpoint {
public abstract void onOpen(Session session, EndpointConfig config);
public void onClose(Session session, CloseReason closeReason) {
// NO-OP by default
}
public void onError(Session session, Throwable throwable) {
// NO-OP by default
}
}
```
## 三、 Tomcat专题 - WebSocket - 案例 - 需求及流程分析
### 1、WebSocket DEMO 案例需求:通过 websocket 实现一个简易的聊天室功能。
### 2、WebSocket DEMO 案例流程
1)登录聊天室
2)登录后,进入聊天界面,进行聊天。
3)用户1 聊天界面,用户2 聊天界面。
4)好友列表、单独聊天模式与广播模式。
### 3、WebSocket DEMO 案例 实现流程
### 4、消息格式
客户端 --> 服务端: {"fromName":"Deng","toName":"HEIMA","content":"约会呀"}
服务端 --> 客户端:
1)如果 type 为 user,则说明返回的是用户列表
{"data" : "HEIMA, Deng, ITCAST" ,"toName" :"" ,"fromName" :"","type" :"user" }
2)如果 type 为 message,则说明返回的是消息内容
{"data" : "你好" ,"toName" : "HE IMA" , " fromName" : "Deng" ,"type" : "message" }
## 四、Tomcat专题 - WebSocket - 案例 - 准备工作
### 1、打开 idea 创建 名为 dzs168_chat_room 的 Web Application 项目
```java
--> idea --> File
--> New --> Project
--> Java
Project SDK: ( 1.8(java version "1.8.0_131" )
--> Java EE : 勾选 ( Web Application )
--> Next
--> Project Name: ( dzs168_chat_room )
Project Location: ( ...\dzs168_chat_room\ )
--> Finish
```
### 2、在项目 dzs168_chat_room 中,导入项目依赖( dzs168_chat_room/web/lib/ ),Add as Library...
fastjson-1.2.5.jar
tomcat-websocket.jar
websocket-api.jar
### 3、在项目 dzs168_chat_room 中,导入静态资源文件。
dzs168_chat_room/web/css/
dzs168_chat_room/web/img/
dzs168_chat_room/web/js/
dzs168_chat_room/web/chat.jsp
dzs168_chat_room/web/login.jsp
### 4、在项目 dzs168_chat_room 中, Web 应用配置欢迎页面为 login.jsp
(project_tomcat\dzs168_chat_room\web\WEB-INF\web.xml)
```java
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
<!-- project_tomcat\dzs168_chat_room\web\WEB-INF\web.xml -->
```
### 5、配置 dzs168_chat_room 应用,进行测试。
```java
idea ---> Run/Debug Configurations
---> 点击 应用 Tomcat 8.5.47
---> Deployment
删除已经存在的应用。
---> 点击 + 添加新应用 Artifact... ,选择我们的项目 dzs168_chat_room.war exploded
---> Application context: ( / )
---> Apply
---> Server
---> On'Update'action: ( Update classes and resources )
---> On frame deactivation: ( Update classes and resources )
---> Apply
---> OK 。
```
### 6、运行 tomcat 服务器,自动打开欢迎页面,localhost:8080
相关推荐
- Sublime Text 4 稳定版 Build 4113 发布
-
IT之家7月18日消息知名编辑器SublimeText4近日发布了Build4113版本,是SublimeText4的第二个稳定版。IT之家了解到,SublimeTe...
- 【小白课程】openKylin便签贴的设计与实现
-
openKylin便签贴作为侧边栏的一个小插件,提供便捷的文本记录和灵活的页面展示。openKylin便签贴分为两个部分:便签列表...
- 壹啦罐罐 Android 手机里的 Xposed 都装了啥
-
这是少数派推出的系列专题,叫做「我的手机里都装了啥」。这个系列将邀请到不同的玩家,从他们各自的角度介绍手机中最爱的或是日常使用最频繁的App。文章将以「每周一篇」的频率更新,内容范围会包括iOS、...
- 电气自动化专业词汇中英文对照表(电气自动化专业英语单词)
-
专业词汇中英文对照表...
- Python界面设计Tkinter模块的核心组件
-
我们使用一个模块,我们要熟悉这个模块的主要元件。如我们设计一个窗口,我们可以用Tk()来完成创建;一些交互元素,按钮、标签、编辑框用到控件;怎么去布局你的界面,我们可以用到pack()、grid()...
- 以色列发现“死海古卷”新残片(死海古卷是真的吗)
-
编译|陈家琦据艺术新闻网(artnews.com)报道,3月16日,以色列考古学家发现了死海古卷(DeadSeaScrolls)新残片。新出土的羊皮纸残片中包括以希腊文书写的《十二先知书》段落,这...
- 鸿蒙Next仓颉语言开发实战教程:订单列表
-
大家上午好,最近不断有友友反馈仓颉语言和ArkTs很像,所以要注意不要混淆。今天要分享的是仓颉语言开发商城应用的订单列表页。首先来分析一下这个页面,它分为三大部分,分别是导航栏、订单类型和订单列表部分...
- 哪些模块可以用在 Xposed for Lollipop 上?Xposed 模块兼容性解答
-
虽然已经有了XposedforLollipop的安装教程,但由于其还处在alpha阶段,一些Xposed模块能不能依赖其正常工作还未可知。为了解决大家对于模块兼容性的疑惑,笔者尽可能多...
- 利用 Fluid 自制 Mac 版 Overcast 应用
-
我喜爱收听播客,健身、上/下班途中,工作中,甚至是忙着做家务时。大多数情况下我会用MarcoArment开发的Overcast(Freemium)在iPhone上收听,这是我目前最喜爱的Po...
- 浅色Al云食堂APP代码(三)(手机云食堂)
-
以下是进一步优化完善后的浅色AI云食堂APP完整代码,新增了数据可视化、用户反馈、智能推荐等功能,并优化了代码结构和性能。项目结构...
- 实战PyQt5: 121-使用QImage实现一个看图应用
-
QImage简介QImage类提供了独立于硬件的图像表示形式,该图像表示形式可以直接访问像素数据,并且可以用作绘制设备。QImage是QPaintDevice子类,因此可以使用QPainter直接在图...
- 滚动条隐藏及美化(滚动条隐藏但是可以滚动)
-
1、滚动条隐藏背景/场景:在移动端,滑动的时候,会显示默认滚动条,如图1://隐藏代码:/*隐藏滚轮*/.ul-scrool-box::-webkit-scrollbar,.ul-scrool...
- 浅色AI云食堂APP完整代码(二)(ai 食堂)
-
以下是整合后的浅色AI云食堂APP完整代码,包含后端核心功能、前端界面以及优化增强功能。项目采用Django框架开发,支持库存管理、订单处理、财务管理等核心功能,并包含库存预警、数据导出、权限管理等增...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)