Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: Problem: Talking from Rebol to Rebol via socket

From: petr::krenzelok::seznam::cz at: 22-Feb-2009 15:40

Robert M. Münch napsal(a):
> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA384 > > Hi, I made some small steps forward. At least I can send a message and get > an answer. But only once, I want this to run in a loop on the server and th > e client side. My actual code now is: > > === Server > rebol [] > > c-port: 12345 > listen: open/direct/no-wait join tcp://: c-port > > waitports: [listen] > > print "Listening:" > > ; wait until something happens > connection: wait waitports > if same? connection listen [ > print [tab "Connected"] > c-client: first connection > > forever [ > print [tab "Read message from c-side"] > print copy c-client > > print [tab "Send answer to c-side"] > insert c-client "r-side" > ] > ] > > === Client > rebol [] > > connection: open/direct/no-wait tcp://localhost:12345 > > forever [ > print "Sending to Rebol server" > insert connection "r-side-client" > > print "Receiving from Rebol server" > prin tab > while [data: copy connection] [prin data] > print newline > > ] > > === Problem > The client side can only send once because it get stuck in the WHILE loop a > lways getting some data from the server. The server loops, doesn't read any > thing from the client and immediately sends out the next message to the cli > ent. > > Is there a way that I can WAIT to "read a message" or "send a message"? I'm > missing a way to control/react on the communication direction flow. >
yes, there is. In async mode, you are responsible for "waiting for signal" - you have to do handshaking yourself. As I said in my previous email, be carefull, as you will run out from your data :-) So, look into your server. You waint for first connection. Good. Then you get your connection, enter forever loop, but you don't wait for the other side! Copy is not blocking, so it copies from the OS buffer (direct mode), and there is no data (empty string returned). Put wait c-client as first means of forever loop. The mindset is more difficult with async mode, and I sometimes too struggly a bit - where to wait, and where the wait is not necessary. Here's the mindset: wait port ; or wait/all [port1 port2 0:00:01], whatever ... while [not empty? data: copy port][append result data] remember, that one call to 'copy just reads out what is available at the given time. Sometimes ppl use copy/part, to read in some chunks. while not empty? will ensure you read out everything available. But you don't have to do that, as you can as well read it out "at next port visit" :-) If you want to look how to read data from many ports, Sterling's proxy script in archive was always a good inspiration for me, as it was able to open multiple connections, keep pairs of send/rcv ports stored, etc. Robert- here's my "multiserver" script I did for my friend some time ago. He was doing some embedded stuff and wanted me to catch data from devices, write them down to file, and log events. Not sure it will work for you, as I now translated it into english, including variables. Hopefully no bug there: ---------------------------- REBOL [ Title: "Multiserver" Version: 0.2 Author: "Petr Krenzelok" ] ;--- open listen server in an async mode listen-port: 9005 server: open/direct/no-wait/binary join tcp://: listen-port print ["Server running on port: " listen-port] ;--- set-up a wait-list - rebol will wait for every item contained ... wait-list: copy [] ;--- set-up a block to store open connections in there ... ;--- along with info - remote IP, port ... conn-list: copy [] ;--- insert time and server into wait-list insert wait-list 0.001 insert wait-list server ;--- forever= endless loop .... forever [ event-port: wait wait-list ;--- if more events, let's pick first one (maybe not needed?) if block? event-port [event-port: first event-port] ;--- has event happened on our listening server? (new connection request) ;--- if so, accept the connection, insert connection into wait-list if event-port == server [ ;--- accept connection ... time: now/time/precise connection: first server print join "New connection from: " [connection/remote-ip ":" connection/remote-port " at " time] ;--- append it into list of ports we wait for events (wait-list) insert wait-list connection ;--- append into our internal register of connections and its parameters insert conn-list reduce [connection connection/remote-ip connection/remote-port] write/append join %data- reduce [connection/remote-ip "-" connection/remote-port".txt"] join "New connection from: " [ connection/remote-ip ":" connection/remote-port " at " time newline "---------------------------------------------------------" newline ] ;--- uncomment to see the data in console ... ;probe connection ] ;--- if event received is not new connection, it might be data on already existing connection if found? conn-port: find conn-list event-port [ ;--- let's copy data ... time: now/time/precise data: copy event-port ;--- close request (none) or real data arriving? either none? data [ print join "Closing connection request from: " [conn-port/2 ":" conn-port/3 " at " time] ;--- Write close even request into file ... write/append join %data- reduce [conn-port/2 "-" conn-port/3 ".txt"] join newline [ "---------------------------------------------------------" newline "Closing connection request from: " conn-port/2 ":" conn-port/3 " at " time newline newline "=========================================================" newline newline ] close event-port remove/part conn-port 3 ][ ;--- if we are here, real data arrived ... print join "Data from: " [conn-port/2 ":" conn-port/3 " at " time] ;--- write data into file ... write/append join %data- reduce [conn-port/2 "-" conn-port/3 .txt ] to-string data ;--- uncomment to see data printed to console ;print mold to-string data ;print mold data ; data as binary, not string ] ;end 'either ] ;end 'if ] ;end 'forever