We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpOther Libraries › Net Library: Server Object: "Data Receive" event
Page Index Toggle Pages: 1
Net Library: Server Object: "Data Receive" event? (Read 1425 times)
Net Library: Server Object: "Data Receive" event?
Jun 8th, 2009, 5:57pm
 
Hello!

FOREWORD

I am a beginner/mediate programmer (mainly functional programming, only barely using OOP) and I have never worked with inter process communication, nor TCP sockets before, neither am I familiar with the theoretical background of server/client principles in programming.

Hence my expectations and imaginations may be absurd, and the implementation of the Processing Net Library anyhow compliant to the general theoretical server/client model. Or otherwise, maybe there is indeed scope for improvements concerning the Net library. In the former case I would very much welcome advise on how to implement correctly, and in the latter case, a possible work around to achieve my objective.

PROJECT

In a current project, I run a PHP script in the CLI version in an endless loop. This script downloads webcam pictures and saves them to disk, and after each successful download, notifies Processing via stream_socket_client(), that a new picture is ready, in a very simple protocol. One protocol message shall consist of a basic command to determine the operation mode of my receiving functions plus some parameters like filepath, x and y position for feeding my receiving functions with arguments. I want to separate the command and argument(s) with tab delimiters, and the messages with newline.

PROBLEM

In Processing I have found the Server object for receiving data from external applications. My intention was to have noLoop() for the draw() function, and only update my canvas by my functions, which are triggered by an event, which occurs when the server receives new data.

But there is no such event for the server object! All examples given in the processing.org/learning section and also on other places such as Dan Shiffman's examples at learningprocessing.com only show a myClient.available() and myClient.read() within the draw() loop, which I think is rather inefficient.

Originally I thought, that I will have a constant socket connection between the PHP client and the Processing Server, and get events whenever new messages are coming in. But I guess this continuous open TCP socket was an illusion, I will rather have to send one message per TCP socket session.

The only server related event available is serverEvent, which occurs when a new client connects. So my current approach is: When serverEvent() happens, run a delay(listeningTime), then disconnect my client with stop() and readString() what the client has sent me within that time. In the optimal case, the client has finished sending his data, and closed the connection before the server closes the connection when listeningTime is over. But by this I may loose precious time. Maybe the client has already closed the connection, but sadly there is no event when a client closes the connection with the server.

And on the other hand: What if the client has not finished sending his data within listeningTime? What if Processing is quite busy with its drawing action, while the PHP client sends to the Processing Server? Will the message be received, and the serverEvent function triggered?

A lot of questions, hints greatly appreciated!


CODE: PHP Client (Slowness Simulation)

$fp = stream_socket_client("tcp://localhost:10003", $errno, $errstr, $socketTimeout);
if (!$fp) {
 echo "$errstr ($errno)\n"; // Error msgs if the Processing Server is not running.
}
else {
 for ($i=0;$i<20;$i++) { // PHP needs 20/0.33 = ~7 secs until all data is sent.
   fwrite($fp,($i . "\n"));
   usleep(300000); // 300000 Nanosecs are 0.33 Secs.
 }
 fclose($fp); // Closes the connection.
}


CODE: Processing Server using the event serverEvent

import processing.net.*;

int port = 10003;  
Server myServer;    

void setup()
{
 size(400, 400);
 background(0);
 myServer = new Server(this, port);
}

void draw() {
}

void serverEvent(Server someServer, Client phpClient) {
 println("We have a new client: " + phpClient.ip());
 println("After 0000ms he sent:\n" + phpClient.readString());
 // null
 delay(2000);
 println("After 2000ms he sent:\n" + phpClient.readString());
 // Received until now: 1 2 3 4 5 6 // As PHP sends 1 msg every 0.33 secs.
 // If I killed the PHP script earlier, Processing receives all data from before PHP's death.
 // Received if PHP was killed after 1000ms: 1 2 3
 phpClient.stop();
 delay(1000);
 println("After 3000ms he sent:\n" + phpClient.readString());
 // null
}


Re: Net Library: Server Object: "Data Receive" event?
Reply #1 - Oct 7th, 2009, 8:33am
 
Hi Stefan, did you find a solution to the above issue. I want to do something similar and can't find anything about where to start in processing. I have done it lots in flash but never processing.

I want to send commands to a processing applet from a socket server or similar.

Cheers
James
Re: Net Library: Server Object: "Data Receive" event?
Reply #2 - Oct 8th, 2009, 12:13pm
 
Hello James!

You lucky one!
Yes I have found a solution back then.

The artistic result can be seen here: Julia Staudach - Welt Zeit Mosaik
Some time has passed already, and so I forgot the technical details.

My help is, what I could do for you in 70 mins (my maximum volunteer time today).

I attach the source code, with the parts irrelevant to networking or too closely project related stripped out, as my service contract stated to keep code private.

wcp.zip (Web Cam Patterns, the preliminary working title of WeltZeitMosaik) is temporarily available for download, as I couldn't figure out a way to attach the file to this discussion board.

WCP consists from wcpn (N-etwork app written in PHP run in the command line mode) and wcpd (D-rawing app written in Processing).

Plus I give you 2 important hints:

1) The net library of Processing has a bug. Do not open/close the socket, but leave it open throughout your whole runtime! I have yet not had the time to follow up my bug report. Hence simplified here:

If a client opens a socket, sends some data, closes it again, somehwere in the "java backend" the object stays alive, hence in the memory!
So after a few open/close sockets operations you get a memory overflow, and your processing app crashes!
This is buggy, because in a normal environment a server MUST be able to serve multiple clients, also returning clients.
In my situation, and hopefully also in yours; I could bypass the problem, by simply establishing the socket from the external app only once and then keep it open throughout the whole session.

2) If you write your own simple protocol, make sure your strings get properly trimed (from whitespaces) before putting them into processing variables/arguments. My inline code comment says it very clear:

// The BLOODY SNEAKY mistake of not removing the linebreak from the filepath, combined with a lousy error reporting from loadImage, did cost me 5 hours of my life.

All the best!

Page Index Toggle Pages: 1