Bandwidth Shaping in my C# application
Asked Answered
S

2

18

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?

Seurat answered 25/4, 2017 at 19:26 Comment(12)
AFAIK, traffic shaping would typically be done in a router using QoS.Vibrato
Do you have any control over the network? Or is it mobile? You say 'when you have low internet bandwidth'. Is that bc the application could be running in multiple locations, or because sometimes your internet runs slow? If you have control and it is a business network, you should be able to set different reserved bandwidth for different connections. So you could do this by splitting the API's and giving them both reserved amounts of bandwidth. Although if you don't have control over the network or the lib streaming, then it might be difficult to throttle it.Gleeful
@Amy I don't have access to the router configurations.Seurat
@AustinWinstanley no I don't have any control over the network. The internet runs slow.Seurat
can you split the code into 2 different projects and run the streaming one with less priority?Gleeful
@AustinWinstanley by 2 different projects you mean two separate processes? How can I set the priority of network traffic of a process in C#?Seurat
What is the relation between those two flows (video streaming vs. web services calls)? it is crucial in order to provide an appropriate solutionRedevelop
@Redevelop Web Service calls are used to manage the video stream. Missing some bytes in the latter are not important. But it happens the opposite, the former reaches timeout because of the latter.Seurat
What do you mean by fail? Do you get timeouts?Shift
@Shift yes timeout exceptionSeurat
@MatinLotfaliee what type of video you are transmitting? is it a live video or a recorded one? Genral principle for this kind of behaviour we go for the CDN as Youtube uses this principle as it keeps the same video with the replication and can provide you the video so that in low bandwidth , with minimal consumption of the resource , they can ablle to provide you with the videoBlancablanch
@Webruster it is live video.Seurat
J
6

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.

Jacobian answered 3/5, 2017 at 7:51 Comment(6)
He said he doesn't have control over the first library and it is a UDP video stream so I don't think it is a REST API nor do I think it goes to an IIS endpoint.Spell
He does not need to have any control over the first library. Just use it as is. Then when he needs to post his control messages his application uses rest api to tell the other service to send a message. From his comments I'm assuming that its just a streaming library that is embedded in a serviceJacobian
His question indicates that the library is part of his application, not the service.Spell
True that, If his application can't run as a service then IIS is not going to be workable. In Solution one it does not matter if its a winform,wpf or service.Jacobian
I prefer the first solution, because the application runs on a client not a server. Now the question is how can I embed the netlimiter? How can I write my own netlimiter?Seurat
I would consider it a major work to create a netlimiter. You could always bundle the other installation with it. But if this is an application that anyone could install and run. I think you should look at Mikes answer instead.Jacobian
S
4

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

Spell answered 4/5, 2017 at 8:31 Comment(6)
This is a very interesting solution. Have you any real use experience with this? With multiple streams I would be a little worried about doubling the amount of IO.Jacobian
I have built TCP based relay servers like this without running into any issues. Since you're sending to localhost it won't actually leave memory so it should be fairly minimal overhead I would think compared to everything else going on (decoding, encoding, etc), but you would have to test it out. You can write a simple relay server in ~15 lines of code and see how it affects your streams.Spell
I just checked CPU usage for one of our TCP relay apps written in C# while transferring data at 90Mbps and it is using ~5% of 1 CPU on a 3Ghz Xeon. Peak download speed is completely unaffected by going through the relay. Make of that what you will :)Spell
that's real good. Cpu is not interesting as the relay stuff should be light on that. I was wondering about the IO. My stuff is is streaming json and peaks on 20 MB/s (160 mbps) and I'm relaying parts of the stream to other servers and having problems. (vm's and SAN setup )Jacobian
That is an interesting solution. I think netlimiter do exactly the same thing.Seurat
I think CPU usage is the only interesting metric for a relay like this because sending to localhost doesn't actually use any real IO, it's just a memcpy as it moves through the OS network stack. It doesn't actually go through a network adapter or anything like that.Spell

© 2022 - 2024 — McMap. All rights reserved.