Вы можете скачать пакеты с веб-сайта и запустить python setup.py install
. Или вы можете запустить pip install
в локальном каталоге, например:
pip install path/to/tar/ball
https://pip.pypa.io/en/stable/reference/pip_install/#usage [113 ]
Смотрите на это сообщение, где можно загрузить обертку прокси, которая делает повторную попытку, когда сессия истекает.
http://www.dasblonde.net/2008/04/24/MyProxyWrapperAndTheEVILSUOFile.aspx
Вы могли решить свои вопросы при помощи делегатов. Это позволит безопасно вызывать действие и, если сбои, поймайте исключение, создайте новый сервисный экземпляр и выполните действие снова.
using System;
using System.ServiceModel;
using System.ServiceModel.Security;
public static class Service
{
private static IService _service;
public static void Invoke(Action<IService> action)
{
try
{
action(_service);
}
catch (MessageSecurityException)
{
if (_service.State != CommunicationState.Faulted)
{
throw;
}
_service.Abort();
_service = CreateFreshInstance();
action(_service);
}
}
}
Вы могли затем назвать свой класс помощника как Service.Invoke(s => s.Method());
вызвать IService. Метод ().
Вы смогли использовать шаблон декоратора для обрабатывания исключений с прокси WCF. Если этот контур открыт для Вас, можно считать что-то вроде этого установкой, которая обработает сбой прокси и повторно инициализирует его для вызывающих сторон. Последующие исключения будут выданы до вызывающей стороны.
//Proxy implements this
interface IMyService
{
void MyMethod();
}
//Decorator 1
public class MyServiceProxyRetryingDecorator : IMyService
{
//This is the real proxy that might be faulted
private realProxy = new RealProxy();
public void MyMethod()
{
ReEstablishProxyIfNecessary();
//now just pass the call to the proxy, if it errors again,
//do more handling or let the exception bubble up
realProxy.MyMethod();
}
private void ReEstablishProxyIfNecessary()
{
if(realProxy.CommunicationState == CommunicationState.Faulted)
{
realProxy.Abort();
realProxy = new RealProxy();
}
}
}
Другая версия декоратора могла иметь декоратора, обрабатывающего Ваш MessageSecurityException и повторно инициализирующего реальный прокси, когда это поймано:
//Decorator 2
public class MyServiceProxyExceptionHandlingDecorator : IMyService
{
//This is the real proxy that might be faulted
private realProxy = new RealProxy();
public void MyMethod()
{
try {realProxy.MyMethod(); }
catch (ExceptionYouAreInterestedIn ex)
{
ReEstablishProxyIfNecessary();
realProxy.MyMethod(); //do it again
}
}
private void ReEstablishProxyIfNecessary()
{
if(realProxy.CommunicationState == CommunicationState.Faulted)
{
realProxy.Abort();
realProxy = new RealProxy();
}
}
}
Основываясь на первом ответе, я придумал это решение, которое в целом обертывает автоматически сгенерированные клиентские прокси, созданные svcutil.exe:
public class ProxyWrapper<T> where T : ICommunicationObject
{
private T _service;
public ProxyWrapper()
{
_service = CreateNewInstance();
}
public void Invoke(Action<T> action)
{
try
{
action(_service);
}
catch (MessageSecurityException)
{
if (_service.State != CommunicationState.Faulted)
{
throw;
}
_service.Abort();
_service = CreateNewInstance();
action(_service);
}
}
public TResult Invoke<TResult>(Func<T, TResult> func)
{
try
{
return func(_service);
}
catch (MessageSecurityException)
{
if (_service.State != CommunicationState.Faulted)
{
throw;
}
_service.Abort();
_service = CreateNewInstance();
return func(_service);
}
}
private T CreateNewInstance()
{
Type type = typeof(T);
return (T)type.GetConstructor(Type.EmptyTypes).Invoke(null);
}
}
Чтобы использовать это, все, что вам нужно сделать, это:
ProxyWrapper<ServiceClient> client = new ProxyWrapper<ServiceClient>();
client.Invoke(s => s.SomeAction());
int val = client.Invoke<int>(s => s.ReturnsAnInteger());
Примечание: Поскольку я использую только конструктор по умолчанию для клиентских прокси, все это поддерживает.