I find this/last week to be a milestone in the rebol world.

we can now start an async xml-rpc server by browsing a remote web page.

Our world is getting soooo coool.


we now even have a tutorial to understand the async protocol... I am thinking of using 
it for my liquid net module.


-MAx
---
"You can either be part of the problem or part of the solution, but in the end, being 
part of the problem is much more fun."
 

> -----Original Message-----
> From: Maarten Koopmans [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, March 03, 2004 1:36 PM
> To: [EMAIL PROTECTED]
> Subject: [REBOL] Re: The REBOL async:// tutorial - take 1
> 
> 
> 
> First, realize that we didn't knock this off in two 
> afternoons. So it is 
> OK to hit your head against the wall.
> 
> >> 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
> >
> >  
> >
> You could use the builtin crlf as a replacement.
> 
> >>             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 :-)
> >  
> >
> That copy doesn't block, because it gets diverted to the copy in the 
> async:// handler IIRC. Also, async:// does all low-level input and 
> output buffering.
> And async opening + async dns://
> 
> >>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?
> >
> >  
> >
> It can be done many ways indeed. Pick your own example.
> 
> >> 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?
> >
> >  
> >
> Gabriele? I missed it, it looks like setting up a tunnel to me.
> 
> >> ] [
> >>     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?
> >
> >  
> >
> The real connecttion :-)  Anyway... this is the way to go. If 
> you take a 
> look at the renewed xml-rpc you will find an add-server function that 
> abstract this away nicely.
> 
> >>        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 :-)
> >
> >  
> >
> Go clean your mouth!
> 
> >>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!
> >  
> >
> I know! That's why I thought I'd share it with you all.
> 
> >Thanks for your tutorial, very educative!
> >
> >  
> >
> Put it to work.  async:// is so clever. Carl explained it 
> Eastern 2003 
> in a private chat, then I started experimenting and Gabriele 
> turned that 
> into async://
> It took some more experimenting, and finally we have a tutorial.
> 
> --Maarten
> -- 
> To unsubscribe from this list, just send an email to
> [EMAIL PROTECTED] with unsubscribe as the subject.
> 
> 

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

Reply via email to