钉钉旧版服务端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、虽然本人使用正常,但未做全面测试,正式使用前请谨慎测试评估,因使用此仓库代码造成的损失,本人概不负责。
钉钉旧版服务端SDK支持异步方法的升级改造的更多相关文章
- 如何让服务端同时支持WebSocket和SSL加密的WebSocket(即同时支持ws和wss)?
自从HTML5出来以后,使用WebSocket通信就变得火热起来,基于WebSocket开发的手机APP和手机游戏也越来越多.我的一些开发APP的朋友,开始使用WebSocket通信,后来觉得通信不够 ...
- 信鸽推送 .NET (C#) 服务端 SDK rest api 调用库(v1.2)
信鸽推送 .NET 服务端 SDK rest api 调用库-介绍 该版本是基于信鸽推送v2版本的时候封装的,先拿出来与大家分享,封装还还凑合,不依赖其他http调用件,唯一依赖json序列化dll ...
- Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
http://blog.csdn.net/janeky/article/details/17151465 开发一款网络游戏,首先要考虑的是客户端服务端之间用何种编码格式进行通信.之前我们介绍了Unit ...
- 谈谈游戏服务端SDK接入
“接sdk其实本质上就是一个对着接口文档写adaptor的工作,重复和无味.” 团队减员,身负多职,上一次调SDK已经可以回溯到游戏测试前夕了... 一般SDK只包含验证和支付功能,绝少部分SDK包含 ...
- MySQL 8 服务端帮助支持
MySQL 服务器支持 HELP 语句,该语句返回参考手册中相应信息,比如: mysql> help change master to; 返回创建主从复制相关语句的信息 参考手册的信息存储在my ...
- 友盟推送 .NET (C#) 服务端 SDK rest api 调用库
友盟推送 .NET SDK rest api 介绍 该版本是基于友盟推送2.3版本封装的,网上查询了下发现没有.NET版本的调用库,官方也没有封装.NET的版本,只有python.java.php版本 ...
- Android Studio旧版(内含SDK)安装和环境变量配置 转自I-T枭
win10下Android Studio和SDK下载.安装和环境变量配置 ------made by siwuxie095 转自I-T枭https://me.csdn.net/hahahhahahah ...
- Laravel框架使用融云服务端SDK
方法一: 使用第三方依赖安装(在项目根目录) 第一步:安装 composer require latrell/rongcloud dev-master 第二步:更新依赖包 c ...
- 开启mode="history"模式,需要服务端的支持,因为出现“刷新页面报错404”的问题;
mode="history"是去除链接中的'#'的,但是加上后页面刷新回报404错误,怎么办呢? 解决办法:只需要在nginx中最末尾加上 try_files $uri $uri/ ...
- DSAPI多功能组件编程应用-HTTP监听服务端与客户端_指令版
前面介绍了DSAPI多功能组件编程应用-HTTP监听服务端与客户端的内容,这里介绍一个适用于更高效更快速的基于HTTP监听的服务端.客户端. 在本篇,你将见到前所未有的超简化超傻瓜式的HTTP监听服务 ...
随机推荐
- 「高频面试题」Redis的持久化方式有哪些?
RDB RDB(Redis DataBase)持久化是把当前Redis中全部数据生成快照保存在硬盘上.RDB持久化可以手动触发,也可以自动触发.save和bgsave命令都可以手动触发RDB持久化.除 ...
- C++面试八股文:C++中,函数的参数应该传值还是传引用?
某日二师兄参加XXX科技公司的C++工程师开发岗位第8面: 面试官:C++中,函数的参数应该传值还是传引用? 二师兄:要看参数的用途.如果是出参,必须传引用.如果是入参,主要考虑参数类型的大小,来决定 ...
- 无限分解流----Fork/Join框架
Fork译为拆分,Join译为合并Fork/Join框架的思路是把一个非常巨大的任务,拆分成若然的小任务,再由小任务继续拆解.直至达到一个相对合理的任务粒度.然后执行获得结果,然后将这些小任务的结果汇 ...
- 【城南】如何识别AI生成图?视觉AIGC伪造检测技术综述
如何识别 AI 生成图片?or 如何识别 AIGC 图?or 如何识别 AI 换脸?or AI生成图伪造检测? 类似的说法有很多种,总之就是利用AI技术来鉴别一张图是不是AI生成的,这种AI技术就是本 ...
- 【后端面经-Java】Java创建线程的方法简介
目录 1. 线程的基本概念 1.1 线程 1.2 线程状态和生命周期 2. 创建线程的四种方法 2.1 继承Thread类 2.2 实现Runnable接口 2.3 实现Callable接口 2.4 ...
- hashtable分析
1.什么是Hash表? Hash表又被称为散列表,是根据关键码值(key-value)也就是键值对来直接访问的一种数据结构.也就是说,它通过把关键码值映射到表中的一个位置来访问记录,用以加快查找的 ...
- PostgreSQL 12 文档: 部分 III. 服务器管理
部分 III. 服务器管理 这部份覆盖了PostgreSQL数据库管理员感兴趣的主题.包括软件安装.搭建和配置一个服务器.管理用户和数据库以及维护任务.任何想要运行一个PostgreSQL服务器的人( ...
- SQL 查询 总结 【行子查询 ; 列子查询 ; 表子查询 ; 自链接 ; 内连接 ;外连接 ; 无规则链接 ……】
简单介绍一下连接方式: 1.1.使用无连接规则连接两表 无限规则 也就简单的 select * from tableA , tableB 即得到一个笛卡尔积. 什么是 笛卡尔积 在 我的 另外 ...
- Hexo博客Yilia主题添加相册功能,丰富博客内容,Next等其他主题可以参考
实现思路 1.在主页上必须有一个可供点击的相册连接 2.要用 hexo 生成一个photos.html文件 3.photos.html中的图片数据来源?因为这是一个静态页面所有要有一个 json文件 ...
- Starting Tomcat v8.0 Server at localhost has encountered a problem.
现有Tomcat文件夹配置有问题,安装新的tomcat从新启动就好了