//
// SocketSlaveDisplay.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.net.*;
import java.io.*;
import java.rmi.RemoteException;
import java.util.*;
import visad.browser.*;
/** A SocketSlaveDisplay server wraps around a VisAD display, providing support
for stand-alone remote displays (i.e., not dependent on the VisAD packages)
that communicate with the server using sockets. For an example, see
examples/Test68.java together with the stand-alone VisAD applet
visad.browser.VisADApplet, usable from within a web browser. */
public class SocketSlaveDisplay implements RemoteSlaveDisplay {
/** debugging flag */
private static final boolean DEBUG = false;
/** the default port for server/client communication */
private static final int DEFAULT_PORT = 4567;
/** list of control classes that support socket-based collaboration */
private static final Class[] supportedControls = {
GraphicsModeControl.class, ContourControl.class
};
/** the port at which the server communicates with clients */
private int port;
/** the server's associated VisAD display */
private DisplayImpl display;
/** flag that prevents getImage() calls from signaling a FRAME_DONE event */
private boolean flag;
/** array of image data extracted from the VisAD display */
private byte[] pix;
/** height of image */
private int h;
/** width of image */
private int w;
/** the server's associated socket */
private ServerSocket serverSocket;
/** vector of client sockets connected to the server */
private Vector clientSockets = new Vector();
/** vector of client sockets' input streams */
private Vector clientInputs = new Vector();
/** vector of client sockets' output streams */
private Vector clientOutputs = new Vector();
/** vector of client socket ids */
private Vector clientIds = new Vector();
/** thread monitoring incoming clients */
private Thread connectThread = null;
/** thread monitoring communication between server and clients */
private Thread commThread = null;
/** whether the server is still alive */
private boolean alive = true;
/** next available client ID number */
private int clientID = 0;
/** this socket slave display */
private final SocketSlaveDisplay socketSlave = this;
/** contains the code for monitoring incoming clients */
private Runnable connect = new Runnable() {
public void run() {
while (alive) {
try {
// wait for a new socket to connect
Socket socket = serverSocket.accept();
if (!alive) break;
if (socket != null) {
synchronized (clientSockets) {
// add client to the list
clientSockets.add(socket);
// add client's input and output streams to the list
DataInputStream in =
new DataInputStream(socket.getInputStream());
clientInputs.add(in);
DataOutputStream out =
new DataOutputStream(socket.getOutputStream());
clientOutputs.add(out);
// assign client an ID number
out.writeInt(++clientID);
clientIds.add(new Integer(clientID));
}
}
}
catch (IOException exc) {
if (DEBUG) exc.printStackTrace();
}
}
}
};
/** contains the code for monitoring server/client communication */
private Runnable comm = new Runnable() {
public void run() {
while (alive) {
boolean silence = true;
Object[] sockets, inputs, outputs, cids;
synchronized (clientSockets) {
sockets = clientSockets.toArray();
inputs = clientInputs.toArray();
outputs = clientOutputs.toArray();
cids = clientIds.toArray();
}
for (int i=0; i 0) {
silence = false;
// receive the client data
int sid = in.readInt();
if (DEBUG && sid != cid) {
System.err.println("Warning: client #" + cid + " believes " +
"its ID number is " + sid);
}
int eventType = in.readInt();
if (eventType == VisADApplet.REFRESH) {
// send latest display image to the client
updateClient(socket, in, out);
// send latest supported control states to the client
for (int j=0; j 0) {
socket = (Socket) clientSockets.elementAt(0);
in = (DataInputStream) clientInputs.elementAt(0);
out = (DataOutputStream) clientOutputs.elementAt(0);
}
}
if (socket == null) break;
else killSocket(socket, in, out);
}
// shut down server socket
try {
serverSocket.close();
}
catch (IOException exc) {
if (DEBUG) exc.printStackTrace();
}
}
}
Ads help maintain this website.