# 利刃出鞘_Tomcat 核心原理解析(十一)-- WebSocket -- 1

利刃出鞘_Tomcat 核心原理解析(十一)-- Tomcat 附加功能 WebSocket – 1

一、Tomcat专题 - WebSocket - 介绍

1、Tomcat 附加功能:websocket 介绍

1)websocket :是 HTML5 新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,
比如说,服务器可以在任意时刻发送消息给浏览器。

2)为什么传统的 HTTP 协议不能做到 websocket 实现的功能?

  • 这是因为 HTTP 协议是一个请求-响应协议,请求必须先由浏览器发给服务器服务器才能响应这个请求,再把数据发送给浏览器。
    换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的,

  • 这样一来,要在浏览器中搞一个实时聊天,或者在线多人游戏的话就没法实现了,只能借助 Elash 这些插件,

3)也有人说,HTTP 协议其实也能实现啊,比如用轮询或者 comet。

  • 轮询:是指浏览器通过 Javascript 启动一个定时器,然后以固定的间隔给服务器发请求,询问服务器有没有新消息。
    这个机制的缺点一是实时性不够,二是频繁的请求会给服务器带来极大的压力。

  • comet 本质上也是轮询,但是在没有消息的情况下,服务器先拖一段时间,等到有消息了再回复,这个机制暂时地解决了实时性问题,

但是它带来了新的问题:

以多线程模式运行的服务器会让大部分线程大部分时间都处于挂起状态,极大地浪费服务器资源。
另外,一个 HTTP 连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,
而网关是我们不可控的,这就要求 comet 连接必须定期发一些 ping 数据表示连接“正常工作"。

tomcat-67.png

2、以上两种机制都治标不治本,所以,HTML5 推出了 websocket 标准,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。websocket 并不是全新的协议,而是利用了 HTTP 协议来建立连接。

tomcat-68.png

3、websocket 连接是如何创建的。

1)首先,websocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:

tomcat-69.png

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 类,源码:


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 实现一个简易的聊天室功能。

tomcat-70.png

2、WebSocket DEMO 案例流程

1)登录聊天室

2)登录后,进入聊天界面,进行聊天。

3)用户1 聊天界面,用户2 聊天界面。

4)好友列表、单独聊天模式与广播模式。

   tomcat-71.png

3、WebSocket DEMO 案例 实现流程

tomcat-72.png

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 项目

--> 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)


<?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 应用,进行测试。


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

在这里插入图片描述

上一节关联链接请点击
利刃出鞘_Tomcat 核心原理解析(十)-- Tomcat 性能调优–2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/415099.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划法-资源分配问题

动态规划法 - 资源分配问题 问题描述 把4个份额的资源分配给3个工程&#xff0c;给定利润表如下表所示&#xff0c;写出资源的最优分配方案的求解过程。 4份资源分配给3个工程的利润表 步骤一&#xff1a;求各个阶段不同分配份额时的最大利润及分配份额 目标 我们的目标是…

53 mysql pid 文件的创建

前言 接上一篇文章 mysql 启动过程中常见的相关报错信息 在 mysql 中文我们在 “service mysql start”, “service mysql stop” 经常会碰到 mysql.pid 相关的错误信息 比如 “The server quit without updating PID file” 我们这里来看一下 mysql 中 mysql.pid 文件的…

微积分复习笔记 Calculus Volume 1 - 1.3Trigonometric Functions

1.3 Trigonometric Functions - Calculus Volume 1 | OpenStax

自己开发完整项目一、登录功能-05(动态权限控制)

一、上节回顾 在上一节中&#xff0c;我们介绍了如何通过数据库查询用户的权限&#xff0c;并对方法级别的接口使用注解的方式进行权限控制&#xff0c;之后通过用户携带的tocken进行解析权限&#xff0c;判断是否可以访问。 具体步骤&#xff1a; 1.在查询用户信息的时候将用户…

map和set的封装

目录 一、红黑树的改造 1.1节点的定义 二、红黑树的迭代器 2.1用节点封装迭代器 2.2迭代器的实现 2.3map和set的迭代器 三、insert的返回值 3.1insert返回值的用处 3.2operator[ ]的实现 四、key不能修改的问题 封装map和set一般分为六步&#xff1a; 封装map和set …

MFC生成dll的区别

主要分三种&#xff1a; A. 动态链接库(dll) B.具有导出项的(dll)动态链接库 C.MFC动态链接库 对比项目&#xff1a;可以根据需要选择哪种dll方便 添加自定义导出功能Demo 1. 添加导出实现接口&#xff1a; A. 导出需要具有&#xff1a;__declspec(dllexport) B. 按照C语言…

Javascript LeeCode选题(汉诺塔求解)

LeeCode选题 汉诺塔递归求解move移动函数hanoi函数main方法测试代码&#xff1a;代码实现 汉诺塔递归求解 汉诺塔介绍&#xff1a; 汉诺塔的的图形&#xff08;从上到下1&#xff0c;2&#xff0c;3个&#xff09;实现&#xff1a; 这里我们可以看到因为必须要将第n个移动到…

