钉钉旧版服务端SDK支持异步方法的升级改造
最近项目中需要对接钉钉,有些钉钉 API 的访问需要使用旧版服务端 SDK 才能搞定,但是这个 SDK 使用的还是 .NET Framework 2.0 框架,不能跨平台部署,也不支持 async\await 的异步操作方法,Nuget 上也有其它用户改造的 .NET Core 版本,但是都不支持异步方法,于是就想自己改造一下,经过若干小时的改造,最终发现完全可行,这篇文章就把改造的结果分享给大家。
主要包括两项改造:调整框架为 .netstandard 2.0;支持异步的Get/Post方法。
代码已经上传到了公共仓库,需要的请自取。
GitHub - bosima/TopSdk: 钉钉旧版服务端SDK改造版:项目框架调整为 .netstandard 2.0;增加异步请求接口。
TopSdk: 钉钉旧版服务端SDK改造版:项目框架调整为 .netstandard 2.0;增加异步请求接口。
安装方法
两种方法:
- 直接下载源代码,然后编译安装。
- 通过 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才支持。不过也有解决办法,有开发者将这个类单独提了出来:GitHub - TalAloni/StandardSocketsHttpHandler: StandardSocketsHttpHandler is a backport of SocketsHttpHandler to .NET Standard 2.0
到这里 HTTP 的基本异步操作问题就都解决了,看看 HttpClient 的初始化方法,这里用了一个双检索来实现单例,因为 HttpClient 内部会创建一个连接池,所以我们没必要每次new一个,每次new还会导致底层网络端口释放不及时的问题。
private HttpClient GetHttpClient()
{if (_httpClient == null){lock (_lock){if (_httpClient == null){// https://github.com/TalAloni/StandardSocketsHttpHandlervar handler = new StandardSocketsHttpHandler{PooledConnectionLifetime = TimeSpan.FromMinutes(3), // Recreate every 3 minutesConnectTimeout = 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支持异步方法的升级改造
最近项目中需要对接钉钉,有些钉钉 API 的访问需要使用旧版服务端 SDK 才能搞定,但是这个 SDK 使用的还是 .NET Framework 2.0 框架,不能跨平台部署,也不支持 async\await 的异步操作方法,Nuget 上也有其它用户改造的 .…...
【C语言】【数据存储】用%d打印char类型数据,猜结果是啥
题目代码如下: #include <stdio.h> int main() {char a -1;signed char b-1;unsigned char c-1;printf("a%d,b%d,c%d",a,b,c);return 0; }解题关键: 1.二进制存储:原码,反码,补码 互换 2.截断 3.整型…...
算法——双指针
1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode) 这道题的重点是,如何用最小的操作数,来使其x变为0——也可以看作是用最少的数据个数,来求和得到x。 ——但是我们可以知道,由于数据是从两端向中间取的…...
【PowerQuery】Excel的PowerQuery按需刷新
将数据通过PowerQuery 导入进来后,这里将进行数据分组运算,最终的数据计算结果将保存在Excel 表格中,图为销售统计结果。 在Excel中,如果我们希望进行销售统计的手动更新可以使用几种不同的方法来进行刷新: 刷新单一数据连接如果仅仅需要刷新单一数据连接的话我们可以通过…...
Django REST Farmowork初探
1.简介 Django REST framework (简称:DRF)是一个强大而灵活的 Web API 工具。 遵循RESTFullAPI风格,功能完善,可快速开发API平台。 官网文档:https://www.django-rest-framework.org 2. framwork的安装 …...
【flink进阶】-- Flink kubernetes operator 版本升级
目录 1、检查当前 flink kubernetes operator 版本 2、停止生产上正在运行的 flink job 3、升级 CRD...
Linux Ubuntu20.04深度学习环境快速配置命令记录
一、驱动安装 1、更新系统包 sudo apt-get updatesudo apt-get upgrade 2、安装显卡驱动 使用apt方式安装驱动,多数情况不容易成功, 使用一下方法更佳: 1.查看合适显卡的驱动版本 ubuntu-drivers devices NVIDIA GeForce 驱动程序 - …...
信息安全三级真题一
目录 一、单选题 二、填空题 三、综合题 一、单选题 二、填空题 三、综合题 知法懂法,请各位网络安全从业者遵守《网络安全法》、《个人信息保护法》 业%$务*$&联&#系 XHU3ZjUxXHU3ZWRjXHU4ZmQwXHU3ZWY0XHU2ZTE3XHU5MDBmXHU1NmUyXHU5NjFmXHUyMDBiXHU2M…...
RK3568-tftp更新设备树和内核nfs挂载文件系统
1. 注意:需要设备树和内核按以下修改才能支持tftp和nfs。 1.1 修改设备树: diff --git a/arch/arm64/boot/dts/rockchip/OK3568-C-linux.dts b/arch/arm64/boot/dts/rockchip/OK3568-C-linux.dts index 178b4d831..34cb57ffd 100644 --- a/arch/arm64/boot/dts/rockchip/OK…...
FIR滤波器简述及FPGA仿真验证
数字滤波器的设计,本项目做的数字滤波器准确来说是FIR滤波器。 FIR滤波器(有限冲激响应滤波器),与另一种基本类型的数字滤波器——IIR滤波器(无限冲击响应滤波器)相对应,其实就是将所输入的信号…...
高速信号处理板资料保存:383-基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡设计原理图
基于kintex UltraScale XCKU060的双路QSFP光纤PCIe 卡 一、板卡概述 本板卡系我司自主研发,基于Xilinx UltraScale Kintex系列FPGA XCKU060-FFVA1156-2-I架构,支持PCIE Gen3 x8模式的高速信号处理板卡,搭配两路40G QSFP接口…...
QT:使用分组框、单选按钮、普通按钮、标签、行编辑器、垂直分布、水平分布做一个小项目
widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QRadioButton> //单选按钮 #include <QGroupBox> //分组框 #include <QHBoxLayout> //水平布局 #include <QVBoxLayout> //垂直布局 #include <QPushButton>…...
封装微信小程序隐私信息授权
隐私 代码 html (modal 组件再后面封装有提供) <modal isShow"{{show}}"><view class"privacy-auth-dialog"><view class"title">温馨提示</view><view class"content"><vi…...
【C#】FileInfo类 对文件进行操作
提示:使用FileInfo类时,要引用System.IO命名空间。 using System.IO; FileInfo类 生成文件删除文件移动文件复制文件获取文件名判断文件是否存在属性列表其它常用方法 生成文件 Create():在指定路径上创建文件。 FileInfo myFile new FileIn…...
python中的字符串也是可迭代对象吗?
python中的字符串也是可迭代对象吗? ━━━━━━━━━━━━━━━━━━━━━━ 是的,Python中的字符串是可迭代对象。这意味着你可以像处理列表或元组那样处理字符串。例如,你可以使用for循环遍历字符串中的每个字符,或…...
C++ 图像线特征提取【HoughLinesP算法】
目录 一、函数介绍二、实现步骤三、代码示例一、函数介绍 HoughLinesP:是一种基于Hough变换的直线检测算法。它可以识别图像中的直线,并返回它们的端点坐标。其函数接口如下: cv::HoughLinesP( InputArray src, // 输入图像,必须 8-bit 的灰度图像 OutputArray…...
Stable Diffusion WebUI内存不够爆CUDA Out of memory怎么办?
在我们运行SD的时候,我们经常会爆CUDA Out of memory。 我们应该怎么办呢? 这是因为我们的显存或者内存不够了。 如果你是用cpu来跑图的则表示内存不够,这个时候就需要换个大点的内存了。 如果你是用gpu来跑图的就说明你显存不够用咯,这时候咋办呢? 下面我将一一述说…...
模板学堂|数据可视化仪表板大屏设计流程梳理
DataEase开源数据可视化分析平台于2022年6月正式发布模板市场(https://dataease.io/templates/)。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板,方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&a…...
基于Xml方式Bean的配置-Bean的延时加载
SpringBean的配置详解 Bean的延时加载 当lazy-init设置为true时为延时加载,也就是当Spring容器创建的时候,不会立即创建Bean实例,等待用到时再创建Bean实例并储存到单例池中,后续使用该Bean时直接从单例池中获取即可,…...
python之pyQt5实例:Matplotlib的应用
1、显示逻辑 1.1MatplotlibWidget.py import sys import random import matplotlibmatplotlib.use("Qt5Agg") from PyQt5 import QtCore from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QSizePolicy, QWidget from numpy import arange, si…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
