Maarten Koopmans napsal(a):

Hi,

that stuff looks really excelent! Strange thing is, that even if the 
code looks pretty straightforward, I don't understand every detail of 
it, but that is what there are questions for :-)

>  handler: func [port [port!] state [word! error!] /local tmp cmd] [
>      if error? :state [print mold disarm state return true]
>      switch state [
>          connect [
>              ; do HTTP request
>              insert port {GET /fg/anen.jpg HTTP/1.0^M^JHost: 
>www.3dwallpaper.com^M^J^M^J}
>  
>
That one - raw tcp stream, right? I wonder if some kind of dialect (set 
of functions) could be produced to handle that ugly MJMJMJ and GET 
commands etc., as e.g. read/custom allows. Just a theoretical question, 
if it even would be worth it, nothing more

>              false
>          ]
>          read    [false]
>          write   [false]
>          close   [
>              ; get data
>              data: copy port
>  
>
OK, so that one does not block right? And it is so just because we are 
inside handler function, which is being called once some event happens 
on port, so theoretically some data should be awaiting us. I just wonder 
it comes in 'close switch part. We get here once other side closed 
connection? So if I understand it correctly, we read it in parts, but 
'read part does nothing, rebol is internally buffering data (how large 
data is rebol able to buffer easily that way?) and once other side 
closes connection, we can read it by copy (which will not block, even if 
no-wait was not used), and whole data is being read out of the port 
buffer at once? Well, I hope I am still on track :-)


>Now for a simple server:
>
>First we add a listening server port to the system/ports/wait-list, like:
>  
>
Why? Is that needed? Am I right thinking it is because of View? Once 
View starts, it adds event-port into wait-list and if we want to process 
all various events properly, we have to go via wait-list?

>  either error? try [listen: open/no-wait tcp://:8000] [
>      port: open async://localhost:8000
>      port/awake: do handler
>  
>
Above code somehow escapes my understanding :-) So if we are not able to 
open listen port (because e.g. we are already listening), we open 
connection on localhost to that port? What is that good for?

>  ] [
>      listen/awake: func [l /local p] [
>          print "Got connection."
>          p: first listen
>          remove find system/ports/wait-list listen
>          port: make port! [scheme: 'async sub-port: p]
>  
>
that is something I never understood. That is why I was not able to 
further more deeply adapt Sterling's proxy.r script. It contained way 
too much port subport and proxy (as a port :-) stuff for my brain to 
swallow :-) 'p is assigned first connected client. It does not contain 
any sub-port, yet it can communicate. IIRC someone said, that sub-port 
contains real communication port. But I don't understand the difference, 
even without sub-port, I am able to send data here and there and I can 
see it buffered in port/state. What is sub-port then?

>          open port
>          port/awake: do handler
>          false
>      ]
>      insert tail system/ports/wait-list listen
>      port: none
>  ]
>
>  
>
so overall - it is clever - once first event happens on listening port, 
we remove it from wait-list, reassign handler and insert it back into 
wait-list. That sounds like nice constructor/init method in OOP :-)

>As you can see, its awake function convert the accepted port to an async
>one and sets the handler. So what is the handler then?
>
>  handler:  [ use [ buffer ][
>      
>      buffer: copy []
>      
>      func [port [port!] state [word! error!] /local tmp cmd] [
>      if error? :state [print mold disarm state return true]
>      switch state [
>          connect [print "Connected." false]
>          read    [
>              append buffer copy port
>              while [tmp: find buffer newline] [
>                  cmd: copy/part buffer tmp
>                  remove/part buffer next tmp
>                  do-cmd cmd
>              ]
>              false
>          ]
>          write   [false]
>          close   [print "Peer closed connection." close port true]
>      ]
>    ]
>    ]
>  ]
>
>The first thing to notice is the fact that we use 'use to create a context
>that returns a function! value. This function (and only this particluar
>value) has access to its buffer. By doing the handler block in the server
>part above, every accepted port gets a copy of theis function value with
>its own "static" buffer space. A very simple but effective trick.
>  
>
cool!

Thanks for your tutorial, very educative!

-pekr-

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.

Reply via email to