张建平 发表于 2023-9-13 12:45:01

钉钉旧版服务端SDK支持异步方法的升级改造

最近项目中需要对接钉钉,有些钉钉 API 的访问需要使用旧版服务端 SDK 才能搞定,但是这个 SDK 使用的还是 .NET Framework 2.0 框架,不能跨平台部署,也不支持 async\await 的异步操作方法,Nuget 上也有其它用户改造的 .NET Core 版本,但是都不支持异步方法,于是就想自己改造一下,经过若干小时的改造,最终发现完全可行,这篇文章就把改造的结果分享给大家。
主要包括两项改造:调整框架为 .netstandard 2.0;支持异步的Get/Post方法。
代码已经上传到了公共仓库,需要的请自取。
https://github.com/bosima/TopSdk
https://gitee.com/bosima/TopSdk
安装方法

两种方法:

[*]直接下载源代码,然后编译安装。
[*]通过 Nuget 公共仓库安装:FireflySoft.TopSdk
使用方法

所有业务类的定义都没有改变,而且原来的同步方法可以继续使用。
这里重点看下异步方法的使用,只需要替换几个名字:

[*]IDingTalkClient 替换为 IAsyncDingTalkClient。
[*]DefaultDingTalkClient 替换为 AsyncDefaultDingTalkClient 。
[*]Execute 替换为 ExecuteAsync。
下面是代码示例:
IAsyncDingTalkClient client = new AsyncDefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
OapiUserGetRequest req = new OapiUserGetRequest();
req.Userid = "userid1";
req.SetHttpMethod("GET");
OapiUserGetResponse rsp = await client.ExecuteAsync(req, accessToken)相关改造

给大家分享下具体怎么做的。
修改框架

修改框架为 .netstandard 2.0 ,这个网上有很多介绍,基本上没有什么难度。
我用了一个 Visual Studio  的插件升级的,有兴趣的可以看看:.NET Upgrade Assistant – Visual Studio Marketplace
支持异步

这个部分比较麻烦一些,因为要支持 async/await 的编写方式。
SDK原来的网络请求都是通过 HttpWebRequest 实现的,这个类十分基础,虽然也支持异步,但还是比较老旧的异步回调方式。所以我使用了 HttpClient这个新的 HTTP 操作类来替换它。
原来的 HTTP 操作都封装在 Util/WebUtils.cs 这个文件中,我模仿这个类创建了一个新的  Util/AsyncWebUtils.cs 。相关的属性和公开方法都保留了下来,只是方法改成了异步方法,方法名后边都加上了 Async。
这里有一点很重要的问题:HttpClient 存在DNS缓存的问题,也就是使用它访问某个域名的时候,它会把这个域名对应的IP缓存下来,默认情况下永远不更新,如果网站更换了DNS解析,原来的IP可能就访问不了了。
为了解决这个问题,微软官方在 HttpHandler 中新增了一个属性设置 PooledConnectionLifetime,它的本来意思是设置连接池中连接的生命周期,然后通过它也可以解决DNS缓存的问题,因为重新连接就要重新解析域名,就可以缓解上面这个问题。
同时为了兼容原来的一些网络超时和代理的设置,我这里选择的 HttpHandler 是 SocketsHttpHandler。但是但是又有新的问题了,.netstandard 2.0 不支持 SocketsHttpHandler,这个要到 .NET Core 2.1才支持。不过也有解决办法,有开发者将这个类单独提了出来:https://github.com/TalAloni/StandardSocketsHttpHandler
到这里 HTTP 的基本异步操作问题就都解决了,看看  HttpClient 的初始化方法,这里用了一个双检索来实现单例,因为 HttpClient 内部会创建一个连接池,所以我们没必要每次new一个,每次new还会导致底层网络端口释放不及时的问题。
private HttpClient GetHttpClient()
{
        if (_httpClient == null)
        {
                lock (_lock)
                {
                        if (_httpClient == null)
                        {
                                // https://github.com/TalAloni/StandardSocketsHttpHandler
                                var handler = new StandardSocketsHttpHandler
                                {
                                        PooledConnectionLifetime = TimeSpan.FromMinutes(3), // Recreate every 3 minutes
                                        ConnectTimeout = TimeSpan.FromMilliseconds(_timeout),
                                        ResponseDrainTimeout = TimeSpan.FromMilliseconds(_readWriteTimeout),
                                        UseProxy = _disableWebProxy,
                                };

                                if (this._ignoreSSLCheck)
                                {
                                        handler.SslOptions.RemoteCertificateValidationCallback = new RemoteCertificateValidationCallback(TrustAllValidationCallback);
                                }

                                _httpClient = new HttpClient(handler);
                        }
                }
        }

        return _httpClient;
}其它就是异步Get、Post的实现,Post的实现又需要实现Json请求和上传文件的处理,最后是返回值的解码处理,这些比较繁琐,但是没什么大问题,大家有兴趣的看代码就可以了。
注意

1、源代码是从钉钉开放平台页面公开下载的(点此前往),其中没有 License 文件,但是从公开下载的行为看,应该是允许修改的,且本人也没有售卖此代码。如有侵权,请联系删除此仓库。
2、虽然本人使用正常,但未做全面测试,正式使用前请谨慎测试评估,因使用此仓库代码造成的损失,本人概不负责。
                                                                                                                                                本文作者:                                                萤火架构                                       
                                                                                        本文链接:                                                https://www.cnblogs.com/bossma/p/17698430.html                                       
                                                                                        关于博主:                                                使用微信扫描左侧二维码关注我的订阅号,每天获取新知识                                       
                                                                                        版权声明:                                                本博客所有文章除特别声明外,均采用                                                BY-NC-SA                                                许可协议。转载请注明出处!                                       
                               
来源:https://www.cnblogs.com/bossma/archive/2023/09/13/17698430.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 钉钉旧版服务端SDK支持异步方法的升级改造