简体   繁体   English

在WCF中实现客户端回调功能

[英]Implementing client callback functionality in WCF

The project I'm working on is a client-server application with all services written in WCF and the client in WPF. 我正在处理的项目是一个客户端-服务器应用程序,所有服务均以WCF编写,而客户端则以WPF编写。 There are cases where the server needs to push information to the client. 在某些情况下,服务器需要将信息推送到客户端。 I initially though about using WCF Duplex Services, but after doing some research online, I figured a lot of people are avoiding it for many reasons. 我最初虽然使用WCF Duplex Services,但是在网上进行了一些研究之后,我发现很多人由于许多原因而避免使用它。

The next thing I thought about was having the client create a host connection, so that the server could use that to make a service call to the client. 我想考虑的下一件事是让客户端创建主机连接,以便服务器可以使用该主机连接来对客户端进行服务调用。 The problem however, is that the application is deployed over the internet, so that approach requires configuring the firewall to allow incoming traffic and since most of the users are regular users, that might also require configuring the router to allow port forwarding, which again is a hassle for the user. 但是,问题在于该应用程序已部署在Internet上,因此该方法需要将防火墙配置为允许传入流量,并且由于大多数用户是常规用户,因此可能还需要配置路由器以允许端口转发,这又是给用户带来麻烦。

My third option is that in the client, spawns a background thread which makes a call to the GetNotifications() method on server. 我的第三个选择是在客户端中产生一个后台线程,该线程调用服务器上的GetNotifications()方法。 This method on the server side then, blocks until an actual notification is created, then the thread is notified (using an AutoResetEvent object maybe?) and the information gets sent to the client. 然后,服务器端的此方法将阻塞,直到创建实际通知为止,然后才通知线程(可能使用AutoResetEvent对象?),然后将信息发送给客户端。 The idea is something like this: 这个想法是这样的:

Client 客户

private void InitializeListener()
{
    Task.Factory.StartNew(() =>
    {
        while (true)
        {
            var notification = server.GetNotifications();

            // Display the notification.
        }
    }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}

Server 服务器

public NotificationObject GetNotifications()
{
    while (true)
    {
         notificationEvent.WaitOne();
         return someNotificationObject;
    }
}

private void NotificationCreated()
{
    // Inform the client of this event.
    notificationEvent.Set();
}

In this case, NotificationCreated() is a callback method called when the server needs to send information to the client. 在这种情况下, NotificationCreated()是当服务器需要向客户端发送信息时调用的回调方法。

What do you think about this approach? 您如何看待这种方法? Is this scalable at all? 这是完全可扩展的吗?

For each client you are going to hold a thread on the server. 对于每个客户端,您将在服务器上保留一个线程。 If you have a few hundred clients and the server wouldn't use the memory anyway, that may be fine. 如果您有几百个客户端,并且服务器仍然不使用内存,那可能很好。 If there can be more clients, or you do not wish to burn 1MB of stack per client, you should make some changes: 如果可以有更多客户端,或者您不希望每个客户端刻录1MB的堆栈,则应进行一些更改:

  1. Use an async WCF action method. 使用异步WCF操作方法。 They allow you to unblock the request thread while the method is waiting. 它们使您可以在方法等待时取消阻塞请求线程。
  2. Change the event model to an async once. 一次将事件模型更改为异步。 SemaphoreSlim has async support. SemaphoreSlim具有异步支持。 You can also use TaskCompletionSource . 您也可以使用TaskCompletionSource

That way you can scale up to many connections. 这样,您可以扩展到许多连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM