Introduction To Computational Media (ICM) : Week 10
Client/Server
Server
Processing now supports the creation of network servers. Servers can accept socket connections from clients and can send and receive data from them.
Here is a simple server program that can accept any number of client connections in order to receive and send x and y coordinates from any of them:
// Import the processing Net library
import processing.net.*;
// Declare our server object
Server myServer;
// X, Y and Previous X and Y coordinates
int x = 0;
int y = 0;
int px = 0;
int py = 0;
void setup()
{
size(500, 500);
// Instantiate our server object, have it listen on port 10001
myServer = new Server(this, 10001);
}
void draw()
{
// Create a client object if data is available to the server
// This object references a client connection
Client currentClient = myServer.available();
// If the client isn't null, meaning that the client has data
if (currentClient != null)
{
// Read the data from the client
String XandY = currentClient.readString();
// If the data is actually there
if (XandY != null)
{
println(currentClient.ip() + ": " + XandY);
// Split the data on the ",", returning an array of strings
String[] sXandY = split(XandY,',');
// Convert the array of strings into an array of ints
int[] iXandY = int(sXandY);
// If there is two values
if (iXandY.length == 2)
{
// Save our previous x and y values
px = x;
py = y;
// assign our new values to x and y
x = iXandY[0];
y = iXandY[1];
println(x + " " + y);
// Display a line from the previous x and y to the new x and y values
line(x,y,px,py);
// Send the new values to all of the clients
myServer.write(XandY);
}
}
}
}
Unfortunately, it is difficult to run a server as an applet (security restrictions and so on). Fortunately, you can run it from the Processing interface or from the "Export Application" functionality in Processing.
Server Example Application
Servers generally need to run on a machine that has a static IP address so clients know where to contact them. Also, Servers need to specify a network port on which to listen for a connection. Generally using a port in the 10000 or higher range is good practice as other more standard servers don't use them.
Client
Clients are programs that connect to servers to send and receive data.
Here is a client for the above server:
// Import the Net library
import processing.net.*;
// Declare a client object
Client myClient;
// X, Y and Previous X and Y coordinates
int x = 0;
int y = 0;
int px = 0;
int py = 0;
void setup()
{
size(500, 500);
// Instantiate the client, connect to "localhost" (the machine that this application is running on), port 10001
myClient = new Client(this, "localhost", 10001);
}
void draw()
{
// If there is data available from the server
if (myClient.available() > 0)
{
// Read the data and save in string
String XandY = myClient.readString();
// If the data isn't null
if (XandY != null)
{
println("Read: " + XandY);
// Split the data on the "," returning an array of strings
String[] sXandY = split(XandY,',');
// Convert our string array to an int array
int[] iXandY = int(sXandY);
// If we have two values
if (iXandY.length == 2)
{
// Set our previous x and y values to what we previously had saved in x and y
px = x;
py = y;
// Set our x and y variables to our new data
x = iXandY[0];
y = iXandY[1];
println(x + " " + y);
// Draw a line from the previous x and y to the new ones
line(x,y,px,py);
}
}
}
}
void mousePressed()
{
// When the mouse is pressed we send our X and Y coordinates to the server
myClient.write(mouseX + "," + mouseY);
}
Clients in the form of applets can only connect to servers that are running on the same machine that they are served from. Unfortunately, it is difficult to run a Processing server on the itp server so we are going to resort to using the client as an application as well.
Client Example Application
You can find out much more about both Clients and Servers from the Processing "Net" library documentation.
More Video/Image Processing
Dan O has a great series of examples working with video and images in a pixel by pixel manner: http://itp.nyu.edu/%7Edbo3/cgi-bin/ClassWiki.cgi?ICMVideo
Here is a more complex example that we can go through as well:
Remove Color from Video:
import processing.video.*;
Capture myImage;
color currentColor = color(255,255,255);
int threshold = 25;
int redColor = 255;
int blueColor = 255;
int greenColor = 255;
boolean reading = false;
void setup()
{
size(320,240);
frameRate(15);
myImage = new Capture(this,width,height,15);
}
void draw()
{
background(0);
//myImage.loadPixels();
reading = true;
for(int row=0; row<myImage.height; row++)
{ //for each row
for(int col=0; col<myImage.width; col++)
{ //for each column
//get the color of this pixels
//find pixel in linear array using formula: pos = row*rowWidth+column
color pix = myImage.pixels[row*myImage.width+col];
//find the difference
if (red(pix) > redColor - threshold
&& red(pix) < redColor + threshold
&& green(pix) > greenColor - threshold
&& green(pix) < greenColor + threshold
&& blue(pix) > blueColor - threshold
&& blue(pix) < blueColor + threshold)
{
myImage.pixels[row*myImage.width+col] = 0;
}
}
}
//myImage.updatePixels();
image(myImage,0,0);
reading = false;
}
void mousePressed()
{
currentColor = myImage.pixels[mouseY*myImage.width+mouseX];
redColor = (int)red(currentColor);
blueColor = (int)blue(currentColor);
greenColor = (int)green(currentColor);
}
void captureEvent(Capture video)
{
if (reading == false)
{
video.read();
}
}