I have a C# application that uses a native library that sends video to other IP over the internet using UDP. I have no traffic control over that library.
My application also calls web services of another server using WebRequest that I have control over them.
The problem is:
When I have low internet bandwidth, the video stream uses all of my bandwidth. So I fail to get responses from my web service methods during that time.
Is there any way to prioritize the WebRequest or save some bandwidth for them so that I could get responses safely?
I do not know of any method in C# that can prioritize traffic in this way.
I know this is not quite a stack overflow kind of answer but this is how I have handled streaming services not killing the bandwidth in my environments when you have no proper networking infrastructure access which is the “proper” way of doing this.
When you conclude on what method you are going to use I recommend you take a look at https://superuser.com which should be able to answer any stumbling blocks you will have in implementing the solution.
Solution One.
Split into 2 services and communicate through REST API in each service or a database poll.
Then use a network limiting program to prioritize the traffic of one of the services.
https://www.netlimiter.com/ and https://netbalancer.com/ are examples of software that can do this but there are many more.
Advantage: You will have dynamic throttling of your streaming service.
Drawbacks: You will have to have another program running on the server and its definitely not free.
Solution Two.
Use IIS, There’s a built-in throttle in IIS https://www.iis.net/configreference/system.applicationhost/weblimits and look at maxGlobalBandWidth.
Then you have 2 websites that communicate through REST or a database poll.
Advantage: Simple out of the box solution.
Drawbacks: your limits are not dynamic and are in your config file.
Note that you should not use this method if your internet networking speed varies much.
It is pretty straightforward to setup a UDP relay server for simple UDP streams, which you can then use to throttle the traffic as needed. You can put this in your application so everything is self-contained and your relay server is aware of when web requests are made. Create one UdpClient to receive traffic on 127.0.0.1 and have the video streaming library connect to that instead of your actual server. Then create another UdpClient that will relay the traffic to the actual destination that you normally connect to with the library.
You can limit bandwidth any number of ways with this method and how you do it will ultimately depend on your requirements. You can just pause forwarding of UDP frames whenever you start a web request and resume forwarding them after you get a response if pausing is acceptable. If not then you can track average UDP frames/second as you are relaying data and dynamically rate limit to 50% (or whatever) of that by inserting appropriate delays into your relay server while you have a web request pending.
You can look here for an example of a simple UDP relay server implementation for DNS requests, the basic principle would be the same:
https://social.msdn.microsoft.com/Forums/en-US/ce062e62-395f-4110-a4dd-3e9ed3c88286/udp-relay-server?forum=netfxnetcom
Related
I am trying to use web sockets to allow two Windows services on different machines to pass data back and forth. Almost all the examples or information I have found are about using web sockets for Client/Server Side communication. I am having trouble figuring out how to set this up. I have considered using WebSocketHost as apart of Microsoft.ServiceModel.WebSockets, but then I am unsure how to bind it to a local port and not a URL.
Does any one have any suggestions
Thanks
I am trying to use web sockets to allow two Windows services on different machines to pass data back and forth.
You can open sockets on both machines using WebSockets as you found. The examples mention clients and servers because this is the typical usage, however the API really doesn't care. As long as each side has a listener and a sender they can communicate.
However I would like to mention that this isn't as simple as it sounds because both machines aren't always available. Sometimes one or the other is busy or the network is blocked or something else is going on, or the listener is too busy to respond right away, so you're going to end up needing some sort of queuing on both sides.
If you're doing a process based operation where one side tells the other "I want X" and it's a big operation like producing a document, I've found it much more resilient to build a queue in a database and toss the request in there, then wait for the other side to update the record to say it's done.
If they're smaller, faster requests, MSMQ would be more appropriate if you have it available.
However back to your original question, if you want to use it, any of the client-server examples should work just fine. The API doesn't care.
You can use SignalR Self-Host you really don't want to create your own WebSockets framework since this this will take a long time.
Here is a link on how to start a OWIN server in Windows services.
Hosting WebAPI using OWIN in a windows service
And how to set signalR in self host
Tutorial: SignalR Self-Host
You can accomplish this with Memory Mapped Files.
Inter-Process Communication with Memory-Mapped Files
I am in the need of creating a C# program that will run on couple of our local Windows client machines. These 'client' programs will have to take commands from a 'admin' program run on another machine.
The commands could be to reboot the client computers, return some local information about IP address etc back to the 'admin' program.
But how to accomplish this? I know a little about WCF but is that the right way to go?
If I go with WCF I will then have to make the client programs run a service method, like every second, to check for new commands. With sockets I establish a 'direct' connection and the client just waits for a command to receive - isn't that correct understood?
Which way would be the right way for me to go?
We are talking about ~10 clients and I want a maximum delay (send command - receive info back) of 1 second.
Any hints would also be appreciated.
Best regards
Duplex WCF server. Basically, the clients all connect into the server (so only 1 server), and the server uses its duplex channel to call back to the clients whenever it needs to. No polling, scales well, etc. The most headache you'll need to deal with is to set a long timeout in case that you don't send anything for a while so that the channels time out.
WCF will end up being much simpler in the end.
A couple of links:
http://msdn.microsoft.com/en-us/library/ms731064.aspx
and
http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF
I hope those help.
You can make WCF clients act as servers and with command & control program connect to them that is no problem. Go for WCF if you don't want to mess with ugly stuff that sockets can bring. WCF can be configured nicely in app.config, and you can make it really self hosted command line application even so no need for IIS server. Configuration will be then resuable and easier to maintain.
You could use .NET Remoting which can provide a "push" backchannel from the server to the client (using "callbacks"). It does not need a 2nd TCP connection in the other direction so you don't need to mess with client's firewalls and routers.
Remoting is considered kind of obsolete but it has its places.
In any case I would not use a WCF polling technique. That leads to bad latency and a DDOS situation for the server.
If you can make the clients open a port then hosting a WCF service there is probably the best idea.
I would recommend a socket implementation as in the long run it probably gives you greater flexibility. You could create this from scratch yourself using the socket namespace. As an alternative you could use an off the shelf network library solution. Checkout lidgren and NetworkComms.Net.
Disclaimer: I'm a developer for NetworkComms.Net.
With the small number of machines and modest performance requirements you mentioned, I think WCF would end up being easier than sockets.
You might look into Duplex WCF. I've never used it, and WCF has given me headaches in the past any time I've needed anything unusual, but it's for the sort of problem you're talking about.
If all the machines are on one network, here's one creative alternative loosely inspired by message queues: you could use a database table as a place where messages appear and get read by clients at their leisure. The clients could just query it and say: get me all messages where MessageID > LastReceivedMessageID.
The downsides of that last approach is that (a) you're still doing polling although your database server should be able to handle it and (b) if you might ever need this outside of your network, you would need a VPN or a new solution.
you could use MSMQ... couldn't be easier to implement
http://msdn.microsoft.com/en-us/library/windows/desktop/ms711472(v=vs.85).aspx
I use MSMQ for a number of similar applications. Works perfectly.
I have the same dilemma as the one who posted this topic, Real-time communication with WCF
except that my problem is not about games programming. I would like to know what's the best method to use to be able to have a real time communication in between two windows applications (server-client). I am using visual c++/c# to date and i would like to be able to display all the Feeds that are being received by my server to the client in real time.
I have started trying to use .NET remoting but in my continuous research, it appears that it will use SOAP-http, and might affect the speed of the communication. My server and client will communicate using the internet and .NET remoting does not permit the use of TCP Channel when communicating in between a firewall or the internet.
Your inputs will be greatly appreciated.
I guess it depends on your escenario, if you want "real-time" and you are willing to lose some packages in the process you are better with UDP, take a video conferencing tool for example, by the time you recover your slow packages you will have to move and display the next frame in the video or audio; that is a good example for the use of UDP. This is the reason why UDP is much faster than TCP.
If however, you are not willing to lose a single bit of your message, then TCP was made for you because if you lost a package the protocol will request it again to have your complete message as complete as possible.
Additionally it depends on the way the communication is being sustained, is the information flowing from one to many?, from many to many?, one to tone?
Take NetNamedPipeBinding for instance, this will be much faster process, but is only deployed in a single machine but accross processes. Whereas NetMsmqBinding will help you to build queues and it will be amazingly reliable and scalable for scenarios where your load will be a massive number of connections.
In the end, it all boils down to your concrete escenario and your business goals.
Hope it helps
If you are willing to do your own message parsing, you can use standard TCP sockets with the TcpClient and TcpListener classes. If your data is already a serializable object, you could serialize it into a text stream and just send it over the socket, deserializing it on the client side.
To get it to work over the internet, the server needs to have the port forwarded on your router, the client would just attach to the server's public IP. You would obviously need to add an exception in your firewall for this port as well.
The biggest problem with WCF and large data is setting up the streaming, by default WCF sends everything at once, which isn't practical for large files.
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)
I hope someone can guide me as I'm stuck... I need to write an emergency broadcast system that notifies workstations of an emergency and pops up a little message at the bottom of the user's screen. This seems simple enough but there are about 4000 workstations over multiple subnets. The system needs to be almost realtime, lightweight and easy to deploy as a windows service.
The problem started when I discovered that the routers do not forward UDP broadcast packets x.x.x.255. Later I made a simple test hook in VB6 to catch net send messages but even those didn't pass the routers. I also wrote a simple packet sniffer to filter packets only to find that the network packets never reached the intended destination.
Then I took a look and explored using MSMQ over HTTP, but this required IIS to be installed on the target workstation. Since there are so many workstations it would be a major security concern.
Right now I've finished a web service with asynchronous callback that sends an event to subscribers. It works perfectly on a small scale but once there are more than 15 subscribers performance degrades considerably. Polling a server isn't really an option because of the load it will generate on the server (plus I've tried it too)
I need your help to guide me as to what technology to use. has anyone used the comet way with so many clients or should I look at WCF?
I'm using Visual C# 2005. Please help me out of this predicament.
Thanks
Consider using WCF callbacks mechanism and events. There is good introduction by Juval Lowy.
Another pattern is to implement blocking web-service calls. This is how GMail chat works, for example. However, you will have to deal with sessions and timeouts here. It works when clients are behind NATs and Firewalls and not reachable directly. But it may be too complicated for simple alert within intranet.
This is exactly what Multicast was designed for.
A normal network broadcast (by definition) stays on the local subnet, and will not be forwarded through routers.
Multicast transmissions on the other hand can have various scopes, ranging from subnet local, through site local, even to global. All you need is for the various routers connecting your subnets together to be multicast aware.
This problem i think is best solved with socket.
Open a connection to the server, and keep it open.
Could you have a slave server in each subnet that was responsible for distributing the messages to all the clients in the subnet?
Then you could have just the slaves attached to the central server where the messages are initiated.
I think some of you are vastly overthinking this. There is already a service built into every version of Windows that provides this exact functionality! It is called the Messenger service. All you have to do is ensure that this service is enabled and running on all clients.
(Although you didn't specify in the question, I'm assuming from your choices of technology that the client population of this network is all Windows).
You can send messages using this facility from the command line using something like this:
NET SEND computername "This is a test message"
The NET SEND command also has options to send by Windows domain, or to specific users by name regardless of where they are logged in, or to every system that is connected to a particular Windows server. Those options should let you easily avoid the subnet issue, particularly if you use domain-based security on your network. (You may need the "Alerter" service enabled on certain servers if you are sending messages through the server and not directly to the clients).
The programmatic version of this is an API called NetMessageBufferSend() which is pretty straightforward. A quick scan of P/Invoke.net finds a page for this API that supplies not only the definitions you need to call out to the API, but also a C# sample program!
You shouldn't need to write any client-side code at all. Probably the most involved thing will be figuring out the best set of calls to this API that will get complete coverage of the network in your configuration.
ETA: I just noticed that the Messenger service and this API are completely gone in Windows Vista. Very odd of Microsoft to completely remove functionality like this. It appears that this vendor has a compatible replacement for Vista.