当前位置: 首页 > news >正文

推进政府网站建设的措施/google关键词挖掘工具

推进政府网站建设的措施,google关键词挖掘工具,网站上线稳定后工作,网站代码开发定制提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、数据库设计二、实现代码1.SessionWrap2.websocket3.insertMessage4.清除未读 前言 使用WebSocket实现一对一的聊天功能与未读消息功能 一、数据库设计 会话…

提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、数据库设计
  • 二、实现代码
    • 1.SessionWrap
    • 2.websocket
    • 3.insertMessage
    • 4.清除未读


前言

使用WebSocket实现一对一的聊天功能与未读消息功能


一、数据库设计

会话表

字段名字段类型长度注释
conversation_idint11会话ID
create_timedatetime创建时间
conversation_typeint1会话类型

消息表

字段名字段类型长度注释
message_idint11消息ID
conversation_idint11会话ID
sender_idint11发送者ID
receiver_idin t11接收者ID
contenttext消息内容
typeint2消息类型
informationvarchar255信息
sender_imgint11发送者头像ID
receiver_imgint11接收者头像ID
message_statusint1消息状态(1已读,0未读)
create_timedatetime创建时间

二、实现代码

1.SessionWrap

@Data
public class SessionWrap {private String from;	// 连接人idprivate String type;	// 连接类型private Session session;private Date lastTime;
}

2.websocket

