SciCo JavaDoc

The Client files javadoc

The Server files javadoc


SciCo is a package of Collaborative tools aimed at scientific Problem Solving Environments.
It started by writing down a chat using serialized messages objects, therefore allowing a much more scalable infrastructure than only string messages.
A general view of the system can be seen on the following picture:

Because of the nature of this architecture, getting the ObjectInputStreams and ObjectOutputStreams to work was a little bit of a hassle;
the server sender thread (SSender_Thread, that calls the ObjectInputStream) is started before the server receiver thread (SReceiver_Thread, that calls the ObjectOutputStream) but is put on wait by the call to getting the next object off the ObjectQueue that has not yet notified until the receiver thread gets the name of the user from the receiver thread.

This made the declaration of a single ObjectOutput/InputStream work very unreliably (but some testing needs to be done since the modification of the ObjectQueue semaphores).
Therefore, the communication calls a new ObjectIn/OutputStream at each request on both sides and never closes it (because when a call is blocked on a readObject, it is pulling from the InputStream expecting the Object's header, if the stream is closed, it generates a type unknown exception for what is received from the readObject.

WhiteBoard objects and event handling

Drawing on a background image is done by :
1- creating an off-sreen image
2- painting the image (only once) on the off-screen image graphics context
3- performing any additional drawing on the off-screen image
4- painting the off-screen image to the screen's graphical context.

Here is some code for it:
constructor()
{
imageJPG=Toolkit.getDefaultToolkit("myimage.jpg");
MediaTracker media = new MediaTracker(this);
media.addImage(imageJPG,0);
}
void initialize()
{
image=createImage(width,height);
IG=image.getGraphics();
}
void paint(Graphics g)
{
if(!IS_BACKGROUND_PAINTED)
{
initialize();
IG.drawImage(imageJPG,0,0,this);
while(!media.checkID(0)) {IS_BACKGROUND_PAINTED=false;return;}
IS_BACKGROUND_PAINTED=true;
}
g.drawImage(image,0,0,this);
}
The whiteboard tools:

Pen,Line,Box,Text

Running the Server as a Service

Before running the SciCo server as a service the system outs and errs should be redirected to a log file.
File log = new File("/path/to/log");
FileOutputStream out = new FileOutputStream(file);
System.setOut(out);
System.setErr(out);
FireDaemon (at http://www.firedaemon.com is a free utility that does the same job as Windows resource kit's srvany/instsrv.
The service can be added by writing a Batch file:
@echo on
set SCICOSRV_HOME=e:\Vincent\work\SciCo\Server\class\
set JAVA_HOME=D:\JDK1.2.2
set JAVA_BIN=%JAVA_HOME%\bin
set _CLASSPATH=%CLASSPATH%
set _PATH=%PATH%
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\tools.jar
set CLASSPATH=%CLASSPATH%;%SCICOSRV_HOME%
set PATH=%PATH%;%JAVA_BIN%
%JAVA_BIN%\java.exe SciCo_Server
set CLASSPATH=%_CLASSPATH%
set PATH=%_PATH%
And adding this batch file as the actual executable in firedaemon.

The problem of this procedure is that the java process is orphaned.
Another more robust way to start the service is from the command line:
FireDaemon -i SciCoSrv \
e:\Vincent\work\SciCo\Server\class d:\jdk1.2.2\bin\java.exe "-cp \
e:\Vincent\work\SciCo\Server\class SciCo_Server" Y 1 0 Y N
Where the sequence Y 1 0 Y N stands for:
Restart ?
Mask (0-14)
Priority (0-3)
Interact ?
Autostart ?

Selecting the background image in the Canvas

Because of the security restrictions of Java applets, this feature can only be made available in the application version; (unless the applet gets signed.
The idea is to choose an image recognizable by Java Graphics (JPEG,GIF, or PNG) from the FileDialog, and send it to the server as a serialized object Sending the File object directly to the client unfortunately won't work (the client will not get the content of the file but only information on where to access the file on his local filesystem).
So in order to share the image, it has to be read byte by byte, sent accross to the server who will broadcast it to all the clients.
Upon receiving the file, each client will create a file from the raw data and display it as a background.
From the client selecting the file:
int length=theSelectedFile.length();
FileInputStream freader = new FileInputStream(theSelectedFile);
Serial_File sfile = new Serial_File(length,theSelectedFile.getName());
while((c=freader.read())!=-1)
	sfile.write(c);
sfile.write(-1);
freader.close();
SciCo_Client.sendObject(sfile);
At this point the Serial_File is sent to the server; who then broadcasts it to each client who in turn request to show it as a background image:
(Serial_File theReceivedFile)
File newfile = new File(theReceivedFile.getName());
FileOutputStream fwriter = new FileOutputStream(newfile);
while((c=theReceivedFile.read())!=-1)
fwriter.write(c);
Image image=Toolkit.getDefaultToolkit().getImage(newfile.getName());
displayIt();
The newfile creates a new file every time a file is received because apparently Toolkit's implementation of getImage somehow caches an image of a certain name so reusing the same name for evvery new file (saving space) did not work but this point needs to be clarified.
Another point is that the use of an FileInputStream/OutputStream as opposed to a FileReader/Writer not only allows this code to work (not corrupting the data) but is also much faster (because it is a bytestream).

Bugs & TODO

While running as an applet: Once the client disconnects he/she cannot reconnect yet,he/she has to refresh the browser by clearing the cache (Ctrl-Refresh)
The tools do not always respond properly to a selection action in the tools Panel (unknown reason)