I'm about to write a "server" application that is responsible to talk with external hardware. The application shall handle requests from clients. The clients send a message to the server, and if the server is busy with doing stuff with the hardware the new messages shall be stored in a queue that will be processed later.
The client shall also be able to cancel a request (if it is in the server's queue.). When the server application is finished with the hardware it shall be able to send the result back to the client that requested the job.
The server and client applications may or may not be on the same PC. All development is done in .NET (C#) 2005.
What is the best way to solve this communication problem?
MSMQ? SOAP? WCF? Remoting? Other?
Assuming you can use .NET 3.0 or greater then you probably want to WCF as the communications channel - the interface is consistent but it will allow you to use an appropriate transport mechanism depending on where the client and server are in relation to each other - so you can choose to use SOAP or MSMQ or a binary format or others as appropriate (and can roll your own if needed). It also covers the need for two way communication.
Queuing the messages at the server should probably be regarded as a separate problem - especially given the need to remove queued messages.
If clients and server processes are on the same machine, I think named pipes will give you the fastest raw byte transfer rate.
If the processes are across different machines, you'd need to use sockets-based approach.
Remoting is reportedly very slow. Based on the target OSes that you're planning to deploy the solution on, you could have options like WCF et al. However, the overhead of these protocols is something you may want to look at while deciding.
Remoting
If all development is done in .NET 2005, Remoting is the best way to go.
MSMQ would make some sense, though there are then security and deployment considerations. You could look at a service bus (such s NServiceBus or MassTransit) and there's also SQL Server Service Broker that could help (and can also be used by a service bus as the transport).
WCF would be another thing to look at, however that's really the across-network transport, so you'd probably still want the WCF calls to put a message on the server queue.
I don't recommend remoting, because it's hard to maintain a separation of concerns, and before you know it you're developing a really chatty interface without realising it. Remote calls are expensive in relative terms, so you should be trying to keep the messages fairly coarse-grained. WCF would be my recommendation. Not least because you can set it up to use a HTTP transport and avoid a lot of deployment and security headache.
The .NET Framework provides several ways to communicate with objects in different application domains, each designed with a particular level of expertise and flexibility in mind. For example, the growth of the Internet has made XML Web services an attractive method of communication, because XML Web services are built on the common infrastructure of the HTTP protocol and SOAP formatting, which uses XML. These are public standards, and can be used immediately with current Web infrastructures without worrying about additional proxy or firewall issues.
Not all applications should be built using some form of XML Web service, however, if only because of the performance issues related to using SOAP serialization over an HTTP connection.
Choosing Communication Options in .NET helps you decide which form of interobject communication you want for your application.
Related
we are evaluating a new project which will have a .NET Server which is available in the internet. We have access to the server but the hosting is done by a 3rd party company.
We are evaluating using WCF on the .NET Server. (I have no professional experience with WCF and just reading into the topic). The WCF service will talk to a SQL Server to perform its duties.
Here is the scenario:
Multiple client machines running our own ActionScript software will connect to that .NET Server.
Clients might be online 24/7 and should periodically poll our server to tell the server that they are there.
A client needs to be able to login, and only if the login has worked the other calls will be allowed and at some point it logs out. So we need to "remember" the state with a particual client...
Highest expected load is around 1000 Clients, of which 500 will only do polling while the other 500 will be "active". "Active" means a maximum of 1 call each minute, no heavy payload in each call, neither in the request nor in the response, just 1-3 database accesses per call.
We already tested some "HelloWorld" with ActionScript and WCF using BasicHttp(s)Binding.
But because we need session handling we were thinking about taking using the wsHttpBinding binding because it can provide us WCF Sessions.
So far so good, but then I stumbled upon the fact that it should
However:
I find that in my Oreilly WCF Services 3rd edition book (Page 177) it is written
and even Microsoft is writing to be careful using that:
http://msdn.microsoft.com/en-us/magazine/cc163590.aspx
"A service configured for private sessions cannot typically support more than a few dozen (or perhaps up to a few hundred) outstanding clients due to the cost associated with each such dedicated service instance."
So because we need to identify the state with each client, we could of course implement our own "Session Handling" on top of stateless HttpBindingBinding, and make a call to that SessionHandling class each time when my WCF methods get called, but I am reluctant to do anything like that, it looks to me like thousands of people should already have faced the same problem.
So, my question now is:
Do you think wsHttpBinding on my server could handle the payload?
How "bad" is it really to go with wsHttpBinding on WCF? Does anybody already have experience with this? Can I use it? What would you use?
Final Remarks:
I am not limited to WCF if we dont like it, we just shall do an evaluation.
From the companies point of view it would also be fine to go for a protobuf-RPC or XML-RPC solution over TCP and the ActionScript clients implementing that. (just examples!) So no need for hosting WCF in IIS on the server as long as the coding part is comfortable (enough) for the programmers on both sides and the ADMINISTRATION on the deployed server is not too much either. With just making some TCP-ports based communication I am a bit afraid what it would mean for the administration in regards to firewall and stuff. Payload is not an issue, client processing power is also not an issue. The only thing I am concerned about is scalability of the server and security.
Thanks in advance for any suggestions!
I would not be concerned with scalability. You can always add a server or two to your farm in case of issues.
I would rather be concerned with your architecture and the need to store anything in session - are you sure about that?
Note that you don't need ws binding to support sessions, basic binding supports sessions as well.
I am working on a project that i want to have a plugin-sandbox like System, However i am having issues working out 2-Way Real time Cross Process Communication. At first i thought of WCF, as it can pass object Metadata, but then soon realized that the Service Client model of WCF will pose an issue. but before i lay down all my ideas and questions here is what i have planned out.
I want to have a host application that will do most of the work, let us call this host.exe, host.exe will host the main application logic for the program, as well as the launching, executing, and killing of Plugins. Plugins will be hosted via a Plugin Proxy that will host them via MEF, so we will call it proxy.exe. The proxy.exe will load plugin dlls and host them in a secluded environment that will isolate faults and if the plugin fails it will kill the proxy and not the application. The Host and the Proxy need to communicate in real time in both directions and because there are going to be multiple proxy hosts it would be best to be able to pass object data.
so that is the basic idea of what i want. I was thinking of several ways to do this. the first being WCF, however i figured that the way WCF works it would be difficult if not impossible for the server of the service to send the client a request/command. the next idea what to use TCP, and have the host be a TCP server and develop a messaging protocol that i can use to communicate, however that poses an issue as i do not have the luxury of the WCF metadata and passing complex class information would be down right insane.
Through all my research i have came up with issue after issue after issue, it would much appreciated if anyone is able to suggest a solution to this issue. Thank you.
My solution for this would likely be remoting. I dont know if WCF does this the same way. but remoting can be configured with text and servers can be setup to remote to an object at will.
I want to warn you up front. The project I am mentioning is from quite a while ago so this may be out dated information (WCF may do the same thing or it may not, My company has not required any WCF work from me.)
I remoted my objects from the client to the server. I would run the server (actually on a separate machine) then using tcp remoting, all the objects I wanted would be declared into that application.
Now here is the fun part. that remoted object used non remoted delegate objects. I would initialize the object (remoted) and the server would create it. Then I would initialize another (Interface Typed) object local and attach it to the remote object.
When the remote object wanted to communicate to me it would send serializable information to me and I would construct that into more objects or commands. Whatever was needed... (possibly more remote objects)
In any rate. One server and multiple remote objects would be sent back and forth with a CommonInterface.dll with all the standard interface objects defined in it.
This was for all intents and purposes a blind plugin setup that any application wanting to get information to or from my server would be able to implement and handle their classes as long as the interfaces matched. (with serializable command data)
If the plugin (client) crashes then the application (server) would not have to suffer. It would just wrap all communication to that plugin in a try catch and the remoted object would have some sort of time to live or ping style release mechanism.
I dont really know what your scenario is going to be like with the sandboxing but this may accomplish what you are asking.
here is a .net remoting chat server.
http://www.codeproject.com/KB/IP/dotnetchatapplication.aspx
This is the same type of project I build my first time with remoting. and I evolved it into my server plugin architecture. The difference between my use and yours is that the server was my client was the main application using the server and yours the server will be the main application allowing multiple clients to plugin.
In my opinion, I advice you use different application domains, an communicate with plug-ins using interfaces, and a real proxy object references. Do not use different processes, you can achieve plug-ins isolation through application domain isolation, because exceptions do not cross application domain boundaries unless specified.
As an alternative, you can use deprecated technologies, as .NET Remoting, for tje cusom marshaling and transparent proxy object creation.
In my opinion, WCF is too heavy and too far from real-time processing
Interprocess communication (IPC). Which maybe should called cross-process communication (CPC) is a known MS/Windows specific concept.
More about it here
In the past I've used RPC and Windows Pipes (which is used also in SQL server for transferring large data-sets/results)
You can always try another method of communication, WCF, Sockets, Pub/Sub Messaging; example, TibcoRv (which locally would bypass sockets).
I find these to be a bit of an overkill. but could be perfect for your requirement.
I'm trying to figure out which client/server technology (i.e. which part of the .NET Framework) to use for our new application. We will be writing the app in C# using .NET 3.5 SP1.
It is going to consist of a central Service that will be running as a "server", and several client applications spread out on several machines. The client application is a trayapp application that is going to receive notifications from the server, and will also send some information back to the server. The communication will therefore be two-way, and it needs to be fast. The server will need to know which client to send the notifications to.
I've been thinking that I could use Sockets. I've also come across the TcpListener and TcpClient classes. Another alternative is to do something with WCF, but I'm not sure how to do fast two-way communication with it.
WCF with NetTcp binding.
You should write a duplex service.
Without knowing how much data you're planning to exchange, it's difficult to make a precise recommendation. I use both WCF and TCP sockets to exchange data between my UI and my Windows service. Here are the considerations I made.
I use WCF for what I refer to as aperiodic data exchange. For example, when an event occurs in my Windows service, I communicate the event to the UI using WCF. Specifically for this event-based mechanism, I would highly recommend Juval Lowy's Publish-Subscribe Framework, which is available for free here. I also use WCF to communicate configuration changes from the UI to the Windows service. WCF is a perfect solution for this kind of data exchange for me.
When the user tells my Windows service to perform some action, a lot of data is sent from the Windows service to the UI. For this, I use TCP sockets. I know WCF has a streaming capability, and I strongly considered using it. I just did not have time to get comfortable with it before I had to make a decision, so I went with what I knew.
While I wish I was using WCF across the board for symmetry, i.e., for aperiodic and streaming data, this hybrid approach has served me well.
Hope this helps.
I would avoid sockets if I were you since there is a lot to know about them. Just look at all socket questions here at SO. It can be a nightmare if you do not know how to use them properly.
WCF will take care of all lower levels for you.
I have a .Net service hosted on a server, and .Net clients connecting to this server over the internet.
I want to implement a publish subscribe model where clients can subscribe to events on the service and have data pushed to them as data becomes available. An alternative would be to have clients poll the server for data, however this will likely be too slow for what is required. Hence the need for a publish/subscribe type of communication.
I understand that the WCF binding WSDualHttpBinding does allow this, however it comes with a downside. According to "Programming WCF Services" author Juval Lowy,
...the WSDualHttpBinding is mostly
unusable, since it is practically
impossible to tunnel through various
communication barriers separating the
service from the client and the need
to find a specific web-server machine
makes this impractical.
I've interpretted this to mean (please correct me if I'm wrong) that to operate with WSDualHttpBinding, it is necessary for clients to open a port on their machines (along with any necessary router configuration) for the server to callback through. If this is the case using WSDualHttpBinding will not be an option for me. Using Windows Azure will also not be an option.
So the crux of my question is, how can I achieve a publish/subscribe/callback type of communication over the internet, without the need to open ports on the client machine? Open standards are ok but unnecessary as client and server are both .Net, Windows Azure is not an option.
WSDualHttpBinding contains two channels one from client to server and second from server to client. The later one indeed requires firewall and NAT configuration. What about Net.Tcp? It uses only single channel and supports callbacks (duplex communication) over that channel initiated from client to server. You mentioned that both client and server will be .NET application so it should be possible with some firewall configuration on the server.
You mention most of the options in your post.
There are 3 options:
Client polls the server. Does not require open ports but too slow.
WSDualHttpBinding requires opening of ports
Azure Service Bus, would do it but not an option.
There is actually a way to do it. If you look at how Azure service bus works, it tricks the client into thinking that it is on an out going port, when really it being used to send messages to the client. You could try to implement this functionality.
Another thing you could try is nservicebus at http://nservicebus.com/, this is an open source .net service bus.
Internet Communication Engine (ICE) offers IceStorm, a publish/subscribe service.
Its open source, and if you download the installation there is a sample Visual Studio project that demonstrates how to implement publish/subscribe (check out the "demos" .zip file and the "IceStorm" directory with the clock demo).
ICE will do all the heavy lifting for you, the learning curve is remarkably short, primarily because the documentation is massive, approachable and well written.
I strongly recommend you DDS (data distribution service from OMG) over the internet http://www.omg.org/news/meetings/workshops/Real-time_WS_Final_Presentations_2008/Session%203/03-02_Bertocci_et_al.pdf
From OMG, that's all I gotta say. Yes, I know you may think OMG is over. I don't, and as a government counselor I really push for standards. Keep in mind that besides the liberal ideology and crises, governments are still a huge customers and inter-operation is a must.
NServiceBus? Right, ok, that's fine, but ain't too complex to start right now? Learning curve is too ... steep? I guess is not but, any easier one?
ICE is a good choice. guys from CORBA world trying to make things better. Don't doubt it, use it, try it! Just a feeling: even with the storm service you might feel you are still in the request/reply world ... but is that a con?
But if you rather prefer a commercial but open solution, think about publish subscribe using protocol buffers (search Google protocol buffers) ... just a first approach http://protocolbus.casessite.org . This is my owm work ... sorry it's just an initial project but I'm working with a central broker distribution as an alternative transport (default is multicast but broadcast and udp is also available). Open source, so be free ...
I have 50+ kiosk style computers that I want to be able to get a status update, from a single computer, on demand as opposed to an interval. These computers are on a LAN in respect to the computer requesting the status.
I researched WCF however it looks like I'll need IIS installed and I would rather not install IIS on 50+ Windows XP boxes -- so I think that eliminates using a webservice unless it's possible to have a WinForm host a webservice?
I also researched using System.Net.Sockets and even got a barely functional prototype going however I feel I'm not skilled enough to make it a solid and reliable system. Given this path, I would need to learn more about socket programming and threading.
These boxes are running .NET 3.5 SP1, so I have complete flexibility in the .NET version however I'd like to stick to C#.
What is the best way to implement this? Should I just bite the bullet and learn Sockets more or does .NET have a better way of handling this?
edit:
I was going to go with a two way communication until I realized that all I needed was a one way communication.
edit 2:
I was avoiding the traditional server/client and going with an inverse because I wanted to avoid consuming too much bandwidth and wasn't sure what kind of overhead I was talking about. I was also hoping to have more control of the individual kiosks. After looking at it, I think I can still have that with WCF and connect by IP (which I wasn't aware I could connect by IP, I was thinking I would have to add 50 webservices or something).
WCF does not have to be hosted within IIS, it can be hosted within your Winform, as a console application or as windows service.
You can have each computer host its service within the winform, and write a program in your own computer to call each computer's service to get the status information.
Another way of doing it is to host one service in your own computer, and make the 50+ computers to call the service once their status were updated, you can use a database for the service to persist the status data of each node within the network. This option is easier to maintain and scalable.
P.S.
WCF aims to replace .net remoting, the alternatives can be net.tcp binding or net.pipe
Unless you have plans to scale this to several thousand clients I don't think WCF performance will even be a fringe issue. You can easily host WCF services from windows services or Winforms applications, and you'll find getting something working with WCF will be fairly simple once you get the key concepts.
I've deployed something similar with around 100-150 clients with great success.
There's plenty of resources out on the web to get you started - here's one to get you going:
http://msdn.microsoft.com/en-us/library/aa480190.aspx
Whether you use a web service or WCF on your central server, you only need to install and configure IIS on the server (and not on the 50+ clients).
What you're trying to do is a little unclear from the question, but if the clients need to call the server (to get a server status, for example), then they just call a method on the webservice running on the server.
If instead you need to have the server call the clients from time to time, then you'll need to have each client call a sign-in method on the server webservice each time the client starts up. The sign-in method would take a delegate method from the client as a parameter. The server would then call this delegate when it needed information from the client.
Setting up each client with its own web service would represent an inversion of the traditional (one server, multiple clients) client/server architecture, and as you've already noted this would be impractical.
Do not use remoting.
If you want robustness and scalability you end up ruling out everything but what are essentially stateless remote procedure calls. Since this is exactly the capability of web services, and web services are simpler and easier to build, remoting is an essentially pointless technology.
Callbacks with remote delegates are on the performance/reliability forbidden list, so if you were thinking of using remoting for that, think again.
Use web services.
I know you don't want to be polling, but I don't think you need to. Since you say all your units are on a single network segment then I suggest UDP for broadcast change notifications, essentially setting a dirty flag, and allowing the application to (re-)fetch on demand. It's still not reliable but it's easy and very fast because it's broadcast.
As others have said you don't need IIS, you can self-host. See ServiceHost class for details on how to do this.
I'd suggest using .NET Remoting. It's quite easy to implement and doesn't require anything else.
For me its is better to learn networking.. or the manual way of socket communication.. web services are mush slower because it contains metadata..
your clients and the servers can transform to multithreaded application. just imitate the request and response architecture. it is much easy to implement a network application like this..
If you just need a status update, you can use much simpler solution, such as simple tcp server/client messaging or like orrsella said, remoting. WCF is kinda overkill here.
One note though, if all your 50+ kiosk is connected via internet, then you might need use VPN or have an open port on each kiosk(which is a security risk) so that your server can retrieve status update from each kiosk.
We had a similiar situation, but the status is send to our server periodically, so we only have 1 port to protect/secure. The frequency of the update is configurable as to accomodate slower clients.
As someone who implemented something like this with over 500+ clients and growing:
Message Queing is the way to go.
We have gone from an internal developed TCP server and client to WCF polling and ended up with Message queing. It's the only guaranteed way to get data to and from clients and servers over the internet. As a bonus, many of these solutions have an extensive framework makeing it trivial to implement publish-subscribe, Send-one-way, point-to-point sending, Request-reply. Some of these are possible with WCF but it will involve crying, shouting, whimpering and long nights not to mention gallons of coffee.
A couple of important remarks:
Letting a process poll the clients instead of the other way around = Bad idea.. it is not scalable at all and you will soon be running in to trouble when the process is take too long to complete.. Not to mention having to handle all the ip addresses ( do you have access to all clients on the required ports ? What happpens when the ip changes etc..)
what we have done: The clients sends status updates to a central message queue on a regular interval ( you can easily implement live updates in the UI), it also listens on it's own queue for a GetStatusRequest message. if it receives this, it answers ( has a timeout).. this way, we can see overal status of all clients at all times and get a specific status of a specific client when needed.
Concerning bandwidth: kiosk usually show images/video etc.. 1Kb or less status messages will not be the big overhead.
I CANNOT stress enough that the current design you present will have a very intensive development cycle AND will not scale or extend well ( trust me, we have learned this lesson). Next to this, building a good client/server protocol for this type of stuff is a hard job that will be totally useless afterwards if you make a design error ( migrating a protocol is not easy)
We have built our solution ontop of ActiveMQ ( using NMS library c#) and are currently extending Simple Service Bus for our internal workings.
We only use WCF for the communication between our winforms app and the centralized service(s)