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

namespace Dpz.Core.Web.Library.Hub;

public class RobotChatHub(
    ILogger<RobotChatHub> logger,
    IChatRecordService chatRecordService,
    IConfiguration configuration,
    XunFeiService xunFeiService,
    AnalyzeService analyzeService
) : Microsoft.AspNetCore.SignalR.Hub
{
    public async Task SendMessage(string question)
    {
        var sessionId = Guid.NewGuid().ToString("N");

        var httpContext = Context.GetHttpContext();
        var userId =
            Context.User?.IsLogin() == true
                ? Context.User.GetIdentity()?.Id
                : httpContext?.Request.Cookies[Program.AuthorizeCookieName + ".SessionId"];
        if (!string.IsNullOrEmpty(userId))
        {
            sessionId = userId;
        }

        var request = await GetXunFeiRequestAsync(sessionId, question, Context.User);
        ResponseResult<List<XunFeiResponse?>> responseResult;
        try
        {
            responseResult = await xunFeiService.ChatAsync(request);
            if (!responseResult.Success)
            {
                await Clients.Caller.SendCoreAsync(
                    "SystemError",
                    [XunFeiReceiverUser(ErrorMessage(responseResult.Message))]
                );
                return;
            }
        }
        catch (Exception ex)
        {
            await Clients.Caller.SendCoreAsync(
                "SystemError",
                [XunFeiReceiverUser(ErrorMessage(ex.Message))]
            );
            logger.LogError(ex, "API调用出错");
            return;
        }

        var message = "";
        if (responseResult.Data != null)
        {
            var messageSb = new StringBuilder();
            responseResult.Data.ForEach(x =>
                messageSb.Append(x?.Payload?.Choices?.Text?.FirstOrDefault()?.Content ?? "")
            );
            message = messageSb.ToString();
            await Clients.Caller.SendCoreAsync("Answer", [XunFeiReceiverUser(message)]);
        }

        if (Context.User.IsLogin())
        {
            var sender = Context.User?.GetIdentity();
            if (sender == null)
            {
                return;
            }

            var receiver = XunFeiUser();

            await chatRecordService.SaveFriendRecordAsync(sender, question, receiver);
            await chatRecordService.SaveRobotRecordAsync(receiver, message, message);
        }
    }

    public async Task SendMessageToChatGpt(string content)
    {
        if (string.IsNullOrWhiteSpace(content))
        {
            await Clients.Caller.SendCoreAsync("SystemError", [ChatGptReceiverUser("请输入内容")]);
            return;
        }

        if (!Context.User.IsLogin())
        {
            await Clients.Caller.SendCoreAsync("SystemError", [ChatGptReceiverUser("尚未登录")]);
            return;
        }

        try
        {
            var sender = Context.User?.GetIdentity() ?? throw new BusinessException("尚未登录");
            var receiver = ChatGptUser();

            await chatRecordService.SaveFriendRecordAsync(sender, content, receiver);

            var records = await chatRecordService.GetFriendRecordAsync(
                sender.Id,
                ApplicationTools.ChatGptUserId,
                1,
                4
            );
            var messages = records
                .OrderBy(x => x.SendTime)
                .Select(x => new ChatMessage
                {
                    Role = x.Sender?.Id == ApplicationTools.ChatGptUserId ? "assistant" : "user",
                    Message = x.Message,
                })
                .ToList();
            //messages.Add(new ChatMessage { Role = "user", Message = content });
            var result = await analyzeService.ChatAsync(messages);
            if (!result.Success)
            {
                await Clients.Caller.SendCoreAsync(
                    "SystemError",
                    [ChatGptReceiverUser(ErrorMessage(result.Message))]
                );
            }

            var sendAnswerContent = result.Data ?? "";
            await Clients.Caller.SendCoreAsync("Answer", [ChatGptReceiverUser(sendAnswerContent)]);

            await chatRecordService.SaveFriendRecordAsync(receiver, sendAnswerContent, sender);
        }
        catch (Exception e)
        {
            await Clients.Caller.SendCoreAsync(
                "SystemError",
                [ChatGptReceiverUser(ErrorMessage(e.Message))]
            );
        }
    }

    private async Task<XunFeiRequest> GetXunFeiRequestAsync(
        string uid,
        string question,
        ClaimsPrincipal? user
    )
    {
        var userInfo = user?.GetIdentity();
        IPagedList<VmChatRecord> chatRecords = PagedList<VmChatRecord>.Empty();
        if (userInfo != null)
        {
            chatRecords = await chatRecordService.GetFriendRecordAsync(
                userInfo.Id,
                XunFeiUserId,
                1,
                4
            );
        }

        var messages = chatRecords
            .OrderBy(x => x.SendTime)
            .Select(x => new XunFeiRequestText
            {
                Content = x.Message,
                Role = x.Sender?.Id == XunFeiUserId ? "assistant" : "user",
            })
            .ToList();
        messages.Add(new XunFeiRequestText { Content = question, Role = "user" });
        return new XunFeiRequest
        {
            Header = new XunFeiRequestHeader
            {
                AppId = configuration["XunFei:AppId"] ?? throw new Exception("AppId is null"),
                Uid = uid,
            },
            Parameter = new XunFeiRequestParameter { Chat = new XunFeiRequestChat() },
            Payload = new XunFeiRequestPayload
            {
                Message = new XunFeiRequestMessage { Text = messages },
            },
        };
    }

    private object XunFeiReceiverUser(string message)
    {
        return new
        {
            id = "kefu",
            avatar = $"{configuration["CDNBaseAddress"]}/images/ai.jpg",
            username = "星火认知大模型",
            type = "friend",
            content = message,
            mine = false,
        };
    }

    private object ChatGptReceiverUser(string message)
    {
        return new
        {
            id = ApplicationTools.ChatGptUserId,
            avatar = $"{configuration["CDNBaseAddress"]}/images/ChatGPT.ico",
            username = "ChatGPT",
            type = "friend",
            content = message,
            mine = false,
        };
    }

    private static string XunFeiUserId => "kefu";

    private VmUserInfo XunFeiUser()
    {
        return new VmUserInfo
        {
            Avatar = $"{configuration["CDNBaseAddress"]}/images/ai.jpg",
            Enable = true,
            Id = XunFeiUserId,
            Key = "",
            LastAccessTime = DateTime.Now,
            Name = "星火认知大模型",
            Permissions = null,
        };
    }

    private VmUserInfo ChatGptUser()
    {
        return new VmUserInfo
        {
            Avatar = $"{configuration["CDNBaseAddress"]}/images/ChatGPT.ico",
            Enable = true,
            Id = ApplicationTools.ChatGptUserId,
            Key = "",
            LastAccessTime = DateTime.Now,
            Name = "ChatGPT",
            Permissions = null,
        };
    }

    private static string ErrorMessage(string? message)
    {
        return $"调用API出错,错误信息:<span style='color:red;'>{(message ?? "Call API fail")}</span>";
    }

    public override Task OnConnectedAsync()
    {
        var sessionId = Context
            .GetHttpContext()
            ?.Request.Cookies[Program.AuthorizeCookieName + ".SessionId"];
        Clients.Caller.SendCoreAsync("Connected", ["websocket connected.", sessionId]);
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception? exception)
    {
        var sessionId = Context
            .GetHttpContext()
            ?.Request.Cookies[Program.AuthorizeCookieName + ".SessionId"];
        Clients.Caller.SendCoreAsync("Disconnected", ["websocket disconnected.", sessionId]);
        if (exception != null)
        {
            logger.LogError(exception, "signalR disconnected");
        }

        return base.OnDisconnectedAsync(exception);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码定义了一个 SignalR Hub 类 RobotChatHub,用于处理与聊天机器人(如讯飞和 ChatGPT)之间的实时消息交互。以下是代码的主要功能和结构的详细解释:

1. 类的构造函数

RobotChatHub 类的构造函数接受多个依赖项,包括日志记录器、聊天记录服务、配置、讯飞服务和分析服务。这些依赖项用于处理聊天请求、记录聊天记录和与外部服务交互。

2. 发送消息

SendMessage 方法

  • 功能:处理用户发送的消息,调用讯飞的聊天服务,并将响应返回给用户。
  • 流程
    • 生成一个会话 ID,优先使用用户的 ID。
    • 调用 GetXunFeiRequestAsync 方法构建请求。
    • 调用 xunFeiService.ChatAsync 方法与讯飞 API 交互。
    • 如果成功,提取响应内容并发送给用户;如果失败,发送错误信息。
    • 如果用户已登录,记录聊天记录。

SendMessageToChatGpt 方法

  • 功能:处理用户发送给 ChatGPT 的消息。
  • 流程
    • 检查内容是否为空和用户是否已登录。
    • 记录用户发送的消息。
    • 获取与 ChatGPT 的聊天记录,并构建消息列表。
    • 调用 analyzeService.ChatAsync 方法与 ChatGPT 交互。
    • 处理响应并将结果发送给用户;记录 ChatGPT 的响应。

3. 构建请求

GetXunFeiRequestAsync 方法

  • 功能:构建发送给讯飞 API 的请求对象。
  • 流程
    • 获取用户的聊天记录,并构建消息列表。
    • 将用户的问题添加到消息列表中。
    • 返回构建好的 XunFeiRequest 对象。

4. 用户信息和消息格式化

  • XunFeiReceiverUserChatGptReceiverUser 方法用于格式化发送给客户端的消息,包含用户的头像、用户名和消息内容。
  • XunFeiUserChatGptUser 方法返回代表讯飞和 ChatGPT 的用户信息对象。

5. 错误处理

  • ErrorMessage 方法用于格式化错误信息,以便在客户端显示。

6. 连接和断开连接

  • OnConnectedAsyncOnDisconnectedAsync 方法用于处理用户连接和断开连接事件,记录连接状态并向客户端发送相应的消息。

总结

RobotChatHub 类实现了一个实时聊天系统的核心功能,允许用户与讯飞和 ChatGPT 进行交互。它处理消息的发送和接收,记录聊天记录,并在出现错误时提供反馈。通过 SignalR,用户可以实时接收来自聊天机器人的响应。

loading