diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs index 8a269c6e..e2824f0e 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/SignalRHubs/OnlineHub.cs @@ -9,7 +9,8 @@ using Yi.Framework.Rbac.Domain.Shared.Model; namespace Yi.Framework.Rbac.Application.SignalRHubs { [HubRoute("/hub/main")] - [Authorize] + //开放不需要授权 + //[Authorize] public class OnlineHub : AbpHub { public static readonly List clientUsers = new(); @@ -32,33 +33,32 @@ namespace Yi.Framework.Rbac.Application.SignalRHubs { lock (objLock) { - var name = CurrentUser.UserName; var loginUser = new LoginLogEntity().GetInfoByHttpContext(_httpContext); - var user = clientUsers.Any(u => u is not null && u.ConnnectionId == Context.ConnectionId); - //判断用户是否存在,否则添加集合 - if (!user) + + OnlineUserModel user = new(Context.ConnectionId) { - OnlineUserModel users = new(Context.ConnectionId) - { - Browser = loginUser?.Browser, - LoginLocation = loginUser?.LoginLocation, - Ipaddr = loginUser?.LoginIp, - LoginTime = DateTime.Now, - Os = loginUser?.Os, - UserName = name ?? "Null", - UserId = CurrentUser.Id ?? Guid.Empty - }; + Browser = loginUser?.Browser, + LoginLocation = loginUser?.LoginLocation, + Ipaddr = loginUser?.LoginIp, + LoginTime = DateTime.Now, + Os = loginUser?.Os, + UserName = name ?? "Null", + UserId = CurrentUser.Id ?? Guid.Empty + }; - - //先移除之前的用户id,一个用户只能一个 + //已登录 + if (CurrentUser.Id is not null) + { //先移除之前的用户id,一个用户只能一个 clientUsers.RemoveAll(u => u.UserId == CurrentUser.Id); - clientUsers.Add(users); _logger.LogInformation($"{DateTime.Now}:{name},{Context.ConnectionId}连接服务端success,当前已连接{clientUsers.Count}个"); - - //当有人加入,向全部客户端发送当前总数 - Clients.All.SendAsync("onlineNum", clientUsers.Count); } + //全部移除之后,再进行添加 + clientUsers.RemoveAll(u => u.ConnnectionId == Context.ConnectionId); + + clientUsers.Add(user); + //当有人加入,向全部客户端发送当前总数 + Clients.All.SendAsync("onlineNum", clientUsers.Count); } return base.OnConnectedAsync(); } @@ -73,23 +73,18 @@ namespace Yi.Framework.Rbac.Application.SignalRHubs { lock (objLock) { - var user = clientUsers.Where(p => p.ConnnectionId == Context.ConnectionId).FirstOrDefault(); - //判断用户是否存在,否则添加集合 - if (user != null) + //已登录 + if (CurrentUser.Id is not null) { - clientUsers.RemoveAll(u => u.UserId == CurrentUser.Id || u.ConnnectionId == u.ConnnectionId); - Clients.All.SendAsync("onlineNum", clientUsers.Count); - _logger.LogInformation($"用户{user?.UserName}离开了,当前已连接{clientUsers.Count}个"); - + clientUsers.RemoveAll(u => u.UserId == CurrentUser.Id); + _logger.LogInformation($"用户{CurrentUser?.UserName}离开了,当前已连接{clientUsers.Count}个"); } + clientUsers.RemoveAll(u => u.ConnnectionId == Context.ConnectionId); + Clients.All.SendAsync("onlineNum", clientUsers.Count); } return base.OnDisconnectedAsync(exception); } - public async Task SendAllTest(string test) - { - await Clients.All.SendAsync("ReceiveAllInfo", test); - } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index 708030a2..8b38803f 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -59,7 +59,6 @@ namespace Yi.Abp.Web var configuration = context.Services.GetConfiguration(); var host = context.Services.GetHostingEnvironment(); var service = context.Services; - //请求日志 Configure(optios => { @@ -261,8 +260,12 @@ namespace Yi.Abp.Web //跨域 app.UseCors(DefaultCorsPolicyName); - //速率限制 - app.UseRateLimiter(); + if (!env.IsDevelopment()) + { + //速率限制 + app.UseRateLimiter(); + } + //无感token,先刷新再鉴权 app.UseRefreshToken(); diff --git a/Yi.Bbs.Vue3/src/App.vue b/Yi.Bbs.Vue3/src/App.vue index 76c23713..36c227f9 100644 --- a/Yi.Bbs.Vue3/src/App.vue +++ b/Yi.Bbs.Vue3/src/App.vue @@ -6,12 +6,12 @@ diff --git a/Yi.Bbs.Vue3/src/hubs/mainHub.js b/Yi.Bbs.Vue3/src/hubs/mainHub.js new file mode 100644 index 00000000..423698ce --- /dev/null +++ b/Yi.Bbs.Vue3/src/hubs/mainHub.js @@ -0,0 +1,22 @@ +import signalR from "@/utils/signalR"; +import useSocketStore from "@/stores/socket.js"; +const receiveMsg=(connection)=> { + connection.on("onlineNum", (data) => { + const socketStore = useSocketStore(); + socketStore.setOnlineNum(data); + }); + connection.on("forceOut", (msg) => { + useUserStore() + .logOut() + .then(() => { + alert(msg); + location.href = "/index"; + }); + }); + }; + + export default ()=>{ + signalR.start(`main`,receiveMsg); +} + + diff --git a/Yi.Bbs.Vue3/src/hubs/noticeHub.js b/Yi.Bbs.Vue3/src/hubs/noticeHub.js new file mode 100644 index 00000000..ace5339f --- /dev/null +++ b/Yi.Bbs.Vue3/src/hubs/noticeHub.js @@ -0,0 +1,28 @@ +import signalR from "@/utils/signalR"; +const receiveMsg=(connection)=> { + connection.on("receiveNotice", (type, title, content) => { + switch (type) { + case "MerryGoRound": + ElNotification({ + title: title, + dangerouslyUseHTMLString: true, + message: content, + }) + break; + case "Popup": + ElNotification({ + title: title, + dangerouslyUseHTMLString: true, + message: content, + }) + break; + } + }); + + }; + + export default ()=>{ + signalR.start(`notice`,receiveMsg); +} + + diff --git a/Yi.Bbs.Vue3/src/layout/AppHeader.vue b/Yi.Bbs.Vue3/src/layout/AppHeader.vue index b3558f7c..130e4031 100644 --- a/Yi.Bbs.Vue3/src/layout/AppHeader.vue +++ b/Yi.Bbs.Vue3/src/layout/AppHeader.vue @@ -86,7 +86,6 @@ import useUserStore from "@/stores/user.js"; import useConfigStore from "@/stores/config"; import useAuths from "@/hooks/useAuths"; import { Session } from "@/utils/storage"; -import signalR from "@/utils/signalR"; const { isLogin, clearStorage } = useAuths(); const configStore = useConfigStore(); @@ -106,7 +105,6 @@ const logout = async () => { }).then(async () => { //异步 await userStore.logOut(); - await signalR.close(); //删除成功后,跳转到主页 router.push("/login"); ElMessage({ diff --git a/Yi.Bbs.Vue3/src/utils/noticeSignalR.js b/Yi.Bbs.Vue3/src/utils/noticeSignalR.js deleted file mode 100644 index 8713ba65..00000000 --- a/Yi.Bbs.Vue3/src/utils/noticeSignalR.js +++ /dev/null @@ -1,107 +0,0 @@ -// 官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio -import * as signalR from "@microsoft/signalr"; - -export default { - // signalR对象 - SR: {}, - // 失败连接重试次数 - failNum: 4, - async init(url) { - const connection = new signalR.HubConnectionBuilder() - .withUrl(`${import.meta.env.VITE_APP_BASE_WS}/` + url) - .withAutomaticReconnect() //自动重新连接 - .configureLogging(signalR.LogLevel.Information) - .build(); - - - this.SR = connection; - // 断线重连 - connection.onclose(async () => { - console.log("断开连接了"); - console.assert( - connection.state === signalR.HubConnectionState.Disconnected - ); - // 建议用户重新刷新浏览器 - }); - - connection.onreconnected(() => { - console.log("断线重新连接成功"); - }); - this.receiveMsg(connection); - // 启动 - await this.start(); - }, - /** - * 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")}) - * @returns - */ - async close() { - try { - var that = this; - await this.SR.stop(); - this.SR = {}; - } catch { } - }, - - async start() { - var that = this; - - try { - //使用async和await 或 promise的then 和catch 处理来自服务端的异常 - await this.SR.start(); - //console.assert(this.SR.state === signalR.HubConnectionState.Connected); - //console.log('signalR 连接成功了', this.SR.state); - return true; - } catch (error) { - that.failNum--; - //console.log(`失败重试剩余次数${that.failNum}`, error) - if (that.failNum > 0) { - setTimeout(async () => { - await this.SR.start(); - }, 5000); - } - return false; - } - }, - // 接收消息处理 - receiveMsg(connection) { - connection.on("receiveNotice", (type, title, content) => { - - switch (type) { - case "MerryGoRound": - ElNotification({ - title: title, - dangerouslyUseHTMLString: true, - message: content, - }) - break; - case "Popup": - ElNotification({ - title: title, - dangerouslyUseHTMLString: true, - message: content, - }) - break; - } - }); - - // connection.on("onlineNum", (data) => { - // store.dispatch("socket/changeOnlineNum", data); - // }); - // // 接收欢迎语 - // connection.on("welcome", (data) => { - // console.log('welcome', data) - // Notification.info(data) - // }); - // // 接收后台手动推送消息 - // connection.on("receiveNotice", (title, data) => { - // Notification({ - // type: 'info', - // title: title, - // message: data, - // dangerouslyUseHTMLString: true, - // duration: 0 - // }) - // }) - }, -}; diff --git a/Yi.Bbs.Vue3/src/utils/signalR.js b/Yi.Bbs.Vue3/src/utils/signalR.js index 27ee72ee..3c7eb6a3 100644 --- a/Yi.Bbs.Vue3/src/utils/signalR.js +++ b/Yi.Bbs.Vue3/src/utils/signalR.js @@ -1,16 +1,11 @@ // 官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio import * as signalR from "@microsoft/signalr"; -import useSocketStore from "@/stores/socket"; import useAuths from "@/hooks/useAuths"; -import useUserStore from "@/stores/user"; const { getToken } = useAuths(); export default { - // signalR对象 SR: {}, - // 失败连接重试次数 - failNum: 4, - async init(url) { + start(url,callFunc) { const connection = new signalR.HubConnectionBuilder() .withUrl(`${import.meta.env.VITE_APP_BASE_WS}/` + url, { headers: { @@ -22,97 +17,28 @@ export default { }, }) - .withAutomaticReconnect() //自动重新连接 - .configureLogging(signalR.LogLevel.Information) + .withAutomaticReconnect(new ForeverRetryPolicy()) //自动重新连接 + .configureLogging(signalR.LogLevel.Error) .build(); - - this.SR = connection; // 断线重连 - connection.onclose(async () => { - console.log("断开连接了"); - console.assert( - connection.state === signalR.HubConnectionState.Disconnected - ); - // 建议用户重新刷新浏览器 + connection.onclose(() => { + console.log("hub断开"); }); connection.onreconnected(() => { - console.log("断线重新连接成功"); + console.log("hub重新连接成功"); }); - this.receiveMsg(connection); + callFunc(connection); // 启动 - await this.start(); - }, - /** - * 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")}) - * @returns - */ - async close() { - try { - var that = this; - await this.SR.stop(); - this.SR={}; - } catch {} + + this.SR.start(); }, - async start() { - var that = this; - - try { - //使用async和await 或 promise的then 和catch 处理来自服务端的异常 - await this.SR.start(); - //console.assert(this.SR.state === signalR.HubConnectionState.Connected); - //console.log('signalR 连接成功了', this.SR.state); - return true; - } catch (error) { - that.failNum--; - //console.log(`失败重试剩余次数${that.failNum}`, error) - if (that.failNum > 0) { - setTimeout(async () => { - await this.SR.start(); - }, 5000); - } - return false; - } - }, - // 接收消息处理 - receiveMsg(connection) { - connection.on("onlineNum", (data) => { - const socketStore = useSocketStore(); - socketStore.setOnlineNum(data); - }); - connection.on("forceOut", (msg) => { - useUserStore() - .logOut() - .then(() => { - alert(msg); - location.href = "/index"; - }); - }); - // connection.on("onlineNum", (data) => { - // store.dispatch("socket/changeOnlineNum", data); - // }); - // // 接收欢迎语 - // connection.on("welcome", (data) => { - // console.log('welcome', data) - // Notification.info(data) - // }); - // // 接收后台手动推送消息 - // connection.on("receiveNotice", (title, data) => { - // Notification({ - // type: 'info', - // title: title, - // message: data, - // dangerouslyUseHTMLString: true, - // duration: 0 - // }) - // }) - // // 接收系统通知/公告 - // connection.on("moreNotice", (data) => { - // if (data.code == 200) { - // store.dispatch("socket/getNoticeList", data.data); - // } - // }) - }, }; +class ForeverRetryPolicy { + nextRetryDelayInMilliseconds(retryContext) { + return 1000*3; + } + +} \ No newline at end of file