Reputation: 46470
I have a project coming up with the requirement to notify WPF desktop clients when something happens on the server. Additionally, the notification to the WPF clients will not be broadcasted (sent to every client), it should be sent to specific clients.
I want to stay away from old fashioned server polling. This needs to be as close to real time as possible.
I've never had this requirement before and I'm investigating solutions. My first thought was to use SignalR with the .NET client. I haven't worked with SignalR yet, but it seems like it could be a solution. I am aware that this is an abstraction over long-polling, Server-Sent Events, and WebSockets, depending on what is available.
I've read briefly about WCF with Callbacks and service buses, but know nothing about them yet or whether those technologies apply here. I could use some feedback and suggestions from the people who have tackled this before. How would you do it?
Upvotes: 16
Views: 5128
Reputation: 958
I was also evaluating a light weight yet easy way to communicate events to WPF clients using a pub/sub service. I did not require guaranteed message delivery so solutions like MassTransit or NServiceBus seemed too heavy as they require queues to be available (MSMQ or otherwise). I also had the requirement that the solution be available as .NET 4.0 Client Profile.
One solution built on WCF that seems to work is nvents. I'm not sure if that project is still active. It is easy to use and the underlying implementation (WCF) is well abstracted. No nasty configuration required.
Another solution I came across on Per Brage's Blog uses SignalR with Reactive Extensions. I haven't tried his implementation and am not sure if it requires a full profile but is a good read!
Upvotes: 3
Reputation: 15467
The point of technologies like SignalR are to meet the demand for realtime communication between servers and web clients. They take advantage of WebSockets and fallback to older/hackier communication mechanisms for older web browsers.
If your environment is going to be a LAN and your client a .NET app then you could use a TCPServer and multiple TCPClients. When your web server has an update/message to send tell your TCPServer (maybe by putting a message on a message bus which it's listening to) which can inform the connected client(s). Realtime web technologies are a great way of doing this but it really depends what your current requirements are and what your plans for the future are:
Note: Although I'm saying TCPServer/Client might be the simplest approach I'd like to emphasise that it also might not be. WebSockets are a really exciting technology and are in many ways more accessible than TCPClient technology so could become the dominant technology for bi-direction communication between any server and client*
I can't comment on Duplex Contracts but my understanding was that the connection they establish were not persisted so they are actually a polling solution - I could be wrong.
Upvotes: 4
Reputation: 790
You can create a wcf service where wpf clients register themselve to on startup. Then each wpf could communicate with a msmq or rabbitmq server where they will poll their own queue created based on the client name/unique id. On the server side, you can have a service that will push data to the queues as data are available based on conditions set for each clients.
Upvotes: 0
Reputation: 16121
This can be done quite easily with WCF and duplex contracts. You can define operations that the client can perform on the server (like any web service) and in addition you can define operations that the server can perform on the client (i.e. a reverse web-service). Code wise, they're both just simple method calls. The client has methods that call operations on the server and it also must supply an object that implements the callback contract, which is an interface the server can call and the client must provide an implementation for. All serialization/deserialization of data and messages and all low level network operations are handled by WCF, so you won’t have to worry about it.
WCF supports duplex contracts using two bindings (or 'protocols'):
WSDualHttpBinding - This entails two SOAP-based HTTP listeners, one on the server and one on the client. When the client wants to contact the server, it performs an HTTP request to server. When the server wants to contact the client, it performs a HTTP request to the client. The advantage of this approach is that any network connection is fleeting, and is not kept open (as with most HTTP connections), and so it can support a large number or concurrent clients. The main disadvantage is that it probably won't work with most client computers over the internet since they are usually behind NAT (a non-issue for server-to-server communications over the internet or any sort of communication inside an intranet or LAN). For more details, see my other answer.
NetTcpBinding - This basically opens a socket from the client to the server and keeps it open for the duration of the session. This allows two way communications even over NAT, but since connections must be kept open it is somewhat more of a burden on the server and therefore will be able to support less concurrent users (but probably still more than enough in most cases). This is my preferred way of doing duplex contracts on WCF since it’s easier to get working and is more reliable.
The advantage of WCF is that you can switch between the two bindings without changing your code. All that is required is changing the configuration (.config file).
Whichever way you choose, you'll be able to perform near-instantaneous communication in both directions (network latency permitting, of course). I don't see the need for SignalR when you have such a rich, powerful and easy to user framework such as WCF at your disposal. If you were constrained by running in a browser, then SignalR would make sense. Since you're running in .NET, it would just introduce unnecessary friction.
Upvotes: 7
Reputation: 9431
You should look into WebSync from Frozen Mountain. I've used it in the past with great results. It does all you require. They even offer a hosted service 'WebSync on Demand'. They offer a free product as well (but up to 10 concurrent users). It is a comercial product. If you don't want to do all the plumbing, WebSync offers you ready to use api's you can just start using and get going fast. I've heard/read about SignalR, have not used it yet, but SignalR seems to be in alpha/beta, whereas WebSync is very mature.
Upvotes: 3
Reputation: 1625
This question is interesting.
We are currently developing an application that interacts with multiple Web Services. One of the requirements is that each client must be kept aware of the actions done by the other clients.
In order to achieve this, we're thinking of creating a Web Service whose purpose is only to build a list of clients to notify, and to handle the logic behind who is notified, when, and the content of the notification. The clients would register with that Service when they are launched. The notifications themselves would be done using callbacks as you mentioned.
The reason behind using a completely separate Web Service was due to the fact that all our existing ones required connections to be established and dropped on every call. With the notification Web Service, connections have to be maintained as long as the clients run.
I'm sorry I could not be of much more help, as we're in the process of developing such a system ourselves. I'm also interested in obtaining feedback on this subject.
Upvotes: 0