网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using Dpz.Core.Web.Library.Api;
using Dpz.Core.Web.Models;
using Microsoft.AspNetCore.Authorization;

namespace Dpz.Core.Web.Library.Hub;

public class ChatHub(
    IChatRecordService chatRecordService,
    IAccountService accountService,
    IChatCurrentUserService chatCurrentUserService
) : Microsoft.AspNetCore.SignalR.Hub
{
    [Authorize]
    public async Task SendMessageToUser(string user, string message)
    {
        if (Context.User == null)
        {
            return;
        }
        var sender = Context.User.GetIdentity();
        if (sender == null)
        {
            return;
        }
        await Clients
            .User(user)
            .SendCoreAsync(
                "ReceiveMessage",
                [ReceiveContent.ToReceiveContent(sender, message)]
            );

        #region save record

        var receiver = await accountService.GetOneUserAsync(user);
        await chatRecordService.SaveFriendRecordAsync(sender, message, receiver);
        #endregion
    }

    [Authorize]
    public async Task SendMessageToGroup(string groupId, string message)
    {
        if (Context.User == null)
        {
            return;
        }
        var sender = Context.User.GetIdentity();
        if (sender == null)
        {
            return;
        }
        var userInfo = Context.User.GetStrictIdentity();
        List<VmUserInfo> users;
        if (groupId == WebToolsExtensions.DefaultGroupId)
        {
            var list = await accountService.GetPageAsync(1, 100, userInfo.Id);
            users = [..list];
        }
        else
        {
            users = new List<VmUserInfo>();
        }
        await Clients
            .Users(users.Select(x => x.Id).ToList())
            .SendCoreAsync(
                "ReceiveMessage",
                [ReceiveContent.ToGroupContent(groupId, userInfo, message)]
            );

        #region save record

        await chatRecordService.SaveGroupRecordAsync(sender, groupId, message);
        #endregion
    }

    public override async Task OnConnectedAsync()
    {
        if (Context.User == null || !Context.User.IsLogin())
        {
            await Clients.Caller.SendCoreAsync(
                "System",
                [
                    new
                    {
                        code = -1,
                        system = true,
                        id = "00000",
                        content = "没有登录"
                    }
                ]
            );
            return;
        }

        var currentUser = Context.User.GetIdentity();
        if (currentUser == null)
        {
            return;
        }
        await chatCurrentUserService.AddAsync(Context.ConnectionId, currentUser);
        await Clients.Others.SendCoreAsync(
            "System",
            [
                new
                {
                    code = 1,
                    system = true,
                    isGuest = false,
                    user = currentUser
                }
            ]
        );
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        if (Context.User.IsLogin())
        {
            await chatCurrentUserService.RemoveAsync(Context.ConnectionId);
        }
        await Clients.Others.SendCoreAsync(
            "System",
            [
                new
                {
                    code = 0,
                    system = true,
                    isGuest = Context.User?.Identity?.IsAuthenticated != true,
                    user = Context.User?.Identity?.IsAuthenticated == true
                        ? Context.User.GetIdentity()
                        : null
                }
            ]
        );
        await base.OnDisconnectedAsync(exception);
    }
}

//public class DomainRestrictedRequirement :
//    AuthorizationHandler<DomainRestrictedRequirement, HubInvocationContext>,
//    IAuthorizationRequirement
//{
//    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
//        DomainRestrictedRequirement requirement,
//        HubInvocationContext resource)
//    {
//        if (IsUserAllowedToDoThis(resource.HubMethodName, context.User.Identity.Name) &&
//            context.User.Identity.Name.EndsWith("@microsoft.com"))
//        {
//            context.Succeed(requirement);
//        }
//        return Task.CompletedTask;
//    }

//    private bool IsUserAllowedToDoThis(string hubMethodName,
//        string currentUsername)
//    {
//        return !(currentUsername.Equals("asdf42@microsoft.com") &&
//                 hubMethodName.Equals("banUser", StringComparison.OrdinalIgnoreCase));
//    }
//}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码定义了一个 SignalR Hub 类 ChatHub,用于处理实时聊天功能。这个 Hub 允许用户之间发送消息,并管理用户的连接和断开连接事件。以下是代码的主要功能和结构的详细解释:

1. 类的构造函数

ChatHub 类的构造函数接受三个服务作为参数:

  • IChatRecordService:用于保存聊天记录。
  • IAccountService:用于获取用户信息。
  • IChatCurrentUserService:用于管理当前在线用户的信息。

2. 发送消息到用户

SendMessageToUser 方法允许已授权的用户向特定用户发送消息。其主要步骤包括:

  • 检查当前用户是否已登录。
  • 获取发送者的身份信息。
  • 使用 Clients.User(user) 将消息发送给指定的用户。
  • 保存聊天记录,调用 chatRecordService.SaveFriendRecordAsync 方法。

3. 发送消息到组

SendMessageToGroup 方法允许已授权的用户向特定组发送消息。其主要步骤包括:

  • 检查当前用户是否已登录。
  • 获取发送者的身份信息。
  • 根据 groupId 获取用户列表(如果是默认组,则获取当前用户的好友列表)。
  • 使用 Clients.Users(users.Select(x => x.Id).ToList()) 将消息发送给组内的所有用户。
  • 保存聊天记录,调用 chatRecordService.SaveGroupRecordAsync 方法。

4. 连接事件

OnConnectedAsync 方法在用户连接到 Hub 时被调用。其主要步骤包括:

  • 检查用户是否已登录,如果未登录,则向调用者发送系统消息,提示未登录。
  • 获取当前用户的身份信息,并将其添加到当前在线用户列表中。
  • 向其他用户发送系统消息,通知他们有新用户连接。

5. 断开连接事件

OnDisconnectedAsync 方法在用户断开连接时被调用。其主要步骤包括:

  • 如果用户已登录,则从当前在线用户列表中移除该用户。
  • 向其他用户发送系统消息,通知他们有用户断开连接。

6. 授权处理(注释部分)

注释部分包含一个 DomainRestrictedRequirement 类,用于处理特定的授权逻辑。它检查用户是否有权执行某个 Hub 方法,并且用户的电子邮件是否以 @microsoft.com 结尾。这个部分目前被注释掉,可能是为了将来使用或进行进一步的开发。

总结

整体而言,ChatHub 类实现了一个基本的实时聊天功能,支持用户之间的私信和群组消息发送,同时管理用户的连接状态和聊天记录。通过使用 SignalR,应用程序能够实现实时的双向通信。

loading