2009-06-25 1 views
39

Я пытаюсь изучить WCF. У меня есть простая настройка клиентского и серверного приложений, и после нажатия кнопки на клиенте она получает обновленное значение с сервера.Какие шаги необходимо предпринять для использования обратных вызовов WCF?

Следующим шагом я пытаюсь выполнить обратный вызов с сервера на клиент, чтобы обновить его значение. Я пролил много примеров, и они кажутся слишком большими и запутанными. Есть ли кто-нибудь, кто может дать мне просто самый простой пример его реализации на C#?

Я продолжаю просматривать примеры в Интернете, и я просто не понимаю, что нужно? Конечно, я мог бы скопировать пример строки за строкой, но это не делает мне ничего хорошего, потому что я все еще не понимаю, что реализовать, если бы я хотел сделать это в своем собственном коде.

Может кто-нибудь, пожалуйста, помогите мне с очень простым примером того, какие шаги мне нужно предпринять, и что мне нужно делать в код сервера, а затем в код клиента, чтобы это произошло?

Спасибо

ответ

75

Вот о простом полном примере, который я могу придумать:

public interface IMyContractCallback 
{ 
    [OperationContract] 
    void OnCallback(); 
} 

[ServiceContract(CallbackContract = typeof(IMyContractCallback))] 
public interface IMyContract 
{ 
    [OperationContract] 
    void DoSomething(); 
} 

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)] 
public class MyService : IMyContract 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("Hi from server!"); 
     var callback = OperationContext.Current.GetCallbackChannel<IMyContractCallback>(); 
     callback.OnCallback(); 
    } 
} 

public class MyContractClient : DuplexClientBase<IMyContract> 
{ 
    public MyContractClient(object callbackInstance, Binding binding, EndpointAddress remoteAddress) 
     : base(callbackInstance, binding, remoteAddress) { } 
} 

public class MyCallbackClient : IMyContractCallback 
{ 
    public void OnCallback() 
    { 
     Console.WriteLine("Hi from client!"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var uri = new Uri("net.tcp://localhost"); 
     var binding = new NetTcpBinding(); 
     var host = new ServiceHost(typeof(MyService), uri); 
     host.AddServiceEndpoint(typeof(IMyContract), binding, ""); 
     host.Open(); 

     var callback = new MyCallbackClient(); 
     var client = new MyContractClient(callback, binding, new EndpointAddress(uri)); 
     var proxy = client.ChannelFactory.CreateChannel(); 
     proxy.DoSomething(); 
     // Printed in console: 
     // Hi from server! 
     // Hi from client! 

     client.Close(); 
     host.Close(); 
    } 
} 

Несколько имен должны быть включены для того, чтобы запустить пример:

using System; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
+1

Я до сих пор считаю, что это слишком сложно. Я собираюсь реализовать сокет: P – Seva

+4

Копирование/вставка этого решения для меня не работало (VS2010, .NET 4.0). Клиент и заблокирует ожидание ответа сервера, и вы получите исключения тайм-аута. Вы должны поместить [OperationContract (IsOneWay = true)] в DoSomething. Кроме того, вы можете либо обрабатывать потоки самостоятельно, либо установить ConcurrencyMode = Multiple, UseSynchronizationContext = false в MyCallbackClient. См. Этот вопрос/ответ: http://stackoverflow.com/a/13091230/2184185 –

+0

Это самая полезная вещь, которую я нашел, пытаясь изучить дуплексную связь в WCF. –

2

Если я читаю ваш вопрос правильно, вы хотите иметь двусторонний разговор между клиентом и сервером (сервер может связываться обратно клиенту). WSDualHttpBinding предоставляет вам эту функциональность.

Несчастная реальность с WCF заключается в том, что нет такого простого примера. Он требует, чтобы вы определяли контракты, настраивали службы и использовали хост, а также создавали клиентский код. Посмотрите на this article на несколько простой пример.

3

захватить копию «Программирование WCF-сервисов, второе издание» Юваля Лоуи. Существуют большие разделы книги, посвященной операциям обратного вызова. В главе 5 запустите на стр. 214. В главе «Управление параллелизмом» (глава 8) есть еще больше информации.

«Программирование WCF-услуг» более или менее является «библией» WCF.

2

Я знаю, старый вопрос ... Сегодня я столкнулся с этим вопросом из поиска Google, и ответ, предоставленный Рэем Вернагусом, является самым легким для понимания примера WCF, который я прочитал на сегодняшний день. Настолько, что я смог переписать его в VB.NET без использования каких-либо онлайн-конвертеров. Я думал, что добавлю вариант VB.NET примера, предложенного Рэем Вернагусом. Просто создайте новое приложение консоли Windows VB.NET, добавьте ссылку на System.ServiceModel и скопируйте/вставьте весь код ниже в файл класса Module1 по умолчанию.

Imports System.ServiceModel 
Imports System.ServiceModel.Channels 



Public Interface IMyContractCallback 
    <OperationContract()> _ 
    Sub OnCallBack() 
End Interface 

<ServiceContract(CallBackContract:=GetType(IMyContractCallback))> _ 
Public Interface IMyContract 
    <OperationContract()> _ 
    Sub DoSomething() 
End Interface 

<ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Reentrant)> _ 
Public Class Myservice 
    Implements IMyContract 

    Public Sub DoSomething() Implements IMyContract.DoSomething 
     Console.WriteLine("Hi from server!") 
     Dim callback As IMyContractCallback = OperationContext.Current.GetCallbackChannel(Of IMyContractCallback)() 
     callback.OnCallBack() 
    End Sub 
End Class 

Public Class MyContractClient 
    Inherits DuplexClientBase(Of IMyContract) 

    Public Sub New(ByVal callbackinstance As Object, ByVal binding As Binding, ByVal remoteAddress As EndpointAddress) 
     MyBase.New(callbackinstance, binding, remoteAddress) 
    End Sub 
End Class 

Public Class MyCallbackClient 
    Implements IMyContractCallback 

    Public Sub OnCallBack() Implements IMyContractCallback.OnCallBack 
     Console.WriteLine("Hi from client!") 
    End Sub 
End Class 


Module Module1 

    Sub Main() 
     Dim uri As New Uri("net.tcp://localhost") 
     Dim binding As New NetTcpBinding() 
     Dim host As New ServiceHost(GetType(Myservice), uri) 
     host.AddServiceEndpoint(GetType(IMyContract), binding, "") 
     host.Open() 

     Dim callback As New MyCallbackClient() 
     Dim client As New MyContractClient(callback, binding, New EndpointAddress(uri)) 
     Dim proxy As IMyContract = client.ChannelFactory.CreateChannel() 

     proxy.DoSomething() 
     ' Printed in console: 
     ' Hi from server! 
     ' Hi from client! 

     Console.ReadLine() 

     client.Close() 
     host.Close() 
    End Sub 

End Module