Вопрос по vb.net, c#, callback, wcf, .net – Какие шаги мне нужно предпринять, чтобы использовать обратные вызовы WCF?

40

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

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

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

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

Спасибо

Ваш Ответ

4   ответа
82

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;
Это самая полезная вещь, которую я нашел, пытаясь научиться дуплексной связи в WCF.
Я все еще думаю, что это слишком сложно. Я собираюсь реализовать с помощью сокета: P
Копирование / вставка этого решения не работает для меня (VS2010, .NET 4.0). Клиент заблокирует ожидание ответа сервера, и вы получите исключения тайм-аута. Вы должны поместить [OperationContract (IsOneWay = true)] в DoSomething. В качестве альтернативы вы можете либо самостоятельно обрабатывать потоки, либо установить ConcurrencyMode = Multiple, UseSynchronizationContext = false в MyCallbackClient. Смотрите этот вопрос / ответ:stackoverflow.com/a/13091230/2184185
Мне было интересно, почему был добавлен ConcurrencyMode.Reentrant. Без этого можно было бы получить исключение на стороне службы: «Исключение типа» System.InvalidOperationException & apos; произошла в mscorlib.dll, но не была обработана в коде пользователя. Дополнительная информация: Эта операция может привести к взаимоблокировке, поскольку ответ не может быть получен, пока текущее сообщение не завершит обработку. Если вы хотите разрешить обработку сообщений не по порядку, задайте ConcurrencyMode для Reentrant или Multiple в ServiceBehaviorAttribute. & Quot;
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
3

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

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

2

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

К сожалению, реальность с WCF заключается в том, что простого примера не существует. Это требует от вас определения контрактов, настройки сервисов, использования хоста и создания клиентского кода. Взгляни наЭта статья за несколько простой пример.

Похожие вопросы