Spring中基于redis stream 的消息队列实现方法

本文主要介绍了消息队列的概念性质和应用场景&#xff0c;介绍了kafka、rabbitMq常用消息队列中间件的应用模型及消息队列的实现方式&#xff0c;并实战了在Spring中基于redis stream 的消息队列实现方法。 一、消息队列 消息队列是一种进程间通信或者同一个进程中不同线程间的…

uni-app 获取当前位置的经纬度以及地址信息

文章目录 uni.getLocation(objc)获取经纬度和地址调试结果问题 uni-app 获取当前位置的经纬度以及地址信息 uni.getLocation(objc) uni-app官方文档定位API: uni.getLocation(OBJECT) uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&…

【系统架构设计】嵌入式系统设计(1)

【系统架构设计】嵌入式系统设计&#xff08;1&#xff09; 嵌入式系统概论嵌入式系统的组成硬件嵌入式处理器总线存储器I/O 设备与接口 软件 嵌入式开发平台与调试环境交叉平台开发环境交叉编译环境调试 嵌入式系统概论 嵌入性、专用性、计算机系统是嵌入式系统的三个基本的核…

【话题讨论】VS Code:倍增编程动力,实现效率飞跃

目录 引言 一、详情介绍 功能特点 使用场景 提高工作效率 二、效率对比 2.1 高度可定制性与丰富的插件生态 2.2 智能的代码补全与导航 2.3 内置的调试器与版本控制集成 2.4 轻量级与跨平台 2.5 选择合适工具的重要性 2.6 实际案例或数据展示 三、未来趋势 3.1 编…

能见度监测站—实时监测道路能见度情况

型号&#xff1a;TH-NJD10】能见度监测站是一种专门用于自动观测和存储气象观测数据的设备&#xff0c;它通过高科技手段实时监测大气能见度的变化&#xff0c;为多个领域提供重要的数据支持。主要基于光在大气中的衰减规律。传感器系统中的发射器发出光线&#xff0c;照射到空…

shell编程--正则表达式

正则表达式 正则表达式都被置于两个正斜杠之间&#xff1b;如/l[oO]ve/ 示例 匹配数字的脚本&#xff0c;用户输入创建账号的数量 语法&#xff1a; [[ ^[0-9]$ ]] 表示必须输入数字 #!/bin/bashwhile : do read -p "输入数字&#xff1a;" numif [[ $num ~ ^[…

产品需求过程管理重要性

产品需求过程管理重要性 背景 以下都是真实事项经历回顾&#xff0c;在产品开发过程中&#xff0c;产品经理与研发团队之间的沟通至关重要。然而&#xff0c;沟通不畅或信息缺失常常导致需求无法准确传达&#xff0c;最终影响产品的成功。以下是一些常见的问题&#xff1a; 1.需…

Jmeter执行多机联合负载

1、注意事项&#xff0c;负载机必须要安装jre&#xff0c;控制机则必须安装jdk。要配置同网段ip&#xff0c;双向关闭防火墙。 每个负载机要平均承担线程数。 具体执行事项查看上面截图所示&#xff0c;控制机和负载机配置。 2、先给负载机设置ip地址&#xff0c;保持与控制…

C++项目详细分析_WebServer

前言 项目地址 项目介绍 源码详细分析 项目路径如下&#xff1a; 1.webserver.cpp 头文件和构造函数 #include "webserver.h"WebServer::WebServer() {// http_conn类对象users new http_conn[MAX_FD];// root文件夹路径char server_path[200];getcwd(server…

prometheus基于文件的服务发现

之间讲到&#xff0c;prometheus监控的对象就来自于他的配置文件里面的targets&#xff0c;如果要新增被监控对象&#xff0c;就继续往targets里面加。 但这个缺点是&#xff0c;每次修改完后都得重启prometheus。有没有什么办法&#xff0c;能在不重启的情况下增加target呢&a…

【Qt】 QComboBox | QSpinBox

文章目录 QComboBox —— 下拉框QComboBox 属性核心方法核心信号QComboBox 使用 QSpinBox —— 微调框QSpinBox 属性核心信号QSpinBox 使用 QComboBox —— 下拉框 QComboBox 属性 QComboBox —— 表示下拉框 currentText ——当前选中的文本 currentindex ——当前选中的条…

【硬件知识】从零开始认识GPU

【硬件知识】从零开始认识GPU 一、GPU的发展史简介二、GPU主要构成三、GPU与AI的关系 一、GPU的发展史简介 GPU&#xff08;图形处理器&#xff09;的发展史是一段充满创新与变革的历程&#xff0c;它不仅改变了计算机图形显示的方式&#xff0c;还推动了高性能计算、人工智能…

盘点大模型中转 API 平台,并比较费用

1. 大模型中转 API 平台集合 1.1 DevAGI DevAGI开放平台 Open AI 价格 1.2 Deepbricks 官网价格 1.3 AiHubMix AiHubMix 官网 使用教程 价格&#xff1a; 1.4 WildCard 开卡订阅 WildCard官网 价格 有3.5% 的充值手续费&#xff0c;API 价格与 Open AI 一样 2. 价…