From 43b4032bbbcf884b8a0e92ba9397e0e0e93ec9e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com>
Date: Thu, 4 Apr 2024 19:28:18 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=B9=E6=8E=A5chathub=E7=94=A8?=
=?UTF-8?q?=E6=88=B7=E5=88=97=E8=A1=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Dtos/ChatUserGetListOutputDto.cs | 26 +++++++
...ework.ChatHub.Application.Contracts.csproj | 1 -
.../Services/ChatUserService.cs | 32 +++++++++
.../SignalRHubs/ChatHub.cs | 69 +++++++++++++++++++
.../Yi.Framework.ChatHub.Application.csproj | 1 -
.../Caches/ChatOnlineUserCacheItem.cs | 65 +++++++++++++++++
.../Consts/ChatConst.cs | 13 ++++
.../Yi.Framework.ChatHub.Domain.Shared.csproj | 5 +-
.../Yi.Framework.ChatHub.Domain.csproj | 6 +-
.../YiFrameworkChatHubDomainModule.cs | 2 +
Yi.Bbs.Vue3/src/apis/chatUserApi.js | 8 +++
Yi.Bbs.Vue3/src/hubs/chatHub.js | 26 +++++++
Yi.Bbs.Vue3/src/layout/ChatLayout.vue | 10 ++-
Yi.Bbs.Vue3/src/main.js | 2 +-
Yi.Bbs.Vue3/src/stores/chat.js | 28 ++++++++
Yi.Bbs.Vue3/src/views/chathub/Index.vue | 24 +++++--
16 files changed, 302 insertions(+), 16 deletions(-)
create mode 100644 Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs
create mode 100644 Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs
create mode 100644 Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs
create mode 100644 Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Caches/ChatOnlineUserCacheItem.cs
create mode 100644 Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs
create mode 100644 Yi.Bbs.Vue3/src/apis/chatUserApi.js
create mode 100644 Yi.Bbs.Vue3/src/hubs/chatHub.js
create mode 100644 Yi.Bbs.Vue3/src/stores/chat.js
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs
new file mode 100644
index 00000000..3980460f
--- /dev/null
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.ChatHub.Application.Contracts.Dtos
+{
+ public class ChatUserGetListOutputDto
+ {
+ ///
+ /// 用户id
+ ///
+ public Guid UserId { get; set; }
+
+ ///
+ /// 用户名称
+ ///
+ public string UserName { get; set; }
+
+ ///
+ /// 用户头像
+ ///
+ public string UserIcon { get; set; }
+ }
+}
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj
index 4e071e4c..8df46007 100644
--- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj
@@ -9,7 +9,6 @@
-
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs
new file mode 100644
index 00000000..92da73da
--- /dev/null
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using FreeRedis;
+using Mapster;
+using Microsoft.Extensions.Options;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Caching;
+using Volo.Abp.DependencyInjection;
+using Yi.Framework.ChatHub.Application.Contracts.Dtos;
+using Yi.Framework.ChatHub.Domain.Shared.Caches;
+
+namespace Yi.Framework.ChatHub.Application.Services
+{
+ public class ChatUserService : ApplicationService
+ {
+ ///
+ /// 使用懒加载防止报错
+ ///
+ private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService();
+ private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>().Value.KeyPrefix;
+ public async Task> GetListAsync()
+ {
+ var key = new ChatOnlineUserCacheKey(CacheKeyPrefix);
+ var cacheUsers = (await RedisClient.HGetAllAsync(key.GetKey())).Select(x => System.Text.Json.JsonSerializer.Deserialize < ChatOnlineUserCacheItem >( x.Value)).ToList();
+ var output = cacheUsers.Adapt>();
+ return output;
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs
new file mode 100644
index 00000000..4dc09c99
--- /dev/null
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs
@@ -0,0 +1,69 @@
+using FreeRedis;
+using Mapster;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.SignalR;
+using Volo.Abp.Caching;
+using Volo.Abp.DependencyInjection;
+using Yi.Framework.ChatHub.Application.Contracts.Dtos;
+using Yi.Framework.ChatHub.Domain.Shared.Caches;
+using Yi.Framework.ChatHub.Domain.Shared.Consts;
+
+namespace Yi.Framework.ChatHub.Application.SignalRHubs
+{
+ [HubRoute("/hub/chat")]
+ [Authorize]
+ public class ChatHub : AbpHub
+ {
+ ///
+ /// 使用懒加载防止报错
+ ///
+ private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService();
+ ///
+ /// 缓存前缀
+ ///
+ private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>().Value.KeyPrefix;
+ public ChatHub()
+ {
+ }
+
+ ///
+ /// 用户进入聊天室
+ ///
+ ///
+ public override async Task OnConnectedAsync()
+ {
+ var key = new ChatOnlineUserCacheKey(CacheKeyPrefix);
+ var item = new ChatOnlineUserCacheItem()
+ {
+ UserId = CurrentUser.Id!.Value,
+ ClientId = Context.ConnectionId,
+ UserName = CurrentUser.UserName!
+ };
+
+
+ await RedisClient.HSetAsync(key.GetKey(), key.GetField(CurrentUser.Id!.Value), item);
+
+
+ //连接时,还需要去查询用户包含在的群组,将群主全部加入.Todo
+ await Groups.AddToGroupAsync(Context.ConnectionId, ChatConst.AllGroupName);
+ await Clients.All.SendAsync("liveUser", item.Adapt());
+
+
+ }
+
+ ///
+ /// 用户退出聊天室
+ ///
+ ///
+ ///
+ public async override Task OnDisconnectedAsync(Exception? exception)
+ {
+ var key = new ChatOnlineUserCacheKey(CacheKeyPrefix);
+ await RedisClient.HDelAsync(key.GetKey(), key.GetField(CurrentUser.Id!.Value));
+ await Groups.RemoveFromGroupAsync(Context.ConnectionId, ChatConst.AllGroupName);
+ await Clients.All.SendAsync("offlineUser", CurrentUser.Id!.Value);
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Yi.Framework.ChatHub.Application.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Yi.Framework.ChatHub.Application.csproj
index f56fff96..4df813a8 100644
--- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Yi.Framework.ChatHub.Application.csproj
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Yi.Framework.ChatHub.Application.csproj
@@ -9,7 +9,6 @@
-
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Caches/ChatOnlineUserCacheItem.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Caches/ChatOnlineUserCacheItem.cs
new file mode 100644
index 00000000..e130c1c4
--- /dev/null
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Caches/ChatOnlineUserCacheItem.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.ChatHub.Domain.Shared.Caches
+{
+ public class ChatOnlineUserCacheItem
+ {
+ public ChatOnlineUserCacheItem()
+ {
+
+
+ }
+ ///
+ /// 用户id
+ ///
+ public Guid UserId { get; set; }
+
+ ///
+ /// 用户名称
+ ///
+ public string UserName { get; set; }
+
+ ///
+ /// 用户头像
+ ///
+ public string UserIcon { get; set; }
+
+ ///
+ /// 客户端id
+ ///
+ public string ClientId { get; set; }
+
+ ///
+ /// 连接时间
+ ///
+ public DateTime CreationTime { get; }=DateTime.Now;
+
+ public override string ToString()
+ {
+ return System.Text.Json.JsonSerializer.Serialize(this);
+ }
+ }
+
+ public class ChatOnlineUserCacheKey
+ {
+ public string CacheKeyPrefix;
+ public ChatOnlineUserCacheKey(string cacheKeyPrefix )
+ {
+ CacheKeyPrefix=cacheKeyPrefix;
+ }
+
+ public string GetKey()
+ {
+ return $"{CacheKeyPrefix}ChatOnline";
+ }
+
+ public string GetField(Guid userId)
+ {
+ return $"{userId}";
+ }
+ }
+}
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs
new file mode 100644
index 00000000..f059a53a
--- /dev/null
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.ChatHub.Domain.Shared.Consts
+{
+ public class ChatConst
+ {
+ public const string AllGroupName = "all";
+ }
+}
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj
index 867a83ce..95fbf7f0 100644
--- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj
@@ -1,8 +1,6 @@
-
+
-
-
@@ -10,5 +8,6 @@
+
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj
index eb4a0764..d478ffca 100644
--- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj
@@ -1,4 +1,4 @@
-
+
@@ -12,8 +12,8 @@
-
-
+
+
diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs
index 2838749f..5554c43e 100644
--- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs
+++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs
@@ -1,4 +1,5 @@
using Volo.Abp.Domain;
+using Yi.Framework.Caching.FreeRedis;
using Yi.Framework.ChatHub.Domain.Shared;
@@ -6,6 +7,7 @@ namespace Yi.Framework.ChatHub.Domain
{
[DependsOn(
typeof(YiFrameworkChatHubDomainSharedModule),
+ typeof(YiFrameworkCachingFreeRedisModule),
typeof(AbpDddDomainModule)
)]
diff --git a/Yi.Bbs.Vue3/src/apis/chatUserApi.js b/Yi.Bbs.Vue3/src/apis/chatUserApi.js
new file mode 100644
index 00000000..d5bfb36e
--- /dev/null
+++ b/Yi.Bbs.Vue3/src/apis/chatUserApi.js
@@ -0,0 +1,8 @@
+import request from "@/config/axios/service";
+
+export function getList() {
+ return request({
+ url: "/chat-user",
+ method: "get"
+ });
+}
diff --git a/Yi.Bbs.Vue3/src/hubs/chatHub.js b/Yi.Bbs.Vue3/src/hubs/chatHub.js
new file mode 100644
index 00000000..6f4d4302
--- /dev/null
+++ b/Yi.Bbs.Vue3/src/hubs/chatHub.js
@@ -0,0 +1,26 @@
+import signalR from "@/utils/signalR";
+import useChatStore from "@/stores/chat";
+
+const receiveMsg = (connection) => {
+ const chatStore = useChatStore();
+ //上线用户
+ connection.on("liveUser", (user) => {
+ chatStore.addUser(user);
+ });
+ //下线用户
+ connection.on("offlineUser", (userId) => {
+ chatStore.delUser(userId);
+ });
+ //接受其他用户消息
+ connection.on("receiveMsg", (type, content) => {
+
+ });
+ //用户状态-正在输入中,无
+ connection.on("userStatus", (type) => {
+
+ });
+};
+export default () => {
+ signalR.start(`chat`, receiveMsg);
+}
+
diff --git a/Yi.Bbs.Vue3/src/layout/ChatLayout.vue b/Yi.Bbs.Vue3/src/layout/ChatLayout.vue
index 707a5ecb..0b96217d 100644
--- a/Yi.Bbs.Vue3/src/layout/ChatLayout.vue
+++ b/Yi.Bbs.Vue3/src/layout/ChatLayout.vue
@@ -4,6 +4,14 @@
+
\ No newline at end of file
+
diff --git a/Yi.Bbs.Vue3/src/main.js b/Yi.Bbs.Vue3/src/main.js
index 080d87ed..da231070 100644
--- a/Yi.Bbs.Vue3/src/main.js
+++ b/Yi.Bbs.Vue3/src/main.js
@@ -14,7 +14,7 @@ import * as ElementPlusIconsVue from "@element-plus/icons-vue";
import directive from "./directive"; // directive
import VueLuckyCanvas from '@lucky-canvas/vue'
-// import "./permission";
+import "./permission";
(async () => {
const app = createApp(App);
diff --git a/Yi.Bbs.Vue3/src/stores/chat.js b/Yi.Bbs.Vue3/src/stores/chat.js
new file mode 100644
index 00000000..16d779f9
--- /dev/null
+++ b/Yi.Bbs.Vue3/src/stores/chat.js
@@ -0,0 +1,28 @@
+import { defineStore } from "pinia";
+
+const chatStore = defineStore("chat", {
+ state: () => ({
+ userList: [],
+ }),
+// getters: {
+// userListData: (state) => state.userList,
+// },
+ actions: {
+ // 设置在线总数
+ setUserList(value) {
+ this.userList = value;
+ },
+ addUser(user)
+ {
+
+ this.userList.push(user);
+ },
+ delUser(userId)
+ {
+
+ this.userList = this.userList.filter(obj => obj.userId != userId);
+ }
+ },
+});
+
+export default chatStore;
diff --git a/Yi.Bbs.Vue3/src/views/chathub/Index.vue b/Yi.Bbs.Vue3/src/views/chathub/Index.vue
index a360657e..1afcf60c 100644
--- a/Yi.Bbs.Vue3/src/views/chathub/Index.vue
+++ b/Yi.Bbs.Vue3/src/views/chathub/Index.vue
@@ -1,6 +1,19 @@
+
+
-

@@ -38,8 +51,8 @@
-
橙子
-
现在感觉怎么样
+
官方学习交流群
+
冲冲冲
@@ -49,17 +62,16 @@
-
+
-
橙子
+
{{item.userName}}
现在感觉怎么样
10:28
-