@Component
@ServerEndpoint(value = "/api/websocket/{from}/{type}")
public class WebSocketServer {@Autowiredprivate RqriMessageService rqriMessageService;public static WebSocketServer webSocketServer;// 所有的连接会话private static CopyOnWriteArraySet<SessionWrap> sessionList = new CopyOnWriteArraySet<>();private String from;private String type;@PostConstructpublic void init() {webSocketServer = this;webSocketServer.rqriMessageService = this.rqriMessageService;}@OnOpenpublic void onOpen(Session session, @PathParam(value = "from") String from, @PathParam(value = "type") String type) {this.from = from;this.type = type;try {// 遍历list,如果有会话,更新,如果没有,创建一个新的for (SessionWrap item : sessionList) {if (item.getFrom().equals(from) && item.getType().equals(type)) {item.setSession(session);item.setLastTime(new Date());log.info("【websocket消息】更新连接,总数为:" + sessionList.size());return;}}SessionWrap sessionWrap = new SessionWrap();sessionWrap.setFrom(from);sessionWrap.setType(type);sessionWrap.setSession(session);sessionWrap.setLastTime(new Date());sessionList.add(sessionWrap);log.info("【websocket消息】有新的连接,总数为:" + sessionList.size());} catch (Exception e) {log.info("【websocket消息】连接失败!错误信息:" + e.getMessage());}}@OnClosepublic void onClose() {try {sessionList.removeIf(item -> item.getFrom().equals(from) && item.getType().equals(type));log.info("【websocket消息】连接断开,总数为:" + sessionList.size());} catch (Exception e) {log.info("【websocket消息】连接断开失败!错误信息:" + e.getMessage());}}@OnMessagepublic void onMessage(String message, Session session) {try {if ("ping".equals(message)) {session.getBasicRemote().sendText("ping");	// 心跳检测} else {// 将消息插入到数据库JSONObject r = webSocketServer.rqriMessageService.insertMessage(message);// 成功if (r.getInteger("code") == 200) {JSONObject data = r.getJSONObject("data");String senderId = data.getString("senderId");      // 发送者String receiverId = data.getString("receiverId");   // 接收者for (SessionWrap item : sessionList) {if (senderId.equals(item.getFrom()) || receiverId.equals(item.getFrom()) ) {item.getSession().getBasicRemote().sendText(r.toJSONString());} }log.info("【websocket消息】发送消息:" + r.toJSONString());}}} catch (Exception e) {log.info("【websocket消息】发送消息失败!错误信息:" + e.getMessage());}}@OnErrorpublic void onError(Session session, Throwable error) {log.error("用户错误,原因:"+error.getMessage());error.printStackTrace();}}

3.insertMessage

private final String rqriMessageStr = "rqri_message_unread_";public JSONObject insertMessage(String message) {JSONObject jsonObject = new JSONObject();RqriMessage rqriMessage = JSONObject.parseObject(message, RqriMessage.class);// 把消息添加到数据库int i = rqriMessageMapper.insertSelective(rqriMessage);// 将未读信息添加到redis  添加接收者的未读String conversationId = String.valueOf(rqriMessage.getConversationId());String receiverId = String.valueOf(rqriMessage.getReceiverId());String key = rqriMessageStr + conversationId + "_" + receiverId;if (redisUtils.get(key) == null) {redisUtils.set(key, 1, 0); 	// 设置永不过期} else {redisUtils.incr(key, 1);	// 未读数量添加1}jsonObject.put("code", 200);jsonObject.put("data", rqriMessage);// 发送者的id和未读数量,返回给前端渲染到页面HashMap<String, Integer> map = new HashMap<>();map.put("num", Integer.valueOf(redisUtils.get(key).toString()));map.put("id", rqriMessage.getSenderId());jsonObject.put("isread", map);return jsonObject;
}

4.清除未读

最后在进入聊天页面和退出聊天页面时把未读数量清零。

相关文章:

使用WebSocket实现聊天功能

提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数据库设计二、实现代码1.SessionWrap2.websocket3.insertMessage4.清除未读 前言 使用WebSocket实现一对一的聊天功能与未读消息功能 一、数据库设计 会话…...

Ubuntu升级Cmake、gcc、g++

背景 最近要安装llvm&#xff0c;我选择的是从源码安装&#xff0c;所以要使用Cmake进行构建项目。但是服务器上的Cmake、gcc、g的版本都太低了&#xff0c;不符合要求&#xff0c;所以要对此进行升级。在本博客中采用的升级方法不一定是最好的方法&#xff08;因为我也是参考…...

8月28日上课内容 第四章 MySQL备份与恢复

本章结构 前言&#xff1a;日志⭐⭐ MySQL 的日志默认保存位置为 /usr/local/mysql/data ##配置文件 vim /etc/my.cnf [mysqld] ##错误日志&#xff0c;用来记录当MySQL启动、停止或运行时发生的错误信息&#xff0c;默认已开启 log-error/usr/local/mysql/data/mysql_error.l…...

es字段查询加keyword和不加keyword的区别

在ES&#xff08;Elasticsearch&#xff09;中&#xff0c;查询字段名后面加上"keyword"和不加"keyword"有着不同的含义和用途。 当字段名后面加上"keyword"时&#xff0c;表示该字段是一个keyword类型的字段。Keyword类型的字段会将文本作为一…...

前端JavaScript将数据转换成JSON字符串以及将JSON字符串转换成对象的两个API

在前端 JavaScript 中&#xff0c;你可以使用 JSON.stringify() 方法将 JavaScript 数据转换成 JSON 字符串&#xff0c;以及使用 JSON.parse() 方法将 JSON 字符串转换成 JavaScript 对象。下面是这两个 API 的详细说明和示例&#xff1a; JSON.stringify()&#xff1a; 用于…...

Spring——Spring Boot基础

文章目录 第一个helloword项目新建 Spring Boot 项目Spring Boot 项目结构分析SpringBootApplication 注解分析新建一个 Controller大功告成,运行项目 简而言之&#xff0c;从本质上来说&#xff0c;Spring Boot 就是 Spring&#xff0c;它做了那些没有它你自己也会去做的 Spri…...

Python基础之基础语法(二)

Python基础之基础语法(二) 语言类型 静态语言 如&#xff1a;C C Java ina a 100 a 100 a abc # 不可以静态语言需要指定声明标识符的类型&#xff0c;之后不可以改变类型赋值。静态语言变异的时候要检查类型&#xff0c;编写源代码&#xff0c;编译时检查错误。 动态语…...

docker常见面试问题详解

在面试的时候&#xff0c;面试官常常会问一些问题&#xff1a; docker是什么&#xff0c;能做什么&#xff1f;docker和虚拟机的区别是什么呢&#xff1f;docker是用什么做隔离的&#xff1f;docke的网络类型&#xff1f;docker数据之间是如何通信的&#xff1f;docker的数据保…...

Auto-GPT 学习笔记

Auto-GPT 学习笔记 Auto-GPT 简介 Auto-GPT 是一个基于 GPT-4 的自主智能体实验项目。它展示了大规模语言模型的规划、记忆和工具使用能力。Auto-GPT 的目标是实现一个完全自主的 AI 代理。GitHub 仓库 Auto-GPT 核心模块 规划(Planning) 使用强化学习策略进行多跳思考。通…...

代码随想录 - Day30 - 修剪二叉树,转换二叉树 + 二叉树总结

代码随想录 - Day30 - 修剪二叉树&#xff0c;转换二叉树 二叉树总结 669. 修剪二叉搜索树 有点像是删除二叉搜索树的变形&#xff0c;改变了删除条件而已。 递归法&#xff1a; class Solution:def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> O…...

[音视频] sdl 渲染到外部创建的窗口上

API SDL_CreateWindowFrom # 在外部窗口上创建窗口 其他 api 调用&#xff0c;按照之前的 代码 ui.setupUi(this); sdl_width ui.label->width(); sdl_height ui.label->height(); SDL_Init(SDL_INIT_VIDEO); sdl_win SDL_CreateWindowFrom((void*)ui.label->wi…...

MongoDB之索引

大数据量使用全集合查询&#xff0c;这是非常影响性能的&#xff0c;而索引可以加快查询效率&#xff0c;提高性能&#xff0c;所以这方面的知识也是必不可少的。 查询分析 explain()可以帮助我们分析查询语句性能。 语法 db.collection.find(...).explain()案例及结果 案…...

Redis的介绍

Redis的架构介绍如下: 1. 概述 Redis是一个基于内存的高性能NoSQL键值数据库,支持网络访问和持久化特性。 2. 功能架构 Redis提供字符串、哈希、列表、集合、有序集合、位数组等多种数据结构,支持事务、Lua脚本、发布订阅、流水线等功能。 3. 技术架构 Redis使用单线程的…...

一文了解Docker的用法

一、什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是…...

netcat的使用

目录 netcat简介 nc的使用场景 nc实现通信 创建一个服务端 创建一个客户端 具体案例 环境 win10在具体路径下执行命令 win7在具体路径下执行命令 netcat文件传输 nc文件传输的利用 服务器等待接收文件 客户端向服务器发送文件 服务器向连接的客户端发送文件 客户…...

深度学习推荐系统(二)Deep Crossing及其在Criteo数据集上的应用

深度学习推荐系统(二)Deep Crossing及其在Criteo数据集上的应用 在2016年&#xff0c; 随着微软的Deep Crossing&#xff0c; 谷歌的Wide&Deep以及FNN、PNN等一大批优秀的深度学习模型被提出&#xff0c; 推荐系统全面进入了深度学习时代&#xff0c; 时至今日&#xff0c…...

前端常用 Vue3 项目组件大全

Vue.js 是一种流行的 JavaScript 前端框架&#xff0c;它简化了构建交互式的用户界面的过程。Vue3 是 Vue.js 的最新版本&#xff0c;引入了许多新的特性和改进。在 Vue3 中&#xff0c;组件是构建应用程序的核心部分&#xff0c;它们可以重用、组合和嵌套。下面是一些前端开发…...

javaee spring 静态代理

静态代理 package com.test.staticProxy;public interface IUsersService {public void insert(); }package com.test.staticProxy;//目标类 public class UsersService implements IUsersService {Overridepublic void insert() {System.out.println("添加用户");…...

Java 包装类和Arrays类(详细解释)

目录 包装类 作用介绍 包装类的特有功能 Arrays类 Arrays.fill() Arrays.toString() Arrays.sort() 升序排序 降序排序 Arrays.equals() Arrays.copyOf() Arrays.binarySearch() 包装类 作用介绍 包装类其实就是8种基本数据类型对应的引用类型。 基本数据类型引用…...

elementUi中的el-table表格的内容根据后端返回的数据用不同的颜色展示

效果图如下&#xff1a; 首先 首先&#xff1a;需要在表格行加入 <template slot-scope"{ row }"> </template>标签 <el-table-column prop"usable" align"center" label"状态" width"180" ><templ…...

在访问一个网页时弹出的浏览器窗口,如何用selenium 网页自动化解决?

相信大家在使用selenium做网页自动化时&#xff0c;会遇到如下这样的一个场景&#xff1a; 在你使用get访问某一个网址时&#xff0c;会在页面中弹出如上图所示的弹出框。 首先想到是利用Alert类来处理它。 然而&#xff0c;很不幸&#xff0c;Alert类处理的结果就是没有结果…...

python 基于http方式与基于redis方式传输摄像头图片数据的实现和对比

目录 0. 需求1. 基于http方式传递图片数据1.1 发送图片数据1.2 接收图片数据并可视化1.3 测试 2. 基于redis方式传递图片数据2.1 发送图片数据2.2 接收图片数据并可视化2.3 测试 3. 对比 0. 需求 在不同进程或者不同语言间传递摄像头图片数据&#xff0c;比如从java实现的代码…...

快速使用Git完整开发

本系列有两篇文章&#xff1a; 一是本篇&#xff0c;主要说明了关于Git工具的基础使用&#xff0c;包含三板斧&#xff08;git add、git commit、git push&#xff09;、Git基本配置、版本回退、分支管理、公钥与私钥、远端仓库和远端分支、忽略文件、命令别名、标签等内容。二…...

鲁棒优化入门(7)—Matlab+Yalmip两阶段鲁棒优化通用编程指南(下)

0.引言 上一篇博客介绍了使用Yalmip工具箱求解单阶段鲁棒优化的方法。这篇文章将和大家一起继续研究如何使用Yalmip工具箱求解两阶段鲁棒优化(默认看到这篇博客时已经有一定的基础了&#xff0c;如果没有可以看看我专栏里的其他文章)。关于两阶段鲁棒优化与列与约束生成算法的原…...

Docker技术--Docker中的网络问题

1.docker中的网络通信 如果想要弄清楚docker中的网络通信问题,其实需要弄清楚这几个问题就可以:容器与容器之间的通信、容器与外部网络之间的通信、外部网络与容器之间的通信。 -a:容器与容器之间的通信,如下所示: 在默认情况下,docker使用网桥(Bridge模式)与NAT通信。这…...

ASP.NET Core 中的两种 Web API

ASP.NET Core 有两种创建 RESTful Web API 的方式&#xff1a; 基于 Controller&#xff0c;使用完整的基于ControllerBase的基类定义接口endpoints。基于 Minimal APIs&#xff0c;使用Lambda表达式定义接口 endpoints。 基于 Controller 的 Web API 可以使用构造函数注入&a…...

【线程池】如何判断线程池中的任务执行完毕(三)

目录 前言 1. isTerminated()方法 2. awaitTermination()方法 3.getTaskCount()方法和executor.getCompletedTaskCount()方法结合使用 4.使用CountDownlatch类 前言 通常我们使用线程池的时候&#xff0c;系统处于运行的状态&#xff0c;而线程池本身就是主要为了线程复用&…...

Qt/C++编写视频监控系统81-Onvif报警抓图和录像并回放

一、前言 视频监控系统中的图文警情模块&#xff0c;是通过Onvif协议的事件订阅拿到的&#xff0c;通过事件订阅后&#xff0c;设备的各种报警事件比如入侵报警/遮挡报警/越界报警/开关量报警等&#xff0c;触发后都会主动往订阅者发送&#xff0c;而且一般都是会发送两次&…...

浅谈安防视频监控平台EasyCVR视频汇聚平台对于夏季可视化智能溺水安全告警平台的重要性

每年夏天都是溺水事故高发的时期&#xff0c;许多未成年人喜欢在有水源的地方嬉戏&#xff0c;这导致了悲剧的发生。常见的溺水事故发生地包括水库、水坑、池塘、河流、溪边和海边等场所。 为了加强溺水风险的提示和预警&#xff0c;完善各类安全防护设施&#xff0c;并及时发现…...

基于单片机的串行通信发射机设计

一、项目介绍 串行通信是一种常见的数据传输方式&#xff0c;允许将数据以比特流的形式在发送端和接收端之间传输。当前实现基于STC89C52单片机的串行通信发射机&#xff0c;通过红外发射管和接收头实现自定义协议的数据无线传输。 二、系统设计 2.1 单片机选择 在本设计中&…...