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

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

一、Tomcat专题 - WebSocket - 案例 - 登录功能

1、在项目 dzs168_chat_room 中,导入 tomcat 项目依赖( dzs168_chat_room/web/lib/ )


idea ---> File
---> Project Structure 
---> Modules 选择我们的项目 dzs168_chat_room---> Dependencies:  点击 + 添加---> Library...---> Application Server Libraries---> Tcomcat ---> Add Selected---> Apply 
---> OK。

2、项目 dzs168_chat_room 中,login.jsp 页面。


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head><title>段子手聊天室——登录</title><meta name="viewport" content="width=device-width, initial-scale=1"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="keywords"content="Transparent Sign In Form Responsive Widget,Login form widgets, Sign up Web forms , Login signup Responsive web form,Flat Pricing table,Flat Drop downs,Registration Forms,News letter Forms,Elements"/><script type="application/x-javascript">addEventListener("load", function () {setTimeout(hideURLbar, 0);}, false);function hideURLbar() {window.scrollTo(0, 1);}</script><script src="js/jquery-1.9.1.min.js"></script><link rel="icon" href="img/chat.ico" type="image/x-icon"/><link rel="stylesheet" href="css/font-awesome.css"/> <!-- Font-Awesome-Icons-CSS --><link rel="stylesheet" href="css/login.css" type="text/css" media="all"/> <!-- Style-CSS -->
</head><body class="background">
<div class="header-w3l"><h1>段子手168聊天室</h1>
</div>
<div class="main-content-agile"><div class="sub-main-w3"><h2>登录</h2><form><div class="icon1"><input placeholder="用户名" id="username" type="text"/></div><div class="icon2"><input placeholder="密码" id="password" type="password"/></div><div class="clear"></div><input type="button" value="登录" onclick="login()"/></form></div>
</div>
<div class="footer"><p>段子手168 版权所有Copyright 2024-9-1  All Rights Reserved </p>
</div>
</body>
<script type="text/javascript">function login() {$.ajax({type: 'POST',url: '/login',dataType: 'json',data: {username: $("#username").val(),password: $("#password").val()},success: function (data) {if (data.success) {window.location.href = "chat.jsp";} else {alert(data.message);}}});}</script>
</html>
<!-- project_tomcat\dzs168_chat_room\web\login.jsp -->

3、项目 dzs168_chat_room 中,chat.jsp 页面。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="format-detection" content="telephone=no"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"><meta name="mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-capable" content="yes"><meta content="yes" name="apple-mobile-web-app-capable"><meta content="yes" name="apple-touch-fullscreen"><meta name="full-screen" content="yes"><meta content="default" name="apple-mobile-web-app-status-bar-style"><meta name="screen-orientation" content="portrait"><meta name="browsermode" content="application"><meta name="msapplication-tap-highlight" content="no"><meta name="x5-orientation" content="portrait"><meta name="x5-fullscreen" content="true"><meta name="x5-page-mode" content="app"><base target="_blank"><title>段子手168-聊天室</title><link href="css/bootstrap.min.css" rel="stylesheet" type="text/css"/><link rel="stylesheet" href="css/chat.css"><script src="js/jquery-1.9.1.min.js"></script><script type="text/javascript"><%String name = session.getAttribute("username")+"";%>var self = "<%= name %>";</script><script type="text/javascript" src="js/ws.js"></script>
</head><body  onload="startWebSocket(self);"><img style="width:100%;height:100%" src="img/chat_bg.jpg"><div class="abs cover contaniner"><div class="abs cover pnl"><div class="top pnl-head" style="padding: 20px ; color: white;" id="userName"></div><div class="abs cover pnl-body" id="pnlBody"><div class="abs cover pnl-left"><div class="abs cover pnl-msgs scroll" id="show"><div class="pnl-list" id="hists"><!-- 历史消息 --></div><div class="pnl-list" id="msgs"><!-- 消息这展示区域 --></div></div><div class="abs bottom pnl-text"><div class="abs cover pnl-input"><textarea class="scroll" id="context_text" onkeydown="sendMessage(self)" wrap="hard" placeholder="在此输入文字信息..."></textarea><div class="abs atcom-pnl scroll hide" id="atcomPnl"><ul class="atcom" id="atcom"></ul></div></div><div class="abs br pnl-btn" id="submit" style="background-color: rgb(32, 196, 202); color: rgb(255, 255, 255);" onclick="sendMsg(self)">发送</div><div class="pnl-support" id="copyright"><a href="http://www.itcast.cn">段子手168,版本所有</a></div></div></div><div class="abs right pnl-right"><div class="slider-container hide"></div><div class="pnl-right-content"><div class="pnl-tabs"><div class="tab-btn active" id="hot-tab">好友列表</div></div><div class="pnl-hot"><ul class="rel-list unselect" id="userlist"></ul></div></div><div class="pnl-right-content"><div class="pnl-tabs"><div class="tab-btn active">系统广播</div></div><div class="pnl-hot"><ul class="rel-list unselect" id="broadcastList"></ul></div></div></div></div></div>
</div>
</body>
</html>
<!-- project_tomcat\dzs168_chat_room\web\chat.jsp -->

