В общем, мы, за исключением дуплекса, работаем так, что клиент возвращается сразу после вызова службы, а информация, отправляемая обратно сервером, передается через контракт обратного вызова.в этом рабочем режиме мы превращаем и контракт на обслуживание, и контракт на обратный вызов в одностороннюю связь.
[OperationContract(Action = "post_num", IsOneWay = true)]
void PostNumber(int n);
Я сделал демонстрацию, хочу, чтобы она была вам полезна.
На стороне сервера.
class Program
{
static void Main(string[] args)
{
using (ServiceHost sh=new ServiceHost(typeof(MyService)))
{
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb==null)
{
smb = new ServiceMetadataBehavior()
{
HttpGetEnabled = true
};
sh.Description.Behaviors.Add(smb);
}
sh.Open();
Console.WriteLine("Service is ready");
Console.ReadKey();
sh.Close();
}
}
}
[ServiceContract(Namespace ="mydomain",Name = "demo", ConfigurationName = "isv", CallbackContract = typeof(ICallback))]
public interface IDemo
{
[OperationContract(Action = "post_num", IsOneWay = true)]
void PostNumber(int n);
}
[ServiceContract]
public interface ICallback
{
[OperationContract(Action = "report", IsOneWay = true)]
void Report(double progress);
}
[ServiceBehavior(ConfigurationName ="sv")]
public class MyService : IDemo
{
public void PostNumber(int n)
{
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
for (int i = 0; i <=n; i++)
{
Task.Delay(500).Wait();
double p = Convert.ToDouble(i) / Convert.ToDouble(n);
callback.Report(p);
}
}
}
Конфигурация сервера
<system.serviceModel>
<services>
<service name="sv">
<endpoint address="http://localhost:3333" binding="wsDualHttpBinding" contract="isv"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:3333"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
На стороне клиента.
class Program
{
static void Main(string[] args)
{
DuplexChannelFactory<IDemo> factory = new DuplexChannelFactory<IDemo>(new CallbackHandler(), "test_ep");
IDemo channel = factory.CreateChannel();
Console.WriteLine("Start to Call");
channel.PostNumber(15);
Console.WriteLine("Calling is done");
Console.ReadLine();
}
}
[ServiceContract(Namespace ="mydomain",Name = "demo", ConfigurationName = "isv", CallbackContract = typeof(ICallback))]
public interface IDemo
{
[OperationContract(Action = "post_num",IsOneWay =true)]
void PostNumber(int n);
}
[ServiceContract]
public interface ICallback
{
[OperationContract(Action = "report",IsOneWay =true)]
void Report(double progress);
}
public class CallbackHandler : ICallback
{
public void Report(double progress)
{
Console.WriteLine("{0:p0}", progress);
}
}
Client-config
<system.serviceModel>
<client>
<endpoint name="test_ep" address="http://localhost:3333" binding="wsDualHttpBinding" contract="isv"/>
</client>
</system.serviceModel>
Результат.