Подтвердить что ты не робот

Какие шаги я должен предпринять, чтобы использовать обратные вызовы WCF?

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

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

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

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

Спасибо

4b9b3361

Ответ 1

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

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;

Ответ 2

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

"Программирование служб WCF" более или менее является "библией WCF".

Ответ 3

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

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

Ответ 4

Я знаю, старый вопрос... Сегодня я столкнулся с этим вопросом из 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