A versão antiga do SDK do servidor DingTalk suporta a atualização de métodos assíncronos.

Em projetos recentes, precisamos nos conectar ao DingTalk. O acesso a algumas APIs do DingTalk requer o uso da versão antiga do SDK do servidor. No entanto, este SDK ainda usa a estrutura .NET Framework 2.0, que não pode ser implantada em várias plataformas e não suporte ao método de operação assíncrona de async\await. , também existem versões do .NET Core modificadas por outros usuários no Nuget, mas nenhuma delas suporta métodos assíncronos, então eu queria modificá-lo sozinho. Após várias horas de modificação, finalmente encontrei que era totalmente viável. Este artigo compartilhará os resultados da modificação com todos.

Inclui principalmente duas modificações: ajuste da estrutura para .netstandard 2.0; suporte a métodos Get/Post assíncronos.

O código foi carregado no repositório público, pegue-o se precisar.

GitHub - bosima/TopSdk: Versão modificada do antigo SDK do servidor DingTalk: a estrutura do projeto é ajustada para .netstandard 2.0; uma interface de solicitação assíncrona é adicionada.

TopSdk: Uma versão modificada do antigo SDK do servidor DingTalk: a estrutura do projeto é ajustada para .netstandard 2.0; uma interface de solicitação assíncrona é adicionada.

método de instalação

Dois métodos:

  • Baixe o código-fonte diretamente, compile e instale.
  • Instale via repositório público Nuget: FireflySoft.TopSdk

Instruções

As definições de todas as classes de negócios não foram alteradas e os métodos de sincronização originais podem continuar a ser usados.

Aqui focamos no uso de métodos assíncronos, bastando substituir alguns nomes:

  • IDingTalkClient substituído por IAsyncDingTalkClient.
  • DefaultDingTalkClient é substituído por AsyncDefaultDingTalkClient.
  • Execute é substituído por ExecuteAsync.

Aqui está o exemplo de código:

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)

Transformação relacionada

Deixe-me compartilhar com você como fazer isso.

Modifique o quadro

Modifique a estrutura para .netstandard 2.0. Existem muitas introduções na Internet e basicamente não é difícil.

Usei um plug-in do Visual Studio para atualizar. Se você estiver interessado, pode conferir: .NET Upgrade Assistant – Visual Studio Marketplace

Suporte assíncrono

Esta parte é um pouco mais problemática porque precisa suportar o método de gravação async/await.

As solicitações de rede originais do SDK foram implementadas por meio de HttpWebRequest. Esta classe é muito básica. Embora também suporte assíncrono, ainda é um método de retorno de chamada assíncrono relativamente antigo. Então usei a nova classe de operação HTTP HttpClient para substituí-la.

As operações HTTP originais estão encapsuladas no arquivo Util/WebUtils.cs. Imitei essa classe e criei um novo Util/AsyncWebUtils.cs. Os atributos relevantes e os métodos públicos são mantidos, mas o método é alterado para um método assíncrono e Async é adicionado após o nome do método.

Há uma questão muito importante aqui: o HttpClient tem um problema de cache de DNS, ou seja, quando você o utiliza para acessar um determinado nome de domínio, ele irá armazenar em cache o IP correspondente ao nome de domínio e nunca atualizá-lo por padrão. Se o site mudar a resolução DNS, o IP original pode não estar acessível.

Para resolver este problema, a Microsoft adicionou oficialmente uma nova configuração de atributo PooledConnectionLifetime no HttpHandler.Seu significado original é definir o ciclo de vida da conexão no pool de conexões, e então também pode resolver o problema de cache DNS porque a reconexão requer reconexão. -parsing.O nome de domínio pode aliviar o problema acima.

Ao mesmo tempo, para ser compatível com algumas das configurações originais de tempo limite e proxy da rede, o HttpHandler que escolhi aqui é SocketsHttpHandler. Mas há um novo problema. O .netstandard 2.0 não oferece suporte a SocketsHttpHandler. Isso não será compatível até o .NET Core 2.1. No entanto, existe uma solução. Alguns desenvolvedores propuseram esta classe separadamente: GitHub - TalAloni/StandardSocketsHttpHandler: StandardSocketsHttpHandler é um backport de SocketsHttpHandler para .NET Standard 2.0

Neste ponto, os problemas básicos de operação assíncrona do HTTP foram resolvidos. Vamos dar uma olhada no método de inicialização do HttpClient. Uma recuperação dupla é usada para implementar um singleton. Como o HttpClient criará um pool de conexões internamente, não precisamos criar um novo a cada vez. Novos horários também causarão o problema de liberação prematura da porta de rede subjacente.

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;
}

Os outros são a implementação de Get e Post assíncronos. A implementação de Post requer o processamento de solicitações Json e arquivos carregados e, finalmente, a decodificação do valor de retorno. Estes são mais complicados, mas não há grande problema. Se você estiver interessado , basta olhar o código.

Perceber

1. O código-fonte é baixado publicamente da página da plataforma aberta DingTalk ( clique aqui para ir ) Não há arquivo de licença, mas a julgar pelo comportamento do download público, a modificação deve ser permitida e eu não vendi este código. Se houver alguma infração, entre em contato para excluir este armazém.

2. Embora eu o use normalmente, não fiz um teste abrangente. Por favor, teste e avalie cuidadosamente antes do uso oficial. Não sou responsável por quaisquer perdas causadas pelo uso deste código de armazém.

Acho que você gosta

Origin blog.csdn.net/bossma/article/details/132844396
Recomendado
Clasificación