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.