使用WCF回调需要采取哪些步骤?

时间:2022-01-14 07:59:10

I am trying to learn WCF. I have a simple client and server application setup and upon pressing a button on the client, it gets an updated value from the server.

我正在努力学习WCF。我有一个简单的客户端和服务器应用程序设置,并在按下客户端上的按钮后,它从服务器获取更新的值。

My next step is I am trying to do a callback from the server to the client to update its value. I have poured through many examples, and they just seem too big and confusing. Is there anyone that can give my just the simplest example of its implementation in C#?

我的下一步是尝试从服务器到客户端进行回调以更新其值。我已经倾注了很多例子,它们看起来太大而且令人困惑。有没有人可以在C#中给出我最简单的实现示例?

I keep looking through examples online and I just do not understand what it takes? Of course I could copy the example line by line but that does me no good because I still don't what to implement if I wanted to do this in my own code.

我一直在线查看示例,我只是不明白它需要什么?当然,我可以逐行复制示例,但这对我没有好处,因为如果我想在自己的代码中执行此操作,我仍然没有实现。

Could someone please help me with a very simple example on what steps I would need to take and what I would need to do in the server code and then in the client code to make this happen?

有人可以帮我一个非常简单的例子,说明我需要采取什么步骤以及我需要在服务器代码中做什么,然后在客户端代码中才能实现这一目标?

Thank you

谢谢

4 个解决方案

#1


77  

Here is about the simplest complete example that I can come up with:

这是关于我能想出的最简单的完整示例:

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();
    }
}

A few namespaces will need to be included in order to run the example:

为了运行示例,需要包含一些名称空间:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

#2


3  

Grab a copy of "Programming WCF Services, 2nd Edition" by Juval Lowy. There are large sections of the book devoted to Callback operations. In Chapter 5, start on page 214. In the chapter on Concurrency Management (ch. 8) there's even more information.

抓住Juval Lowy的“Programming WCF Services,2nd Edition”。本书的大部分内容专门用于回调操作。在第5章,从第214页开始。在“并发管理”(第8章)一章中,还有更多信息。

"Programming WCF Services" is more or less the WCF "bible."

“编程WCF服务”或多或少是WCF“圣经”。

#3


2  

If I'm reading your question right, you want to have a two-way conversation between the client and the server (the server can communicate back to the client). The WSDualHttpBinding gives you this functionality.

如果我正确地阅读您的问题,您希望在客户端和服务器之间进行双向对话(服务器可以与客户端进行通信)。 WSDualHttpBinding为您提供此功能。

The unfortunate reality with WCF is that there is no such thing as a simple example. It requires you to define contracts, configure the services, and use a host, and create client code. Take a look at this article for a somewhat simple example.

WCF的不幸现实是没有一个简单的例子。它要求您定义合同,配置服务,使用主机,并创建客户端代码。看一下这篇文章,看一个简单的例子。

#4


2  

I know, old question... I came across this question from a google search earlier today and the answer provided by Ray Vernagus is the easiest to understand example of WCF that I have read to date. So much so that I was able to rewrite it in VB.NET without using any online converters. I thought I'd add the VB.NET variant of the example that Ray Vernagus provided. Just create a new VB.NET Windows Console application, add a reference to System.ServiceModel, and copy/paste the entire code below into the default Module1 class file.

我知道,老问题......我今天早些时候从谷歌搜索中发现了这个问题,Ray Vernagus提供的答案是迄今为止我读过的最容易理解的WCF示例。这么多,以至于我能够在不使用任何在线转换器的情况下在VB.NET中重写它。我想我会添加Ray Vernagus提供的示例的VB.NET变体。只需创建一个新的VB.NET Windows控制台应用程序,添加对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

#1


77  

Here is about the simplest complete example that I can come up with:

这是关于我能想出的最简单的完整示例:

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();
    }
}

A few namespaces will need to be included in order to run the example:

为了运行示例,需要包含一些名称空间:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

#2


3  

Grab a copy of "Programming WCF Services, 2nd Edition" by Juval Lowy. There are large sections of the book devoted to Callback operations. In Chapter 5, start on page 214. In the chapter on Concurrency Management (ch. 8) there's even more information.

抓住Juval Lowy的“Programming WCF Services,2nd Edition”。本书的大部分内容专门用于回调操作。在第5章,从第214页开始。在“并发管理”(第8章)一章中,还有更多信息。

"Programming WCF Services" is more or less the WCF "bible."

“编程WCF服务”或多或少是WCF“圣经”。

#3


2  

If I'm reading your question right, you want to have a two-way conversation between the client and the server (the server can communicate back to the client). The WSDualHttpBinding gives you this functionality.

如果我正确地阅读您的问题,您希望在客户端和服务器之间进行双向对话(服务器可以与客户端进行通信)。 WSDualHttpBinding为您提供此功能。

The unfortunate reality with WCF is that there is no such thing as a simple example. It requires you to define contracts, configure the services, and use a host, and create client code. Take a look at this article for a somewhat simple example.

WCF的不幸现实是没有一个简单的例子。它要求您定义合同,配置服务,使用主机,并创建客户端代码。看一下这篇文章,看一个简单的例子。

#4


2  

I know, old question... I came across this question from a google search earlier today and the answer provided by Ray Vernagus is the easiest to understand example of WCF that I have read to date. So much so that I was able to rewrite it in VB.NET without using any online converters. I thought I'd add the VB.NET variant of the example that Ray Vernagus provided. Just create a new VB.NET Windows Console application, add a reference to System.ServiceModel, and copy/paste the entire code below into the default Module1 class file.

我知道,老问题......我今天早些时候从谷歌搜索中发现了这个问题,Ray Vernagus提供的答案是迄今为止我读过的最容易理解的WCF示例。这么多,以至于我能够在不使用任何在线转换器的情况下在VB.NET中重写它。我想我会添加Ray Vernagus提供的示例的VB.NET变体。只需创建一个新的VB.NET Windows控制台应用程序,添加对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