4、在项目 dzs168_chat_room 中,创建 用户登录的 servlet 类 LoginServlet.java

/***  project_tomcat\dzs168_chat_room\src\djh\it\servlet\LoginServlet.java**  2024-9-1 创建 用户登录的 servlet 类 LoginServlet.java*/package djh.it.servlet;import com.alibaba.fastjson.JSON;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;@WebServlet(name = "loginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {private static final String PASSWORD = "dzs168";@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//处理中文乱码问题resp.setCharacterEncoding("UTF-8");//1. 接收页面传递的参数 , 用户名/密码String username = req.getParameter("username");String password = req.getParameter("password");Map resultMap = new HashMap();//2. 判定用户名密码是否正确//3. 如果正确, 响应登录成功的信息if(PASSWORD.equals(password)){resultMap.put("success",true);resultMap.put("message","登录成功");req.getSession().setAttribute("username",username);}else{//4. 如果不正确, 响应登录失败的信息resultMap.put("success",false);resultMap.put("message","用户名或密码错误");}//5. 响应数据resp.getWriter().write(JSON.toJSONString(resultMap));}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req,resp);}
}

5、运行 tomcat 服务,进行测试。浏览器地址栏输入:localhost:8080/ 输入错误密码 和 正确密码,分别进行测试。

tomcat-74.png

tomcat-75.png

二、Tomcat专题 - WebSocket - 案例 - OnOpen

1、在项目 dzs168_chat_room 中,工具类 MessageUtil.java

/***  project_tomcat.dzs168_chat_room.src.djh.it.utils.MessageUtil.java**  2024-9-2 工具类 MessageUtil.java*/
package djh.it.utils;import com.alibaba.fastjson.JSON;import java.util.HashMap;
import java.util.Map;public class MessageUtil {public final static String TYPE = "type";public final static String DATA = "data";public final static String FROM_NAME = "fromName";public final static String TO_NAME = "toName";public final static String TYPE_MESSAGE = "message";public final static String TYPE_USER = "user";//组装消息, 然后返回一个json格式的消息数据public static String getContent(String type, String fromName, String toName, String content) {Map<String, Object> userMap = new HashMap<String, Object>();userMap.put(MessageUtil.TYPE, type);userMap.put(MessageUtil.DATA, content);userMap.put(MessageUtil.FROM_NAME, fromName);userMap.put(MessageUtil.TO_NAME, toName);String jsonMsg = JSON.toJSONString(userMap);return jsonMsg;}
}

2、在项目 dzs168_chat_room 中,创建 获取 HttpSession 的 GetHttpSessionConfigurator.java 类,

/***  project_tomcat\dzs168_chat_room\src\djh\it\websocket\GetHttpSessionConfigurator.java**  2024-9-2 创建 获取 HttpSession 的 GetHttpSessionConfigurator.java 类,*/package djh.it.websocket;import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator {@Override  //重写方法public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {HttpSession httpSession = (HttpSession) request.getHttpSession();config.getUserProperties().put(HttpSession.class.getName(),httpSession);}
}

3、在项目 dzs168_chat_room 中,创建 websocket 类 ChatSocket.java

