我正在开发的项目是一个客户端 - 服务器应用程序,其中所有服务都是用WCF编写的,而客户端是用WPF编写的。在某些情况下,服务器需要将信息推送到客户端。我最初虽然关于使用WCF双工服务,但在网上进行了一些研究之后,我认为很多人因为很多原因而避免使用它。
我想到的下一件事是让客户端创建一个主机连接,以便服务器可以使用它来对客户端进行服务调用。然而,问题是应用程序是通过互联网部署的,因此该方法需要配置防火墙以允许传入流量,并且由于大多数用户是常规用户,这可能还需要配置路由器以允许端口转发,这也是给用户带来麻烦。
我的第三个选择是在客户端中生成一个后台线程,该线程调用服务器上的GetNotifications()
方法。然后,服务器端的此方法将阻塞,直到创建实际通知,然后通知线程(可能使用AutoResetEvent
对象?)并将信息发送到客户端。这个想法是这样的:
客户端
private void InitializeListener()
{
Task.Factory.StartNew(() =>
{
while (true)
{
var notification = server.GetNotifications();
// Display the notification.
}
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
服务器
public NotificationObject GetNotifications()
{
while (true)
{
notificationEvent.WaitOne();
return someNotificationObject;
}
}
private void NotificationCreated()
{
// Inform the client of this event.
notificationEvent.Set();
}
在这种情况下,NotificationCreated()
是服务器需要向客户端发送信息时调用的回调方法。
您如何看待这种方法?这可扩展吗?
答案 0 :(得分:1)
对于每个客户端,您将在服务器上保留一个线程。如果您有几百个客户端并且服务器无论如何都不会使用内存,那可能没问题。如果可以有更多客户端,或者您不希望为每个客户端刻录1MB堆栈,则应进行一些更改:
SemaphoreSlim
具有异步支持。您也可以使用TaskCompletionSource
。通过这种方式,您可以扩展到许多连接。