01_tomcat 通过websocket 实现一个简易聊天室功能-项目-教程(一)
ztj100 2024-12-11 18:24 11 浏览 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
相关推荐
- 使用Python编写Ping监测程序(python 测验)
-
Ping是一种常用的网络诊断工具,它可以测试两台计算机之间的连通性;如果您需要监测某个IP地址的连通情况,可以使用Python编写一个Ping监测程序;本文将介绍如何使用Python编写Ping监测程...
- 批量ping!有了这个小工具,python再也香不了一点
-
号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部下午好,我的网工朋友。在咱们网工的日常工作中,经常需要检测多个IP地址的连通性。不知道你是否也有这样的经历:对着电脑屏...
- python之ping主机(python获取ping结果)
-
#coding=utf-8frompythonpingimportpingforiinrange(100,255):ip='192.168.1.'+...
- 网站安全提速秘籍!Nginx配置HTTPS+反向代理实战指南
-
太好了,你直接问到重点场景了:Nginx+HTTPS+反向代理,这个组合是现代Web架构中最常见的一种部署方式。咱们就从理论原理→实操配置→常见问题排查→高级玩法一层层剖开说,...
- Vue开发中使用iframe(vue 使用iframe)
-
内容:iframe全屏显示...
- Vue3项目实践-第五篇(改造登录页-Axios模拟请求数据)
-
本文将介绍以下内容:项目中的public目录和访问静态资源文件的方法使用json文件代替http模拟请求使用Axios直接访问json文件改造登录页,配合Axios进行登录请求,并...
- Vue基础四——Vue-router配置子路由
-
我们上节课初步了解Vue-router的初步知识,也学会了基本的跳转,那我们这节课学习一下子菜单的路由方式,也叫子路由。子路由的情况一般用在一个页面有他的基础模版,然后它下面的页面都隶属于这个模版,只...
- Vue3.0权限管理实现流程【实践】(vue权限管理系统教程)
-
作者:lxcan转发链接:https://segmentfault.com/a/1190000022431839一、整体思路...
- swiper在vue中正确的使用方法(vue中如何使用swiper)
-
swiper是网页中非常强大的一款轮播插件,说是轮播插件都不恰当,因为它能做的事情太多了,swiper在vue下也是能用的,需要依赖专门的vue-swiper插件,因为vue是没有操作dom的逻辑的,...
- Vue怎么实现权限管理?控制到按钮级别的权限怎么做?
-
在Vue项目中实现权限管理,尤其是控制到按钮级别的权限控制,通常包括以下几个方面:一、权限管理的层级划分...
- 【Vue3】保姆级毫无废话的进阶到实战教程 - 01
-
作为一个React、Vue双修选手,在Vue3逐渐稳定下来之后,是时候摸摸Vue3了。Vue3的变化不可谓不大,所以,本系列主要通过对Vue3中的一些BigChanges做...
- Vue3开发极简入门(13):编程式导航路由
-
前面几节文章,写的都是配置路由。但是在实际项目中,下面这种路由导航的写法才是最常用的:比如登录页面,服务端校验成功后,跳转至系统功能页面;通过浏览器输入URL直接进入系统功能页面后,读取本地存储的To...
- vue路由同页面重定向(vue路由重定向到外部url)
-
在Vue中,可以使用路由的重定向功能来实现同页面的重定向。首先,在路由配置文件(通常是`router/index.js`)中,定义一个新的路由,用于重定向到同一个页面。例如,我们可以定义一个名为`Re...
- 那个 Vue 的路由,路由是干什么用的?
-
在Vue里,路由就像“页面导航的指挥官”,专门负责管理页面(组件)的切换和显示逻辑。简单来说,它能让单页应用(SPA)像多页应用一样实现“不同URL对应不同页面”的效果,但整个过程不会刷新网页。一、路...
- Vue3项目投屏功能开发!(vue投票功能)
-
最近接了个大屏项目,产品想在不同的显示器上展示大屏项目不同的页面,做出来的效果图大概长这样...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 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)