views:

39

answers:

3

This is driving me nuts and because it's a combination of various technologies together I have a hard time tracking the problem.

Scenario

I wrote a tiny HTTP server that serves .flv files; these flv files are encoded on the spot. The flv files are encoded with adobe's screencodec (I started with libflv but that was too buggy so I ended up implementing my own flv encoder). For the problem below it doesn't matter which codec I use or if I serve plain flv files instead of on-the-spot generated ones (the problem also occurs if I just send 12 h264 encoded files). I also have a swf that I coded in as3. The as3 opens 12 connections to my server and requests 12 different flv's and just displays them as 12 different videos on the page. I tested the setup with Firefox and chrome and am using the latest flash client (version 10). The HTTP server is pseudo streaming those files; e.g. it tells the client the file is of mime type video/x-flv, tells the filesize is 2GB and just starts streaming. For sake of completeness here's a header it generates:

HTTP/1.1 200 OK
Content-Type: video/x-flv
Accept-Ranges: bytes
Content-Length: 2147483647
Date: Mon, 28 Jun 2010 12:53:09 GMT
Host: localhost
Keep-Alive: timeout=100000, max=100
Connection: Keep-Alive
Server: Foobar

So what happens is that the swf asks for a flv, the server gets the request, starts encoding a flv and starts sending that bytestream over the open tcp connection. Both the client (Browser) and the server are running on localhost. The server will also serve crossdomain.xml stuff (both on port 843 as adobe wants it) as well as on port 80. Flash indeed asks for the crossdomain file and in the file I allow everything. In flash/CS4 I enabled all settings that allow the swf to do its networking stuff.

This all works fine except that flash stops after the 6th flv. If I close the socket after I send a couple of frames then the swf will happily display all 12. But if I keep the socket open (which is the whole point if I want to keep serving) it just quits after six Netstream connections. Ergo, it will send 6 requests to the server and then stops. On the as3 side I tried all kind of things (using one NetConnection, tweeking the buffertime) but nothing seems to help.

The as3 code looks like this:

var connection = new NetConnection();
connection.connect(null); 
var stream = new NetStream(connection);
var listener:Object = new Object();
listener.onMetaData = onMetaData;
listener.onCuePoint = onCuePoint;
// stream.checkPolicyFile=true;
stream.client = listener;
stream.bufferTime = 0; 
var video = new Video(640,480);
video.attachNetStream(stream);
// connection.maxPeerConnections = 32;
stream.play("http://localhost:80/" + n +".flv"); 

And I loop over this code 12 times to generate the requests.

So what gives; why does flash stop after the 6th connection. I google'd whole week trying to find whether flash has some maximum on either its sockets or NetConnections or NetStreams but neither Adobe nor anyone else seems to mention this anywhere.

Another odd thing that I found out is that the 6 open connections are only on a per-port basis, so I can open 6 flv's on port 80 and another 6 on port 81 ... I could probably rewrite my implementation to serve on different ports but that would be a pain (especially considering people have firewalls) and it just doesn't make sense.

Either I am doing something wrong in as3, or flash does have some limitation that I am not aware of and that's not documented, or maybe there's some problem in my HTTP headers.

Anybody got a clue what might be the problem? I am really running out of options, I've been fiddling with this for a week now and it's driving me nuts!

Thanks a lot, Woporo

A: 

I believe that when Flash opens an HTTP connection, it goes through the browser's connection mechanisms which has limits to the maximum number of concurrent persistent connections to a single host, as well as total concurrent persistent connections.

You could test this theory by increasing the maximum number of connections in Firefox by going to the config URL about:config and filtering on "network.http". There should be some settings such as "network.http.max-persistent-connections-per-server" that you can tweak.

If this turns out to be the limiting factor, then you may want to research other ways to serve your videos, such as RTMP which doesn't go through the browser for connections, but rather connects directly from Flash to your server.

Marc Novakowski
A: 

Thanks for the response Marc,

That was one of the things I initially also thought but that doesn't seem to be the problem. You are right that flash goes through the browser for the actual connection. Chrome has indeed a hard limit of 6 connections on a per-host basis. Firefox however is default set to 15 (and I even changed it up to 32 through the about:config) but that doesn't help :(

One other problem is that running the swf file in CS4 itself (e.g. without running it in a browser is unstable as hell - it either crashes CS4 or just randomly loads two, four or no flv's) ... sigh :)

RTMP is certainly another option but that would mean I'd have to whip up an RTMP implementation (I don't want to use Red5) and it seems a little going overboard if in theory serving through a simple HTTP mechanism should do the trick.

Thanks a lot for the tip!

Cheers, Woporo

Woporo
A: 

Marc,

Dammit - you were right! ;-)

I rechecked my settings just to be sure and saw another setting. I initially changed network.http.max-connections-per-server but I should have also changed network.http.max-persistent-connections-per-server ... sigh :)

You're a life-saver! thank so much for that tip!

(since I am clearing my cache all the time to do the tests I also seem to have deleted the cookie for stackoverflow so I can't edit my previous response ...)

Cheers, Woporo

Woporo
No problem. And welcome to Stack Overflow. BTW, you may want to add comments such as these as comments to my answer rather than as new answers to your own question. I just makes things easier to follow since answers are always displayed in random order (and these aren't really answers to your question). Don't forget to mark answers as "accepted" if it does solve your problem.
Marc Novakowski