/***   project_tomcat\dzs168_chat_room\src\djh\it\websocket\ChatSocket.java**   2024-9-2 创建 websocket 类 ChatSocket.java*/package djh.it.websocket;import djh.it.utils.MessageUtil;import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;@ServerEndpoint(value = "/websocket",configurator = GetHttpSessionConfigurator.class )
public class ChatSocket {private  Session session;private  HttpSession httpSession;//保存当前系统中登录的用户的HttpSession信息, 及对应的Endpoint实例信息private static Map<HttpSession , ChatSocket> onlineUsers = new HashMap<HttpSession, ChatSocket>();private static int onlineCount = 0;@OnOpenpublic void onOpen(Session session, EndpointConfig config){//1. 记录webSocket的会话信息对象Sessionthis.session = session;//2. 获取当前登录用户HttpSession信息.HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());this.httpSession = httpSession;System.out.println("当前登录用户 : " + httpSession.getAttribute("username") +", Endpoint : " +hashCode());//3. 记录当前登录用户信息, 及对应的Endpoint实例if (httpSession.getAttribute("username") != null){onlineUsers.put(httpSession,this);}//4. 获取当前所有登录用户 --------> DZS168,dzs,TOM...String names = getNames();//5. 组装消息 ---> {"data":"dzs168,Deng,study","toName":"","fromName":"","type":"user"}String message = MessageUtil.getContent(MessageUtil.TYPE_USER, "", "", names);//6. 通过广播的形式发送消息//session.getBasicRemote().sendText("");broadcastAllUsers(message);//7. 记录当前用户登录数 .incrCount();}// 发送广播消息private void broadcastAllUsers(String message) {for (HttpSession hsession : onlineUsers.keySet()) {try {onlineUsers.get(hsession).session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}//获取所有的在线用户private String getNames() {String names = "";if(onlineUsers.size()>0){for (HttpSession hsession : onlineUsers.keySet()) {String username = (String) hsession.getAttribute("username");names += username+",";}}return names.substring(0,names.length()-1);}public int getOnlineCount(){return onlineCount;}public synchronized void incrCount(){onlineCount ++;}public synchronized void decrCount(){onlineCount --;}}

三、Tomcat专题 - WebSocket - 案例 - OnOpen测试

1、运行 tomcat 服务,进行测试。观察控制台输出结果。

tomcat-76.png

2、多个 浏览器地址栏输入:localhost:8080/ 进行测试,观察控制台输出结果。

tomcat-77.png

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

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

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

相关文章

数据结构与算法---排序算法

文章目录 排序选择排序冒泡排序插入排序 希尔排序归并排序快速排序桶排序计数排序基数排序堆排序 排序 排序是指将一组数据按照特定的规则或顺序进行排列&#xff0c;比如一个数组[1, 5, 2, 4, 3]按照从小到大的顺序排列后就是[1,2,3,4,5]。 排序算法&#xff08;Sorting alg…

全球1km分辨率人口分布栅格数据

我们在《全国省市县三级“七普”人口数据分享》一文中&#xff0c;为你分享过全国人口数据。 现在再为你分享全球1km分辨率人口分布栅格数据&#xff0c;你可以在文末查看该数据的领取方法。 全球1km分辨率人口分布 人口空间分布数据是在各项研究中经常使用的数据&#xff0…

新版IDEA配置前进和后退、打开资源管理器等快捷按钮

新版IDEA&#xff0c;好像是IDEA2024版本开始就默认隐藏了工具条&#xff0c;这时一些很常用的快捷按钮&#xff0c;如前进、后退、打开资源管理器就无法使用。这里图文介绍&#xff0c;如何把这些配置出来。 具体操作如下&#xff1a; 1、选择 File / Settings(windows版)&am…

解决jupyter notebook启动需要密码的问题

解决方法 在运行界面输入 jupyter notebook list 之后运行界面会输出token值&#xff0c;将对应地址后的token复制到密码栏中即可

14 大模型微调-KitTrain

1 介绍 如何降低占用的显存&#xff1a; 梯度累计&#xff1a;在一个完整的模型更新周期&#xff08;epoch&#xff09;中&#xff0c;将多个小批量&#xff08;mini-batches&#xff09;的数据的梯度进行累加&#xff0c;然后在一个较大的批量&#xff08;累积步数&#xff…

测试框架到底是什么,如何定义?

测试框架的关键组件是什么&#xff1f; 测试执行引擎&#xff1a;协调测试的运行、管理序列和报告结果。 测试脚本存储库&#xff1a;存储将要执行的实际测试用例或脚本。 测试数据&#xff1a;测试执行所需的输入数据&#xff0c;可以是静态的、动态的或动态生成的。 存根…

开店到经营,分贝通帮助连锁经营企业这样省钱

如果说大企业的经营核心是做好主营业务的大生意,那么对于连锁经营企业而言,线下门店的一个个小生意,其实也隐藏着“大学问”。费用支出方面,如何从细节处节流,让资金流呈现更良性循环,是连锁经营行业的重要课题。 1、开店前:选址BD全国跑,筐筐发票财务恼 2、日常经营:费用类目…

PMP–冲刺–十大领域易考点三大项目流程敏捷中的角色职责与3个工件高频考点考试技巧

文章目录 十大知识领域易考点--题干关键词一、整合管理二、范围管理三、进度管理四、成本管理五、质量管理六、资源管理七、沟通管理八、风险管理九、采购管理十、干系人管理 考试中的三大项目流程一 、变更流程二 、风险流程三 、收尾流程 敏捷中的角色职责与3个工件--题干关键…

es映射配置(_mapping)

文章目录 1、创建映射字段2、查看映射关系 1、创建映射字段 PUT /索引库名/_mapping {"properties": {"字段名": {"type": "类型","index": true&#xff0c;"store": true&#xff0c;"analyzer": &q…

LVGL | VisualStuio PC模拟器

LVGL | VisualStuio PC模拟器 时间&#xff1a;2024年8月30日17:46:41 文章目录 LVGL | VisualStuio PC模拟器1.参考Visual Studio 版本LVGL版本 2.工程代码3.演示 1.参考 1.16.LVGL&#xff08;UI设计&#xff09;_军事研究员的博客-CSDN博客 2.嵌入式UI开发-lvglwsl2vscode系…

HTML5好看的花店商城源码2

文章目录 1.设计来源1.1 主界面1.2 界面效果11.3 界面效果21.4 界面效果31.5 界面效果41.6 界面效果51.7 界面效果61.8 界面效果71.9 界面效果8 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#…

嵌入式OTG硬件电路分析

大家好,今天主要给大家分享一下,如何使用OTG硬件检测电路,和之前的接口有什么区别。 1. OTG接口与转换器 OTG是"On The Go"的英文缩写,字面上可以理解为“安上即可用”。USB传输是主从结构,一切USB传输都有Host发起。比如在开发板上可以插入U盘,这时开发板作为…

【数据分析预备】Numpy入门

Jupyter Notebook 是一个基于网页的交互式计算环境编写代码、运行代码、查看输出、可视化数据、分享报告文档按单元格运行代码可展示的信息格式更丰富&#xff08;支持Markdown和Latex)交互式运行环境 安装 cmd窗口 pip install notebook启动 jupyter notebook退出 CtrlC …

不平衡分类阈值移动的简单介绍

不平衡分类阈值移动的简单介绍 分类预测模型通常涉及预测类别标签。 尽管如此&#xff0c;许多机器学习算法能够预测类别成员的概率或得分&#xff0c;并且必须对其进行解释&#xff0c;然后才能将其映射到明确的类别标签。这是通过使用阈值&#xff08;例如 0.5&#xff09;…

甜羊浏览器:抖店多店铺管理与自动回复的最佳解决方案

随着短视频平台的蓬勃发展&#xff0c;抖音旗下的电商平台——抖店&#xff0c;已成为许多商家的重要销售渠道。然而&#xff0c;对于拥有多个抖店店铺的商家而言&#xff0c;如何高效管理这些店铺以及处理大量的客户咨询&#xff0c;成为了亟待解决的问题。此时&#xff0c;甜…

2D 凸包-2D Convex Hulls

2D 凸包-2D Convex Hulls 本章描述了CGAL中用于生成二维凸包的函数&#xff0c;以及用于检查点集是否为强凸的函数。还有许多用于计算特殊极值点和包点子序列的函数&#xff0c;如一组点的下包和上包。 CGAL提供了几种经典算法的实现&#xff0c;用于计算二维点集的逆时针极值…

论文《Generalized Focal Loss》阅读笔记

论文作者对自己文章的中文介绍&#xff1a;这里&#xff0c;所以本人结合论文进行一些简单记录。 存在的问题 之前的工作在训练阶段和推理阶段对最终得分的计算有些问题&#xff0c;即训练分开计算分类得分和定位得分&#xff0c;但是推理时又相乘得到最终的得分进行NMS&#…

读研刷题复习day01

27. 移除元素https://leetcode.cn/problems/remove-element/ 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c…

MySQL集群技术4——MySQL路由

mysql-route MySQL 路由&#xff08;Routing&#xff09;通常指的是在 MySQL 架构中如何处理客户端请求和数据流向的问题。在 MySQL 中&#xff0c;路由可以涉及多种不同的场景和技术&#xff0c;包括但不限于反向代理、负载均衡、读写分离等。下面我将详细介绍这些场景和技术…

解耦利器 - Java中的SPI机制

为什么需要SPI机制 SPI和API的区别是什么 SPI是一种跟API相对应的反向设计思想&#xff1a;API由实现方确定标准规范和功能&#xff0c;调用方无权做任何干预&#xff1b; 而SPI是由调用方确定标准规范&#xff0c;也就是接口&#xff0c;然后调用方依赖此接口&#xff0c;第…