vs2017 tutorial microsoft .net azure azure-service-fabric

.net - tutorial - ¿Cómo agregar un encabezado de mensaje a la solicitud cuando se usa el cliente predeterminado de la estructura de servicio de Azure?



service fabric tutorial (2)

Hice la misma pregunta en el foro de MSDN hace unas semanas, sin embargo, no obtuve respuesta allí.

Miré el código fuente de la biblioteca del cliente y no encontré una manera de agregar encabezados. Me temo que la única forma es agregarlos como parte de la llamada al método. Esto podría hacerse usando clases de solicitud como parámetros de método y usando herencia para ellos. (p. ej., clase RequestBase con encabezados [Authorization, ClientInfo, ...]). Luego debe asegurarse de que estos encabezados estén configurados para cada solicitud ajustando todas las invocaciones o configurándolas manualmente.

Se agradecería mucho más aclaraciones del equipo de Service Fabric.

Me pregunto si es posible inyectar un encabezado de mensaje personalizado en la solicitud saliente para llevar información adicional sin deserializar la carga útil para completar la funcionalidad como autenticación, validación o correlación de solicitud como wcf proporcionada por medio de messagesinspector.


Actualizar

Con SDK v2, ahora puede (relativamente) modificar fácilmente los encabezados de los servicios y actores confiables. Tenga en cuenta que en los ejemplos a continuación se omitieron algunos miembros del contenedor por brevedad.

Cliente

Utilizamos ServiceProxyFactory para crear proxies en lugar del ServiceProxy estático. Luego podemos envolver IServiceRemotingClientFactory e IServiceRemotingClient e interceptar las llamadas de servicio. Lo mismo se puede hacer con ActorProxyFactory . Tenga en cuenta que esto anula el comportamiento de atributos como WcfServiceRemotingProviderAttribute , ya que especificamos explícitamente la fábrica del cliente nosotros mismos.

_proxyFactory = new ServiceProxyFactory(c => new ServiceRemotingClientFactoryWrapper( // we can use any factory here new WcfServiceRemotingClientFactory(callbackClient: c))); private class ServiceRemotingClientFactoryWrapper : IServiceRemotingClientFactory { private readonly IServiceRemotingClientFactory _inner; public ServiceRemotingClientFactoryWrapper(IServiceRemotingClientFactory inner) { _inner = inner; } public async Task<IServiceRemotingClient> GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken) { var client = await _inner.GetClientAsync(serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings, cancellationToken).ConfigureAwait(false); return new ServiceRemotingClientWrapper(client); } } private class ServiceRemotingClientWrapper : IServiceRemotingClient { private readonly IServiceRemotingClient _inner; public ServiceRemotingClientWrapper(IServiceRemotingClient inner) { _inner = inner; } public Task<byte[]> RequestResponseAsync(ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody) { // use messageHeaders.AddHeader() here return _inner.RequestResponseAsync(messageHeaders, requestBody); } public void SendOneWay(ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody) { // use messageHeaders.AddHeader() here _inner.SendOneWay(messageHeaders, requestBody); } }

Servidor

Herede de ServiceRemotingDispatcher y ActorServiceRemotingDispatcher para examinar los encabezados.

class CustomServiceRemotingDispatcher : ServiceRemotingDispatcher { public override async Task<byte[]> RequestResponseAsync(IServiceRemotingRequestContext requestContext, ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody) { // read messageHeaders here // or alternatively put them in an AsyncLocal<T> scope // so they can be accessed down the call chain return base.RequestResponseAsync(requestContext, messageHeaders, requestBody); } }

Para usar esta clase, nuevamente necesitamos anular el ServiceRemotingProviderAttribute creando directamente el escucha de comunicación:

class MyService : StatelessService { protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() { yield return new ServiceInstanceListener(context => new WcfServiceRemotingListener(context, new CustomServiceRemotingDispatcher()); } }