diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..7ce8afb
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,123 @@
+
+# Contributor Covenant Code of Conduct
+
+English | [简体中文](./CODE_OF_CONDUCT_CN.md)
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual
+identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall
+ community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or advances of
+ any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email address,
+ without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of
+actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or permanent
+ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the
+community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenantversion 2.1][homepage],
+
+For answers to common questions about this code of conduct, see [https://www.contributor-covenant.org/faq][FAQ]
+
+[homepage]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
+[FAQ]: https://www.contributor-covenant.org/faq
diff --git a/CODE_OF_CONDUCT_CN.md b/CODE_OF_CONDUCT_CN.md
new file mode 100644
index 0000000..e4703cf
--- /dev/null
+++ b/CODE_OF_CONDUCT_CN.md
@@ -0,0 +1,84 @@
+
+# 贡献者公约
+
+[English](./CODE_OF_CONDUCT.md) | 简体中文
+
+## 我们的承诺
+
+身为社区成员、贡献者和领袖,我们承诺使社区参与者不受骚扰,无论其年龄、体型、可见或不可见的缺陷、族裔、性征、性别认同和表达、经验水平、教育程度、社会与经济地位、国籍、相貌、种族、种姓、肤色、宗教信仰、性倾向或性取向如何。
+
+我们承诺以有助于建立开放、友善、多样化、包容、健康社区的方式行事和互动。
+
+## 我们的准则
+
+有助于为我们的社区创造积极环境的行为例子包括但不限于:
+
+* 表现出对他人的同情和善意
+* 尊重不同的主张、观点和感受
+* 提出和大方接受建设性意见
+* 承担责任并向受我们错误影响的人道歉
+* 注重社区共同诉求,而非个人得失
+
+不当行为例子包括:
+
+* 使用情色化的语言或图像,及性引诱或挑逗
+* 嘲弄、侮辱或诋毁性评论,以及人身或政治攻击
+* 公开或私下的骚扰行为
+* 未经他人明确许可,公布他人的私人信息,如物理或电子邮件地址
+* 其他有理由认定为违反职业操守的不当行为
+
+## 责任和权力
+
+社区领袖有责任解释和落实我们所认可的行为准则,并妥善公正地对他们认为不当、威胁、冒犯或有害的任何行为采取纠正措施。
+
+社区领导有权力和责任删除、编辑或拒绝或拒绝与本行为准则不相符的评论(comment)、提交(commits)、代码、维基(wiki)编辑、议题(issues)或其他贡献,并在适当时机知采取措施的理由。
+
+## 适用范围
+
+本行为准则适用于所有社区场合,也适用于在公共场所代表社区时的个人。
+
+代表社区的情形包括使用官方电子邮件地址、通过官方社交媒体帐户发帖或在线上或线下活动中担任指定代表。
+
+## 监督
+
+辱骂、骚扰或其他不可接受的行为可通过社区群、微信公众号等向负责监督的社区领袖报告。
+所有投诉都将得到及时和公平的审查和调查。
+
+所有社区领袖都有义务尊重任何事件报告者的隐私和安全。
+
+## 处理方针
+
+社区领袖将遵循下列社区处理方针来明确他们所认定违反本行为准则的行为的处理方式:
+
+### 1. 纠正
+
+**社区影响**:使用不恰当的语言或其他在社区中被认定为不符合职业道德或不受欢迎的行为。
+
+**处理意见**:由社区领袖发出非公开的书面警告,明确说明违规行为的性质,并解释举止如何不妥。或将要求公开道歉。
+
+### 2. 警告
+
+**社区影响**:单个或一系列违规行为。
+
+**处理意见**:警告并对连续性行为进行处理。在指定时间内,不得与相关人员互动,包括主动与行为准则执行者互动。这包括避免在社区场所和外部渠道中的互动。违反这些条款可能会导致临时或永久封禁。
+
+### 3. 临时封禁
+
+**社区影响**: 严重违反社区准则,包括持续的不当行为。
+
+**处理意见**: 在指定时间内,暂时禁止与社区进行任何形式的互动或公开交流。在此期间,不得与相关人员进行公开或私下互动,包括主动与行为准则执行者互动。违反这些条款可能会导致永久封禁。
+
+### 4. 永久封禁
+
+**社区影响**:行为模式表现出违反社区准则,包括持续的不当行为、骚扰个人或攻击或贬低某个类别的个体。
+
+**处理意见**:永久禁止在社区内进行任何形式的公开互动。
+
+## 参见
+
+本行为准则改编自 [Contributor Covenant 2.1 版][homepage]。
+
+有关本行为准则的常见问题的答案,参见 [https://www.contributor-covenant.org/faq][FAQ]。
+
+[homepage]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
+[FAQ]: https://www.contributor-covenant.org/faq
diff --git a/README.md b/README.md
index 6bca532..b642c57 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,54 @@
-
-
-MallChat的后端项目,是一个既能购物又能即时聊天的电商系统。致力于打造互联网企业级项目的最佳实践。电商该有的购物车,订单,支付,推荐,搜索,拉新,促活,推送,物流,客服,它都必须有。持续更新ing~~(记得star啊喂!)
-
-
+
+
+
+
+
+MallChat-抹茶
+一个既能购物又能即时聊天的电商系统。致力于打造互联网企业级项目的最佳实践。
电商该有的购物车、订单、支付、推荐、搜索、拉新、促活、推送、物流、客服、它都必须有。持续更新 ing~
+
+
## 项目导航
-1. **快速体验地址**:[抹茶聊天首页](https://mallchat.cn)
-2. **前端项目仓库**:[MallChatWeb](https://github.com/Evansy/MallChatWeb)
-3. **项目视频记录**:[Bilibili地址](https://space.bilibili.com/146719540) 全程分享项目进度,功能选型的思考,同时征集迭代建议。
-4. **项目学习文档**:10w+字,保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、一个不落。可点击[抹茶项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)查看(内含500人交流大群)
-5. **项目交流群**:对抹茶感兴趣的,可以加入[交流群](#公众号)。你的每一个举动,都会决定项目未来的方向。无论是提意见做产品经理,还是找bug做个测试人员,又或者加入开发小模块成为contributer,都欢迎你的加入。
-6. **码云仓库**:[https://gitee.com/zhongzhibinbin/MallChat](https://gitee.com/zhongzhibinbin/MallChat) (国内访问速度更快)
+- **快速体验地址**:[抹茶聊天首页](https://mallchat.cn)
+- **前端项目仓库**:[MallChatWeb](https://github.com/Evansy/MallChatWeb)
+- **项目视频记录**:[Bilibili地址](https://space.bilibili.com/146719540) 全程分享项目进度,功能选型的思考,同时征集迭代建议。
+- **项目学习文档**:10w+字,保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、一个不落。可点击[抹茶项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)查看(内含500人交流大群)
+- **项目交流群**:对抹茶感兴趣的,可以加入[交流群](#公众号)。你的每一个举动,都会决定项目未来的方向。无论是提意见做产品经理,还是找bug做个测试人员,又或者加入开发小模块成为contributer,都欢迎你的加入。
+- **码云仓库**:[Gitee](https://gitee.com/zhongzhibinbin/MallChat)(国内访问速度更快)
## 项目介绍
-抹茶聊天是一个IM项目,通过netty实现和前端的websocket连接。内含微信扫描登录,成员列表,上下线动画,消息列表,消息互动,还有很多实用的小轮子列如aop日志,分布式锁注解,频控注解,ip解析归属地等,持续更新中。。。
+抹茶聊天是一个IM项目,通过netty实现和前端的websocket连接。内含微信扫描登录,成员列表,消息列表,消息互动,丰富的消息类型,还有很多实用的小轮子列如aop日志,分布式锁注解,频控注解,ip解析归属地等,持续更新中。。。
+
+
+
+
### 项目演示
#### C端项目
-- 前端项目地址:[https://github.com/Evansy/MallChatWeb](https://github.com/Evansy/MallChatWeb)
+- 前端源码地址:[https://github.com/Evansy/MallChatWeb](https://github.com/Evansy/MallChatWeb)
- 项目演示地址:[https://mallchat.cn](https://mallchat.cn) (记住抹茶.cn,下次工作摸鱼可直接打开)
-
+
+
+
### 技术选型
@@ -52,10 +69,11 @@ MallChat的后端项目,是一个既能购物又能即时聊天的电商系统
| Hutool | Java工具类库 | https://github.com/looly/hutool |
| Swagger-UI | API文档生成工具 | https://github.com/swagger-api/swagger-ui |
| Hibernate-validator | 接口校验框架 | [hibernate.org/validator/](hibernate.org/validator/) |
+| minio | 自建对象存储 | https://github.com/minio/minio |
#### 前端技术
-见[MallChatWeb](https://github.com/Evansy/MallChatWeb)
+前往[MallChatWeb](https://github.com/Evansy/MallChatWeb)查看
### 环境搭建
@@ -63,24 +81,80 @@ MallChat的后端项目,是一个既能购物又能即时聊天的电商系统
### 项目文档
-保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、项目亮点一个不落。点击[项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)
+保姆级教学路线,涵盖环境搭建、核心功能实现、基础架构构建、接口压力测试、问题记录以及项目的亮点。无一遗漏持续不断地更新中~
+查看[项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)
-更多有趣功能在持续更新中。。。
-
-
+
+

+

+
## star 趋势图

-## 贡献者
+## 贡献
+**贡献之前请先阅读[行为准则](CODE_OF_CONDUCT.md) 和 贡献指南。感谢所有为 MallChat 做过贡献的人!**
+
+#### 后端:
+
+
+
+#### 前端:
+
+
+
+优秀贡献者:
+
+
+
+
+
+
+
+## License
+[Apache License 2.0](./LICENSE)
## 公众号
微信搜索 **阿斌Java之路** 关注我的原创公众号,后台回复「**抹茶**」即可加入抹茶交流群,一些做过公司万人群聊,高并发的小伙伴都在里面讨论方案。公众号也会经常更新项目相关的文档,等你来撩~~

-
diff --git a/docs/image/复杂图片.jpg b/docs/image/复杂图片.jpg
new file mode 100644
index 0000000..feda4d6
Binary files /dev/null and b/docs/image/复杂图片.jpg differ
diff --git a/docs/image/文档1.jpg b/docs/image/文档1.jpg
new file mode 100644
index 0000000..c6638e4
Binary files /dev/null and b/docs/image/文档1.jpg differ
diff --git a/docs/image/文档2.jpg b/docs/image/文档2.jpg
new file mode 100644
index 0000000..4e78122
Binary files /dev/null and b/docs/image/文档2.jpg differ
diff --git a/docs/image/群聊截图.jpg b/docs/image/群聊截图.jpg
new file mode 100644
index 0000000..1ebff4a
Binary files /dev/null and b/docs/image/群聊截图.jpg differ
diff --git a/docs/image/设计模式.jpg b/docs/image/设计模式.jpg
new file mode 100644
index 0000000..4e0a949
Binary files /dev/null and b/docs/image/设计模式.jpg differ
diff --git a/docs/image/项目大纲.jpg b/docs/image/项目大纲.jpg
new file mode 100644
index 0000000..2de07a2
Binary files /dev/null and b/docs/image/项目大纲.jpg differ
diff --git a/docs/mallchat.sql b/docs/mallchat.sql
index 3a21d4b..9a94090 100644
--- a/docs/mallchat.sql
+++ b/docs/mallchat.sql
@@ -113,7 +113,8 @@ CREATE TABLE `user` (
INDEX `idx_create_time`(`create_time`) USING BTREE,
INDEX `idx_update_time`(`update_time`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
-
+INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10001, 'ChatGPT', 'https://img1.baidu.com/it/u=3613958228,3522035000&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500', 0, '??', '2023-06-29 17:03:03.357', NULL, NULL, 0, '2023-06-29 17:03:03.357', '2023-07-01 14:56:10.271');
+INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10002, 'ChatGLM2', 'http://mms1.baidu.com/it/u=1979830414,2984779047&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=500', NULL, '450', '2023-07-01 11:58:24.605', NULL, NULL, 0, '2023-07-01 11:58:24.605', '2023-07-01 12:02:56.900');
-- ----------------------------
-- Table structure for user_backpack
-- ----------------------------
diff --git a/docs/version/2023-07-01.sql b/docs/version/2023-07-01.sql
new file mode 100644
index 0000000..847dbeb
--- /dev/null
+++ b/docs/version/2023-07-01.sql
@@ -0,0 +1,2 @@
+INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10001, 'ChatGPT', 'https://img1.baidu.com/it/u=3613958228,3522035000&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500', 0, '??', '2023-06-29 17:03:03.357', NULL, NULL, 0, '2023-06-29 17:03:03.357', '2023-07-01 14:56:10.271');
+INSERT INTO `mallchat`.`user` (`id`, `name`, `avatar`, `sex`, `open_id`, `last_opt_time`, `ip_info`, `item_id`, `status`, `create_time`, `update_time`) VALUES (10002, 'ChatGLM2', 'http://mms1.baidu.com/it/u=1979830414,2984779047&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=500', NULL, '450', '2023-07-01 11:58:24.605', NULL, NULL, 0, '2023-07-01 11:58:24.605', '2023-07-01 12:02:56.900');
\ No newline at end of file
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/ThreadPoolConfig.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/ThreadPoolConfig.java
index 687f7f4..0a7a46d 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/ThreadPoolConfig.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/ThreadPoolConfig.java
@@ -1,9 +1,6 @@
package com.abin.mallchat.common.common.config;
-import cn.hutool.core.thread.NamedThreadFactory;
-import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.abin.mallchat.common.common.factory.MyThreadFactory;
-import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@@ -11,9 +8,7 @@ import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.*;
/**
* Description: 线程池配置
@@ -32,6 +27,9 @@ public class ThreadPoolConfig implements AsyncConfigurer {
*/
public static final String WS_EXECUTOR = "websocketExecutor";
+
+ public static final String AICHAT_EXECUTOR = "aichatExecutor";
+
@Override
public Executor getAsyncExecutor() {
return mallchatExecutor();
@@ -64,5 +62,15 @@ public class ThreadPoolConfig implements AsyncConfigurer {
return executor;
}
-
+ @Bean(AICHAT_EXECUTOR)
+ public ThreadPoolTaskExecutor chatAiExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setCorePoolSize(10);
+ executor.setMaxPoolSize(10);
+ executor.setQueueCapacity(15);
+ executor.setThreadNamePrefix("aichat-executor-");
+ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());//满了直接丢弃,默认为不重要消息推送
+ executor.setThreadFactory(new MyThreadFactory(executor));
+ return executor;
+ }
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java
index af02421..fe2a97e 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/JwtUtils.java
@@ -26,7 +26,7 @@ public class JwtUtils {
/**
* token秘钥,请勿泄露,请勿随便修改
*/
- @Value("jwt.secret")
+ @Value("${mallchat.jwt.secret}")
private String secret;
private static final String UID_CLAIM = "uid";
diff --git a/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java
new file mode 100644
index 0000000..50908e4
--- /dev/null
+++ b/mallchat-common/src/test/java/com/abin/mallchat/common/common/algorithm/ac/CreateTokenTest.java
@@ -0,0 +1,44 @@
+package com.abin.mallchat.common.common.algorithm.ac;
+
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.auth0.jwt.interfaces.JWTVerifier;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+
+import java.util.Date;
+
+
+@Slf4j
+public class CreateTokenTest {
+
+ @Test
+ public void create(){
+ String token = JWT.create()
+ .withClaim("uid", 123L) // 只存一个uid信息,其他的自己去redis查
+ .withClaim("createTime", new Date())
+ .sign(Algorithm.HMAC256("dsfsdfsdfsdfsd")); // signature
+ log.info("生成的token为 {}",token);
+
+
+ try {
+ JWTVerifier verifier = JWT.require(Algorithm.HMAC256("dsfsdfsdfsdfsd")).build();
+ DecodedJWT jwt = verifier.verify(token);
+ log.info(jwt.getClaims().toString());
+ } catch (Exception e) {
+ log.info("decode error,token:{}", token, e);
+ }
+ }
+
+ @Test
+ public void verifyToken(){
+ String token = JWT.create()
+ .withClaim("uid", 1) // 只存一个uid信息,其他的自己去redis查
+ .withClaim("createTime", new Date())
+ .sign(Algorithm.HMAC256("dsfsdfsdfsdfsd")); // signature
+ log.info("生成的token为{}",token);
+ }
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/AbstractChatAIHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/AbstractChatAIHandler.java
index 04e5a6e..e644b4d 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/AbstractChatAIHandler.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chatai/handler/AbstractChatAIHandler.java
@@ -1,10 +1,8 @@
package com.abin.mallchat.custom.chatai.handler;
-import cn.hutool.core.thread.NamedThreadFactory;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
-import com.abin.mallchat.common.common.exception.BusinessException;
-import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler;
+import com.abin.mallchat.common.common.config.ThreadPoolConfig;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import com.abin.mallchat.custom.chat.domain.vo.request.msg.TextMsgReq;
import com.abin.mallchat.custom.chat.service.ChatService;
@@ -12,22 +10,18 @@ import com.abin.mallchat.custom.user.domain.vo.response.user.UserInfoResp;
import com.abin.mallchat.custom.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import javax.annotation.PostConstruct;
import java.util.Collections;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
@Slf4j
-@Component
-public abstract class AbstractChatAIHandler implements DisposableBean, InitializingBean {
- public static ExecutorService EXECUTOR;
+public abstract class AbstractChatAIHandler {
+ @Autowired
+ @Qualifier(ThreadPoolConfig.AICHAT_EXECUTOR)
+ private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
protected ChatService chatService;
@@ -47,7 +41,7 @@ public abstract class AbstractChatAIHandler implements DisposableBean, Initializ
if (!supports(message)) {
return;
}
- EXECUTOR.execute(() -> {
+ threadPoolTaskExecutor.execute(() -> {
String text = doChat(message);
if (StringUtils.isNotBlank(text)) {
answerMsg(text, message.getRoomId(), message.getFromUid());
@@ -101,30 +95,4 @@ public abstract class AbstractChatAIHandler implements DisposableBean, Initializ
chatService.sendMsg(answerReq, getChatAIUserId());
}
- @Override
- public void afterPropertiesSet() {
- EXECUTOR = new ThreadPoolExecutor(
- 10,
- 10,
- 0L,
- TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<>(15),
- new NamedThreadFactory("openAI-chat-gpt",
- null,
- false,
- new GlobalUncaughtExceptionHandler()),
- (r, executor) -> {
- throw new BusinessException("别问的太快了,我的脑子不够用了");
- });
- }
-
- @Override
- public void destroy() throws Exception {
- EXECUTOR.shutdown();
- if (!EXECUTOR.awaitTermination(30, TimeUnit.SECONDS)) { //最多等30秒,处理不完就拉倒
- if (log.isErrorEnabled()) {
- log.error("Timed out while waiting for executor [{}] to terminate", EXECUTOR);
- }
- }
- }
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/HttpTraceIdFilter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/HttpTraceIdFilter.java
index 35c9ac9..a8d1c7b 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/HttpTraceIdFilter.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/intecepter/HttpTraceIdFilter.java
@@ -23,6 +23,7 @@ public class HttpTraceIdFilter implements Filter {
String tid = UUID.randomUUID().toString();
MDC.put(MDCKey.TID, tid);
chain.doFilter(request, response);
+ MDC.remove(MDCKey.TID);
}
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java
index 72f4b3c..30f6cdd 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/HttpHeadersHandler.java
@@ -4,13 +4,11 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
-import io.netty.util.AttributeKey;
import org.apache.commons.lang3.StringUtils;
import java.net.InetSocketAddress;
public class HttpHeadersHandler extends ChannelInboundHandlerAdapter {
- private AttributeKey key = AttributeKey.valueOf("Id");
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
@@ -22,6 +20,7 @@ public class HttpHeadersHandler extends ChannelInboundHandlerAdapter {
ip = address.getAddress().getHostAddress();
}
NettyUtil.setAttr(ctx.channel(), NettyUtil.IP, ip);
+ ctx.pipeline().remove(this);
}
ctx.fireChannelRead(msg);
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java
index d2bacef..79daafa 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyUtil.java
@@ -12,6 +12,7 @@ import io.netty.util.AttributeKey;
public class NettyUtil {
+ public static AttributeKey TOKEN = AttributeKey.valueOf("token");
public static AttributeKey IP = AttributeKey.valueOf("ip");
public static AttributeKey UID = AttributeKey.valueOf("uid");
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java
index 4ebf470..b70b867 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServer.java
@@ -10,7 +10,6 @@ import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
-import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
@@ -89,7 +88,7 @@ public class NettyWebSocketServer {
* 4. WebSocketServerProtocolHandler 核心功能是把 http协议升级为 ws 协议,保持长连接;
* 是通过一个状态码 101 来切换的
*/
- pipeline.addLast(new WebSocketServerProtocolHandler("/"));
+ pipeline.addLast(new WebSocketHandshakeHandler());
// 自定义handler ,处理业务逻辑
pipeline.addLast(new NettyWebSocketServerHandler());
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java
index 7f1c981..3d75069 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/websocket/NettyWebSocketServerHandler.java
@@ -1,5 +1,6 @@
package com.abin.mallchat.custom.user.websocket;
+import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.abin.mallchat.custom.user.domain.enums.WSReqTypeEnum;
@@ -66,6 +67,10 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler