基于WebSocket实现客户聊天室

目录

一、实现聊天室原理

二、聊天室前端代码

三、聊天室后端代码(重点)

四、聊天室实现效果展示


一、实现聊天室原理

1.1 介绍websocket协议

websocket是一种通信协议,再通过websocket实现弹幕聊天室时候,实现原理是客户端首先使用http协议请求服务器将通信协议转为websocket协议。

1.2、websocket的API

websocket分为客户端与服务器,其实现的API都不一样。

前端创建websocket案例:

<script>
let ws = new WebSocket("ws:/localhost/chat")
ws.open = function(){
};ws.onmessage = function(evt){//通过evt.data 可以获取服务器发送的数据
};ws.onclose = function(){
};</script>

1.3 项目实现流程

1.4 项目结构


二、聊天室前端代码

前端核心在于两个:一个登陆界面,一个聊天室界面。

登陆界面:

<!DOCTYPE html>
<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>聊天室</h1>
</div>
<div class="main-content-agile" id="app"><div class="sub-main-w3"><h2>登录</h2><form id="loginForm"><div class="icon1"><input placeholder="用户名" id="username" v-model="user.username" type="text"/></div><div class="icon2"><input placeholder="密码" id="password" v-model="user.password" type="password"/></div><div class="clear"></div><input type="button" id="btn1" @click="login" value="登录"/><div class="icon1"><span id="err_msg" style="color: red; ">{{errMessage}}</span></div></form></div>
</div>
<div class="footer"><p>北京传智播客教育科技有限公司 版权所有Copyright 2006-2019  All Rights Reserved </p>
</div>
<script src="js/vue.js"></script>
<script src="js/axios-0.18.0.js"></script>
<script>new Vue({el:"#app",data() {return {errMessage: "",user:{username:"",password:""}}},methods: {login() {axios.post("user/login",this.user).then(res => {//判断登陆是否成功if(res.data.flag) {location.href = "main.html"} else {this.errMessage = res.data.message;}});}}});
</script>
</body>
</html>

效果:

聊天室页面:

<!DOCTYPE html>
<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>聊天室</h1>
</div>
<div class="main-content-agile" id="app"><div class="sub-main-w3"><h2>登录</h2><form id="loginForm"><div class="icon1"><input placeholder="用户名" id="username" v-model="user.username" type="text"/></div><div class="icon2"><input placeholder="密码" id="password" v-model="user.password" type="password"/></div><div class="clear"></div><input type="button" id="btn1" @click="login" value="登录"/><div class="icon1"><span id="err_msg" style="color: red; ">{{errMessage}}</span></div></form></div>
</div>
<div class="footer"><p>北京传智播客教育科技有限公司 版权所有Copyright 2006-2019  All Rights Reserved </p>
</div>
<script src="js/vue.js"></script>
<script src="js/axios-0.18.0.js"></script>
<script>new Vue({el:"#app",data() {return {errMessage: "",user:{username:"",password:""}}},methods: {login() {axios.post("user/login",this.user).then(res => {//判断登陆是否成功if(res.data.flag) {location.href = "main.html"} else {this.errMessage = res.data.message;}});}}});
</script>
</body>
</html>


三、聊天室后端代码(重点)

3.1首先需要创建springboot项目,并导入以下jar包.

<!--        使用阿里巴巴的fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.78</version></dependency><!--        实现websocket的jar包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

3.2 实现websocket,还需要对其进行配置,创建两个配置类

第一个进行websocketConfig的配置

@Configuration
public class WebsocketConfig {// 将ServerEndPointExplorer加入ioc容器中@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

第二个配置是获取httpsession配置

public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator {@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {//获取HttpSession对象HttpSession httpSession = (HttpSession) request.getHttpSession();//将httpSession对象保存起来sec.getUserProperties().put(HttpSession.class.getName(),httpSession);}
}

项目中需要ServerEndPoint存储所有用户的session对象,通过session实现用户之间的交流。所以还需要获取所有httpsession对象。

3.3 确定消息格式(JSON)

 为了确保实现的消息格式的准确,需要创建对应工具类,确保对应的格式的准确。

public class MessageUtils {public static String getMessage(boolean isSystemMessage,String fromName, Object message) {ResultMessage result = new ResultMessage();result.setSystem(isSystemMessage);result.setMessage(message);if(fromName != null) {result.setFromName(fromName);}return JSON.toJSONString(result);}
}

3.4 然后就是所有实体类的创建。

对于前端实体类,需要用户,封装http请求实体。

对于聊天室,需要用户发送的信息,服务器给用户发送的信息。

@Data
public class Result {private boolean flag;private String message;
}
@Data
public class User {private String userId;private String username;private String password;
}
@Data
public class Message {private String toName;private String message;
}
@Data
public class ResultMessage {private boolean isSystem;private String fromName;private Object message;//如果是系统消息是数组
}

3.5 后端基础功能的实现

后端实现登陆功能:用户名可以随意输入,但是密码必须是123。

    @PostMapping("/login")public Result login(@RequestBody User user, HttpSession session) {Result result = new Result();if(user != null && "123".equals(user.getPassword())) {result.setFlag(true);//将数据存储到session对象中session.setAttribute("user",user.getUsername());} else {result.setFlag(false);result.setMessage("登陆失败");}return result;}

后端实现获取用户名称功能:

 @GetMapping("/getUsername")public String getUsername(HttpSession session) {String username = (String) session.getAttribute("user");return username;}

 3.6 通过session发送消息的核心功能(重点)

@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfig.class)
@Component
public class ChatEndpoint {private static Map<String,Session> onlineUsers = new ConcurrentHashMap<>();static {// 初始化onlineUsers对象onlineUsers = new ConcurrentHashMap<>();}private HttpSession httpSession;/*** 建立websocket连接后,被调用* @param session*/@OnOpenpublic void onOpen(Session session, EndpointConfig config) {//1,将session进行保存this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());String user = (String) this.httpSession.getAttribute("user");onlineUsers.put(user,session);//2,广播消息。需要将登陆的所有的用户推送给所有的用户String message = MessageUtils.getMessage(true,null,getFriends());broadcastAllUsers(message);}public Set getFriends() {Set<String> set = onlineUsers.keySet();return set;}private void broadcastAllUsers(String message) {try {//遍历map集合Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();for (Map.Entry<String, Session> entry : entries) {//获取到所有用户对应的session对象Session session = entry.getValue();//发送消息session.getBasicRemote().sendText(message);}} catch (Exception e) {//记录日志}}/*** 浏览器发送消息到服务端,该方法被调用** 张三  -->  李四* @param message*/@OnMessagepublic void onMessage(String message) {try {//将消息推送给指定的用户Message msg = JSON.parseObject(message, Message.class);//获取 消息接收方的用户名String toName = msg.getToName();String mess = msg.getMessage();//获取消息接收方用户对象的session对象Session session = onlineUsers.get(toName);String user = (String) this.httpSession.getAttribute("user");String msg1 = MessageUtils.getMessage(false, user, mess);session.getBasicRemote().sendText(msg1);} catch (Exception e) {//记录日志}}/*** 断开 websocket 连接时被调用* @param session*/@OnClosepublic void onClose(Session session) {//1,从onlineUsers中剔除当前用户的session对象String user = (String) this.httpSession.getAttribute("user");onlineUsers.remove(user);//2,通知其他所有的用户,当前用户下线了String message = MessageUtils.getMessage(true,null,getFriends());broadcastAllUsers(message);}
}

代码重点在于对session的使用,将内容放在对应用户session的共享域中,后端则负责统一管理所有用户的session。


四、聊天室实现效果展示

4.1 登陆功能:

4.2 在线与不在线,当后端运行后才能显示在线

4.3 当有其他人登陆时候弹出对应用户名称

4.4 通过点击对应的名称进行一对一聊天

4.5 实现聊天功能


 

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

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

相关文章

Unity Image - 镜像

1、为什么要使用镜像 在游戏开发过程中&#xff0c;我们经常会为了节省 美术图片资源大小&#xff0c;美术会将两边相同的图片进行切一半来处理。如下所示一个按钮 需要 400 * 236&#xff0c;然而美术只需要切一张 74*236的大小就可以了。这样一来图集就可以容纳更多的图片。…

HarmonyOs 4 (一) 认识HarmonyOs

目录 一 HarmonyOs 背景1.1 发展时间线1.2 背景分析1.2.1 新场景1.2.2 新挑战1.2.3 鸿蒙生态迎接挑战 二 HarmonyOS简介2.1 OpenHarmony2.2 HarmonyOS Connect2.3 HarmonyOS Next**2.4 ArkTS &#xff08;重点掌握&#xff09;****2.5 ArkUI** 三 鸿蒙生态应用核心技术理念**3.…

SmartSoftHelp8,数据库字段详细文档自动生成工具

数据库开发文档自动生成 包括数据库设计详细信息&#xff1a; 数据库字段名称&#xff0c;数据类型&#xff0c;大小&#xff0c;是否主键&#xff0c;说明等 一键自动生成开发需求文档 导出html 格式方便查询 下载地址 https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg…

Spring---更简单的存储和读取对象

文章目录 存储Bean对象配置扫描路径添加注解存储Bean对象使用类注解为什么需要五个类注解呢&#xff1f;Bean命名规则 使用方法注解重命名Bean 读取Bean对象属性注入Setter注入构造方法注入注入多个相同类型的BeanAutowired vs Resource 存储Bean对象 配置扫描路径 注&#xf…

maven下载和安装

maven下载和安装 一、概述 Maven是一个项目管理工具&#xff0c;它包含了一个项目对象模型 (Project Object Model)&#xff0c;一组标准集合&#xff0c;一个项目生命周期(Project Lifecycle)&#xff0c;一个依赖管理系统(Dependency Management System)&#xff0c;和用来…

conda环境下 ERROR: CMake must be installed to build dlib问题解决

1 问题描述 在构建video_retalking项目过程中&#xff0c;使用命令安装依赖包时&#xff0c;运行依赖安装命令&#xff1a; pip install -r requirements.txt 出现如下错误&#xff1a; Building wheels for collected packages: face-alignment, dlib, ffmpy, futureBuil…

【HuggingFace Transformer库学习笔记】基础组件学习:Tokenizer

基础组件——Tokenizer &#xff08;1&#xff09;模型加载 from transformers import AutoTokenizersen "弱小的我也有大梦想!" # 从HuggingFace加载&#xff0c;输入模型名称&#xff0c;即可加载对于的分词器 tokenizer AutoTokenizer.from_pretrained("m…

〖大前端 - 基础入门三大核心之JS篇㊸〗- DOM事件对象及它的属性

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

【稳定检索|投稿优惠】2024年生物神经工程与健康大数据国际会议(ICBNHBD 2024)

2024年生物神经工程与健康大数据国际会议(ICBNHBD 2024) 2024 International Conference on Biological Neuroengineering and Health Big Data(ICBNHBD) 一、【会议简介】 2024年生物神经工程与健康大数据国际会议(ICBNHBD 2024)&#xff0c;这场科学盛宴&#xff0c;会议在中…

rtsp点播异常出现‘circluar_buffer_size‘ option was set but it is xx

先说现象: 我使用potplay播放器来点播rtsp码流的时候可以点播成功&#xff0c;同事使用vlc和FFplay来点播rtsp码流的时候异常。 排查思路: 1.开始怀疑是oss账号问题&#xff0c;因为ts切片数据是保存在oss中的&#xff0c;我使用的是自己的oss账号&#xff0c;同事使用的是公司…

Azure Machine Learning - 使用 REST API 创建 Azure AI 搜索索引

本文介绍如何使用 Azure AI 搜索 REST AP和用于发送和接收请求的 REST 客户端以交互方式构建请求。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员&…

Python 安装mysqlclient 错误 无法打开包括文件: “mysql.h”: 解决方法

解决方案&#xff1a;python最新3.12.0不支持mysqlclient 请下载 python3.9.9 版本 高速下载地址CNPM Binaries Mirror 官方下载地址Welcome to Python.org 下载完成后将python添加到环境变量 pycharm 虚拟环境下的python版本切换到你刚才下载的3.9.9的python版本 Avai…

C++动态内存管理new,delete

C动态内存管理new&#xff0c;delete 1.C/C内存分布2.C语言中的内存管理方式3.C中的内存管理方式new&#xff0c;delete3.1C中的内置类型new&#xff0c;delete3.2new&#xff0c;delete操作自定义类型3.3 new和delete匹配 4. operator new与operator delete函数4.1new和delete…

反转链表的实现

题目描述&#xff1a; 给出一个链表的头节点&#xff0c;将其反转&#xff0c;并返回新的头节点 思路1&#xff1a;反转地址 将每个节点里的地址由指向下一个节点变为指向前一个节点 定义三个结构体指针n1,n2,n3,n1表示改后指针的地址&#xff0c;n2表示要修改结构体里next的…

PT读spef报PARA-006如何解决?

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 There are multiple causes that can trigger PARA-006 errors. Here is a checklist. 1) SPEF reading order Functionally, the parasitic files can be read in any order. For best stitching…

百度飞桨(张江)人工智能产业赋能中心入驻申请

中心如何赋能 百度飞桨&#xff08;张江&#xff09;人工智能产业赋能中心是浦东“大企业开放创新中心计划”首批企业代表&#xff0c;百度和张江集团将联合为入驻初创企业及生态合作伙伴提供以下服务&#xff1a; 降低AI使用门槛 通过“百度飞桨人工智能公共技术平台”&#x…

解决git与huggingface项目下载速度慢或者失败的问题

git clone 项目报错 比如使用git clone 下载项目&#xff1a; git clone https://github.com/ChuRuaNh0/FastSam_Awsome_TensorRT.git有时候会报以下错误&#xff1a; fatal: unable to access ‘https://github.com/xxx.git/’: Failed to connect to github.com port 443 …

[读论文]meshGPT

概述 任务&#xff1a;无条件生成mesh &#xff08;无颜色&#xff09;数据集&#xff1a;shapenet v2方法&#xff1a;先trian一个auto encoder&#xff0c;用来获得code book&#xff1b;然后trian一个自回归的transformermesh表达&#xff1a;face序列。face按规定的顺序&a…

大型网站系统架构演化(Web)

大型网站系统架构演化 大型网站系统架构演化需要关注的维度涉及的技术演进过程单体架构垂直架构使用缓存改善网站性能缓存与数据库的数据一致性问题缓存技术对比Redis分布式存储方案Redis集群切片的常见方式Redis数据类型Redis 淘汰算法使用服务集群改善网站并发能力 大型网站系…

Python实现FA萤火虫优化算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法&#xff08;Fire-fly algorithm&#xff0c;FA&#xff09;由剑桥大学Yang于2009年提出 , …