Skip to content

.NET Core 使用 WebApiClient 调用融云 IM API

🏷️ .NET Core WebApiClient

因项目需求,需要调用 融云 IM 即时通讯 的 API。

开发环境为 .NET Core 2.1,且仍然使用 WebApiClient 包。

具体的实现步骤如下:

1. 安装 WebApiClient

powershell
Install-Package WebApiClient.JIT -Version 1.0.6

2. 定义 HttpApi 和 对应的模型

这里以 消息历史记录下载地址获取 接口为例:

IRCMessageApi.cs

csharp
/// <summary>
/// 融云消息接口
/// </summary>
public interface IRCMessageApi : IHttpApi
{
    /// <summary>
    /// 消息历史记录下载地址获取
    /// </summary>
    /// <param name="parameter">表单参数</param>
    /// <returns>返回值</returns>
    [HttpPost("message/history.json")]
    ITask<MessageHistoryResult> MessageHistory([FormContent] MessageHistoryParameter parameter);
}

参数模型类: MessageHistoryParameter.cs

csharp
/// <summary>
/// 消息历史记录下载地址获取参数
/// </summary>
public class MessageHistoryParameter
{
    /// <summary>
    /// 国内数据中心为指定北京时间某天某小时,格式为 2014010101,表示获取 2014 年 1 月 1 日凌晨 1 点至 2 点的数据。如使用的是融云海外数据中心为 UTC 时间。(必传)
    /// </summary>
    public string Date { get; set; }
}

返回值模型类: MessageHistoryResult.cs

csharp
/// <summary>
/// 消息历史记录下载地址获取结果
/// </summary>
public class MessageHistoryResult
{
    /// <summary>
    /// 返回码,200 为正常。
    /// </summary>
    public int Code { get; set; }
    /// <summary>
    /// 历史记录下载地址,如没有消息记录数据时,则 url 值为空。
    /// </summary>
    public string Url{ get; set; }
    /// <summary>
    /// 历史记录时间
    /// </summary>
    public string Date { get; set; }
}

3. 创建注册用工厂类

RongCloudApiFactory.cs

csharp
/// <summary>
/// 融云 Api 工厂类
/// </summary>
public class RongCloudApiFactory
{
    /// <summary>
    /// 注册
    /// </summary>
    public static void Register()
    {
        // 消息接口
        HttpApi.Register<IRCMessageApi>()
            .ConfigureHttpApiConfig(c =>
            {
                c.HttpHost = new Uri("http://api-cn.ronghub.com/");
                c.FormatOptions = new FormatOptions() { UseCamelCase = true };
                c.GlobalFilters.Add(new RCSignFilter());
            });
    }
}

根据项目类型,在项目的启动过程中调用一次注册(Register)方法即可。

4. 通过 Filter 对请求签名

就是上面注册时添加的 RCSignFilter

其中 SHA1 加密使用的是 System.Security.Cryptography.SHA1 类。

csharp
/// <summary>
/// 融云签名过滤器
/// </summary>
class RCSignFilter : IApiActionFilter
{
    /// <summary>
    /// 请求前处理
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task OnBeginRequestAsync(ApiActionContext context)
    {
        var appKey = ZConfig.GetConfigString(CommonType.ApolloConfigKey.RONG_CLOUD_APP_KEY);
        var appSecret = ZConfig.GetConfigString(CommonType.ApolloConfigKey.RONG_CLOUD_APP_SECRET);

        var nonce = new Random().Next(int.MaxValue).ToString();
        var timeStamp = ConvertHelper.ConvertDateTimeInt(DateTime.Now).ToString();
        var sha1 = System.Security.Cryptography.SHA1.Create();
        var signature = BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(appSecret + nonce + timeStamp))).Replace("-", string.Empty).ToLower();

        context.RequestMessage.Headers.Add("App-Key", appKey);
        context.RequestMessage.Headers.Add("Nonce", nonce);
        context.RequestMessage.Headers.Add("Timestamp", timeStamp);
        context.RequestMessage.Headers.Add("Signature", signature);

        return Task.FromResult<object>(null);
    }

    /// <summary>
    /// 请求后处理
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task OnEndRequestAsync(ApiActionContext context)
    {
        return Task.FromResult<object>(null);
    }
}

5. 调用 HTTP Api

调用是异步的方式,示例代码如下:

csharp
var history = await HttpApi.Resolve<IRCMessageApi>().MessageHistory(new MessageHistoryParameter()
{
    Date = DateTime.Now.AddHours(-1).ToString("yyyyMMddHH"),
});

同步方法可以使用如下方式获取返回值:

csharp
var history = HttpApi.Resolve<IRCMessageApi>().MessageHistory(new MessageHistoryParameter()
{
    Date = DateTime.Now.AddHours(-1).ToString("yyyyMMddHH"),
}).GetAwaiter().GetResult();

附 1. 参考文档

  1. Computing SHA1 with ASP.NET Core
  2. byte[] to hex string