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

namespace Dpz.Core.Service.Network;

public class XunFeiService(IConfiguration configuration, ILogger<XunFeiService> logger)
{
    private readonly string _host = "spark-api.xf-yun.com";

    private readonly string _path = "/v3.5/chat";

    private readonly string _date = DateTime.UtcNow.ToString("R");

    private readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    };

    public async Task<List<XunFeiResponse?>> ChatAsync(XunFeiRequest request)
    {
        var authorization = GetAuthorization();
        var serverUri = new Uri(
            $"wss://{_host}{_path}?authorization={Uri.EscapeDataString(authorization)}&date={Uri.EscapeDataString(_date)}&host={_host}"
        );
        using var ws = new ClientWebSocket();
        var source = new CancellationTokenSource();
        //source.CancelAfter(5000);

        try
        {
            await ws.ConnectAsync(serverUri, source.Token);
            logger.LogInformation("websocket {@ServerUri} connected", serverUri);
        }
        catch (Exception e)
        {
            logger.LogError(e, "connection fail");
            return [];
        }

        var requestMessage = JsonSerializer.Serialize(request, _jsonSerializerOptions);

        const int retry = 5;
        return await ApplicationTools.RetryAsync(
            async () => await CommunicationAsync(),
            TimeSpan.FromSeconds(1),
            retry
        );

        async Task<List<XunFeiResponse?>> CommunicationAsync()
        {
            List<XunFeiResponse?> list = [];
            try
            {
                if (ws.State != WebSocketState.Open)
                {
                    throw new BusinessException($"websocket state {ws.State}");
                }

                var bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(requestMessage));
                await ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, source.Token);
                var receiveBuffer = new byte[1 << 10];
                var result = await ws.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), source.Token);
                
                while (!result.CloseStatus.HasValue)
                {
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        var receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);
                        var response = JsonSerializer.Deserialize<XunFeiResponse>(receivedMessage, _jsonSerializerOptions);
                        if (response == null)
                        {
                            logger.LogWarning(
                                "response is null,response message:{Message}",
                                receivedMessage
                            );
                        }
                        
                        if (response != null && response.Header?.Code != 0)
                        {
                            logger.LogWarning("response code is error,response :{Response}", response);
                        }

                        list.Add(response);
                    }
                    else if (result.MessageType == WebSocketMessageType.Close)
                    {
                        logger.LogInformation("websocket {@ServerUri} disconnect", serverUri);
                        break;
                    }

                    result = await ws.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), source.Token);
                }
                
            }
            catch (Exception e)
            {
                logger.LogInformation(e, "communication fail");
            }
            
            return list;
        }
    }

    private string GetAuthorization()
    {
        var apiKey =
            configuration["XunFei:ApiKey"] ?? throw new Exception("XunFei:ApiKey is null or empty");
        var apiSecret =
            configuration["XunFei:ApiSecret"]
            ?? throw new Exception("XunFei:ApiSecret is null or empty");

        var parameters = new List<string>
        {
            $"host: {_host}",
            $"date: {_date}",
            $"GET {_path} HTTP/1.1",
        };
        var buffer = Encoding.UTF8.GetBytes(string.Join("\n", parameters));
        var hashBytes = HMACSHA256.HashData(Encoding.UTF8.GetBytes(apiSecret), buffer);
        var signature = Convert.ToBase64String(hashBytes);
        var authorizationOrigin =
            $"api_key=\"{apiKey}\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"{signature}\"";
        var authorizationOriginBytes = Encoding.UTF8.GetBytes(authorizationOrigin);
        return Convert.ToBase64String(authorizationOriginBytes);
    }
}
loading