Hi!

Thanks for the patch. It's probably usefull for other stuff as well.
But I still have a problem.

If I post the request via telnet, I now get the missing 8 bytes by
reading from the channel. If I try to connect with Chrome via
WebSockets I still get nothing. Even if I'm feeding the request into
the telnet client with

telnet www.dcon.at 80 < ws_req.txt

I don't get the 8 bytes.

Maybe there is a race condition involved?

I know, that you can't start a thread per client when one expects
thousands of clients, but I think this would not be too hard to solve,
either by ns_proxy, tcl threads or the background module Tom and
Gustaf mentioned. I'll post my working solution with some benchmarking
as soon as I can connect with Chrome.

wiwo

On 1 Nov., 23:51, Jeff Rogers <[email protected]> wrote:
> It looks like my previous answer was, at best, partially right.  It
> looks lke [ns_conn channel] does in fact give you a read/write channel.
>     The effect of the missing content-length header is to discard any
> data that was read past the headers.   Attached is a patch
> (readahead.patch) to change that behavior.   The patch does 2 things:
> one, if the request includes 'upgrade' in the connection header, it
> doesn't read past the header (and doesn't throw away what it has read).
>   Two, when [ns_conn channel] is called, it will insert into the channel
> buffer any data that was already read (and not processed) on the socket.
>   Combined, it means that on an upgrade connection you can get the
> entire body, even if there was no content-length header sent.
>
> Also attached is a tcl file (index.tcl) that looks for an upgrade
> header, and when it gets one it forks a background tcl thread that
> echoes everything read back to the sender.  Every new request will get a
> new thread.  It also probably needs some tweaking to get a second
> request to work at all (since it's using shared channels to give the
> socket to the background thread).
>
> Importantly, this design of thread-per-connection is not scalable - your
> server will fall down and start crying once you start up a few dozen
> threads. (perhaps more; a really rough guess is that each tcl thread
> consumes 2M of memory before doing anything).  What you really want to
> do is to transfer each new websocket to a single existing background
> thread, but I'm not sure how to send stuff into another thread's event
> loop using the aolserver thread tools.  The standard tcl thread package
> is more powerful (with thread::send and thread::wait) but I don't know
> if those play nice inside AOLserver.
>
> -J
>
>
>
>
>
>
>
>
>
> wiwo wrote:
> > Hi!
>
> > I just tried the following:
>
> > I've been telneting to our server and was feeding it this request:
>
> > GET /test/ns_chan HTTP/1.1
> > Host:www.dcon.at
> > Connection: Upgrade
> > Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
> > Sec-WebSocket-Protocol: sample
> > Content-Length: 8
> > Upgrade: WebSocket
> > Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
> > Origin:http://example.com
>
> > ^n:ds[4U
>
> > Notice the "Content-Length" header. As Jeff told me, I've now been
> > able to output the 8 byte "body" of the request.
>
> > Then I was creating an ns_chan with:
>
> > set ch [ns_conn channel]
> > ns_chan create $ch $chan_name
>
> > and getting it back with:
> > set ch [ns_chan get $chan_name]
>
> > The I tried to write my WebSocket server handshake with:
>
> > puts $ch "
> > HTTP/1.1 101 WebSocket Protocol Handshake
> > Upgrade: WebSocket
> > Connection: Upgrade
> > Sec-WebSocket-Origin:http://[util::host]
> > Sec-WebSocket-Location: ws://[util::host]/[ns_conn url]
> > Sec-WebSocket-Protocol: sample
>
> > $ret
> > "
>
> > which showed up in the telnet client.
>
> > Then I tried to read again
>
> > set str [read $x 10]
> > ns_log notice $str
>
> > and typed 10 characters in the telnet client which showed up in the
> > log.
>
> > So far so good! I could now write my own proposal for changing the
> > WebSocket Client and make Google and Apple change their
> > implementations of the protocol. Unfortunately my relationship with
> > Steve and Larry cooled down the last few months, so this could take a
> > while :-)
>
> > Or I could get my hands dirty and mess around with the code in
> > driver.c.
>
> > As far as I can see, the crucial code is in
> > static ReadErr SockReadLine(Driver *drvPtr, Ns_Sock *sock, Conn
> > *connPtr)
> > somewhere at line 1878 where the content length is read. I could
> > simply check for the "Upgrade: WebSocket" header and set the length to
> > the magic number of 8.
>
> > Of course I have no idea when I'm talking about AOLserver C code, but
> > maybe someone with a clue can give me his/her thoughts here.
>
> > wiwo
>
> >> I'm pretty sure it's not possible to implement websockets in AOLserver
> >> without some C-level work, and if you could you wouldn't want to.
>
> >> You can't, because the driver reads the entire request, including
> >> content, before handing it off to the connection thread.  And it only
> >> reads past the headers if there is a 'Content-length' header.  (You can
> >> hook into the content-reading with a read filter, but that won't help
> >> because with no content-length it won't ever try to read it).
>
> >> You wouldn't want to, because you would attach a conn thread to a single
> >> persistent websocket, which would severely limit how many you could
> >> handle.  Doing it as a background tcl thread would be little better,
> >> because you'd still need a thread per connection.  Handling all
> >> websockets with a single background thread using tcl event handling
> >> would work, if you could get read/write handles to the sockets (which
> >> currently you can't - I think the background delivery patch only creates
> >> a writable channel).
>
> >> So what else can you do?
>
> >> For starters, you could check the current state of naviserver - I'm not
> >> up to date on what has changed there lately, but a r/w version of
> >> 'ns_conn channel' might have been implemented.
>
> >> Otherwise, you need to get your hands dirty in the C code and implement
> >> 'Upgrade' handling.  If you do take this approach, I'd suggest
> >> implementing just enough logic to transfer control elsewhere - that is,
> >> in the driver, don't try to handle websockets, rather set it up to
> >> recognize the upgrade protocol ("Connection: upgrade" and "Upgrade:
> >> something" headers) and call a registered procedure and forget about the
> >> connection (leaving it to the registered proc to actually do anything
> >> with it).
>
> >> -J
>
> >> --
> >> AOLserver -http://www.aolserver.com/
>
> >> To Remove yourself from this list, simply send an email to 
> >> <[email protected]> with the
> >> body of "SIGNOFF AOLSERVER" in the email message. You can leave the 
> >> Subject: field of your email blank.
>
> > --
> > AOLserver -http://www.aolserver.com/
>
> > To Remove yourself from this list, simply send an email to 
> > <[email protected]> with the
> > body of "SIGNOFF AOLSERVER" in the email message. You can leave the 
> > Subject: field of your email blank.
>
> --
> AOLserver -http://www.aolserver.com/
>
> To Remove yourself from this list, simply send an email to 
> <[email protected]> with the
> body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: 
> field of your email blank.
>
>  readahead.patch
> 1KAnzeigenHerunterladen
>
>  index.tcl
> < 1 KBAnzeigenHerunterladen


--
AOLserver - http://www.aolserver.com/

To Remove yourself from this list, simply send an email to 
<[email protected]> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: 
field of your email blank.

Reply via email to