More code, more code, more kibbles and code.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Client.java,v 1.1 2001/05/22 06:07:59 mdb Exp $
|
// $Id: Client.java,v 1.2 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.client;
|
package com.samskivert.cocktail.cher.client;
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ public class Client
|
|||||||
case CLIENT_FAILED_TO_LOGON:
|
case CLIENT_FAILED_TO_LOGON:
|
||||||
obs.clientFailedToLogon(this, cause);
|
obs.clientFailedToLogon(this, cause);
|
||||||
break;
|
break;
|
||||||
case CLIENT_CONNETION_FAILED:
|
case CLIENT_CONNECTION_FAILED:
|
||||||
obs.clientConnectionFailed(this, cause);
|
obs.clientConnectionFailed(this, cause);
|
||||||
break;
|
break;
|
||||||
case CLIENT_WILL_LOGOFF:
|
case CLIENT_WILL_LOGOFF:
|
||||||
@@ -191,7 +191,7 @@ public class Client
|
|||||||
// client observer codes
|
// client observer codes
|
||||||
static final int CLIENT_DID_LOGON = 0;
|
static final int CLIENT_DID_LOGON = 0;
|
||||||
static final int CLIENT_FAILED_TO_LOGON = 1;
|
static final int CLIENT_FAILED_TO_LOGON = 1;
|
||||||
static final int CLIENT_CONNETION_FAILED = 2;
|
static final int CLIENT_CONNECTION_FAILED = 2;
|
||||||
static final int CLIENT_WILL_LOGOFF = 3;
|
static final int CLIENT_WILL_LOGOFF = 3;
|
||||||
static final int CLIENT_DID_LOGOFF = 4;
|
static final int CLIENT_DID_LOGOFF = 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: Communicator.java,v 1.2 2001/05/22 21:51:29 mdb Exp $
|
// $Id: Communicator.java,v 1.3 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.client;
|
package com.samskivert.cocktail.cher.client;
|
||||||
|
|
||||||
@@ -10,8 +10,10 @@ import java.net.InetAddress;
|
|||||||
import com.samskivert.util.Queue;
|
import com.samskivert.util.Queue;
|
||||||
|
|
||||||
import com.samskivert.cocktail.cher.Log;
|
import com.samskivert.cocktail.cher.Log;
|
||||||
import com.samskivert.cocktail.cher.io.FramingOutputStream;
|
import com.samskivert.cocktail.cher.io.*;
|
||||||
|
import com.samskivert.cocktail.cher.io.ObjectStreamException;
|
||||||
import com.samskivert.cocktail.cher.net.*;
|
import com.samskivert.cocktail.cher.net.*;
|
||||||
|
import com.samskivert.cocktail.cher.util.Codes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The client performs all network I/O on separate threads (one for
|
* The client performs all network I/O on separate threads (one for
|
||||||
@@ -69,12 +71,59 @@ class Communicator
|
|||||||
* network connection. Also causes all communication threads to
|
* network connection. Also causes all communication threads to
|
||||||
* terminate.
|
* terminate.
|
||||||
*/
|
*/
|
||||||
public void logoff ()
|
public synchronized void logoff ()
|
||||||
{
|
{
|
||||||
|
// if our socket is already closed, we've already taken care of
|
||||||
|
// this business
|
||||||
|
if (_socket == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// let our reader and writer know that it's time to go
|
||||||
|
if (_reader != null) {
|
||||||
|
// if logoff() is being called by the client as part of a
|
||||||
|
// normal shutdown, this will cause the reader thread to be
|
||||||
|
// interrupted and shutdown gracefully. if logoff is being
|
||||||
|
// called by the reader thread as a result of a failed socket,
|
||||||
|
// it won't interrupt itself as it is already shutting down
|
||||||
|
// gracefully. if the JVM is buggy and calling interrupt() on
|
||||||
|
// a thread that is blocked on a socket doesn't wake it up,
|
||||||
|
// then when we close() the socket a bit further down, we have
|
||||||
|
// another chance that the reader thread will wake up; this
|
||||||
|
// time slightly less gracefully because it will think there's
|
||||||
|
// a network error when in fact we're just shutting down, but
|
||||||
|
// at least it will cleanly exit
|
||||||
|
_reader.shutdown();
|
||||||
|
}
|
||||||
|
if (_writer != null) {
|
||||||
|
// shutting down the writer thread is simpler because we can
|
||||||
|
// post a termination message on the queue and be sure that it
|
||||||
|
// will receive it. we do run the risk that it is in the
|
||||||
|
// middle of trying to send a message when we close the
|
||||||
|
// socket, but in theory the send will fail, it will complain
|
||||||
|
// and then it will cleanly exit. if we were uber paranoid
|
||||||
|
// about JVMs misbehaving on simultaneous close()/write(), we
|
||||||
|
// could wait here for the writer thread to exit, but that
|
||||||
|
// makes me even more nervous because I know that some JVMs
|
||||||
|
// don't handle Thread.join() properly (hopefully no one is
|
||||||
|
// still using those JVMs but one can never be sure)
|
||||||
|
_writer.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// close down our socket
|
||||||
|
try {
|
||||||
|
_socket.close();
|
||||||
|
} catch (IOException cle) {
|
||||||
|
Log.warning("Error closing failed socket: " + cle);
|
||||||
|
}
|
||||||
|
_socket = null;
|
||||||
|
|
||||||
|
// let the client observers know that we're logged off
|
||||||
|
_client.notifyObservers(Client.CLIENT_DID_LOGOFF, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues up the specified message for delivery to the server.
|
* Queues up the specified message for delivery upstream.
|
||||||
*/
|
*/
|
||||||
public void postMessage (UpstreamMessage msg)
|
public void postMessage (UpstreamMessage msg)
|
||||||
{
|
{
|
||||||
@@ -82,17 +131,46 @@ class Communicator
|
|||||||
_msgq.append(msg);
|
_msgq.append(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void startWriter ()
|
/**
|
||||||
|
* Callback called by the reader when the authentication process
|
||||||
|
* completes successfully. Here we extract the bootstrap information
|
||||||
|
* for the client and start up the writer thread to manage the other
|
||||||
|
* half of our bi-directional message stream.
|
||||||
|
*/
|
||||||
|
protected synchronized void logonSucceeded (AuthResponseData data)
|
||||||
{
|
{
|
||||||
|
// extract bootstrap information
|
||||||
|
|
||||||
|
// create a new writer thread and start it up
|
||||||
if (_writer != null) {
|
if (_writer != null) {
|
||||||
throw new RuntimeException("Writer already started!?");
|
throw new RuntimeException("Writer already started!?");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new writer thread and start it up
|
|
||||||
_writer = new Writer();
|
_writer = new Writer();
|
||||||
_writer.start();
|
_writer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called by the reader or writer thread when something goes
|
||||||
|
* awry with our socket connection to the server.
|
||||||
|
*/
|
||||||
|
protected synchronized void connectionFailed (IOException ioe)
|
||||||
|
{
|
||||||
|
// make sure the socket isn't already closed down (meaning we've
|
||||||
|
// already dealt with the failed connection)
|
||||||
|
if (_socket == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// let the client know that things went south
|
||||||
|
_client.notifyObservers(Client.CLIENT_CONNECTION_FAILED, ioe);
|
||||||
|
|
||||||
|
// and request that we go through the motions of logging off
|
||||||
|
logoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called by the reader thread when it goes away.
|
||||||
|
*/
|
||||||
protected synchronized void readerDidExit ()
|
protected synchronized void readerDidExit ()
|
||||||
{
|
{
|
||||||
// clear out our reader reference
|
// clear out our reader reference
|
||||||
@@ -100,6 +178,19 @@ class Communicator
|
|||||||
|
|
||||||
// let the client know when we finally go away
|
// let the client know when we finally go away
|
||||||
_client.communicatorDidExit();
|
_client.communicatorDidExit();
|
||||||
|
|
||||||
|
Log.info("Reader thread exited.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called by the writer thread when it goes away.
|
||||||
|
*/
|
||||||
|
protected synchronized void writerDidExit ()
|
||||||
|
{
|
||||||
|
// clear out our writer reference
|
||||||
|
_writer = null;
|
||||||
|
|
||||||
|
Log.info("Writer thread exited.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,7 +200,7 @@ class Communicator
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
// first we flatten the message so that we can measure it's length
|
// first we flatten the message so that we can measure it's length
|
||||||
msg.writeTo(_dout);
|
TypedObjectFactory.writeTo(_dout, msg);
|
||||||
// then write the framed message to actual output stream
|
// then write the framed message to actual output stream
|
||||||
_fout.writeFrameAndReset(_out);
|
_fout.writeFrameAndReset(_out);
|
||||||
}
|
}
|
||||||
@@ -121,11 +212,19 @@ class Communicator
|
|||||||
protected DownstreamMessage receiveMessage ()
|
protected DownstreamMessage receiveMessage ()
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
// read the frame size which comes first
|
// read in the next message frame
|
||||||
int count = _din.readInt();
|
_fin.clearAndReadFrame(_in);
|
||||||
|
// then use the typed object factory to read and decode the proper
|
||||||
|
// downstream message instance
|
||||||
|
return (DownstreamMessage)TypedObjectFactory.readFrom(_din);
|
||||||
|
}
|
||||||
|
|
||||||
// now read
|
/**
|
||||||
return null;
|
* Callback called by the reader thread when it has parsed a new
|
||||||
|
* message from the socket and wishes to have it processed.
|
||||||
|
*/
|
||||||
|
protected void processMessage (DownstreamMessage msg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,10 +253,9 @@ class Communicator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// once authenticated, we go into full-duplex mode,
|
// now that we're authenticated, we manage the reading
|
||||||
// starting up another thread to listen for messages while
|
// half of things by continuously reading messages from
|
||||||
// we handle the delivery of messages
|
// the socket and processing them
|
||||||
startWriter();
|
|
||||||
listen();
|
listen();
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
@@ -166,6 +264,22 @@ class Communicator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs the reader thread that it's no longer running. The next
|
||||||
|
* time through the read loop, it will exit.
|
||||||
|
*/
|
||||||
|
public synchronized void shutdown ()
|
||||||
|
{
|
||||||
|
_running = false;
|
||||||
|
|
||||||
|
// if we are not the reader thread, then we want to interrupt
|
||||||
|
// the reader thread as it may be blocked listening to the
|
||||||
|
// socket
|
||||||
|
if (Thread.currentThread() != this) {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void connect ()
|
protected void connect ()
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
@@ -180,13 +294,14 @@ class Communicator
|
|||||||
// establish a socket connection to said server
|
// establish a socket connection to said server
|
||||||
_socket = new Socket(host, _client.getPort());
|
_socket = new Socket(host, _client.getPort());
|
||||||
|
|
||||||
// create our input and output streams
|
// get a handle on our input and output streams
|
||||||
InputStream in = _socket.getInputStream();
|
_in = _socket.getInputStream();
|
||||||
_din = new DataInputStream(new BufferedInputStream(in));
|
|
||||||
_out = _socket.getOutputStream();
|
_out = _socket.getOutputStream();
|
||||||
|
|
||||||
// we frame our messages here and then write them directly to
|
// our messages are framed (preceded by their length), so we
|
||||||
// the real output stream
|
// use these helper streams to manage the framing
|
||||||
|
_fin = new FramedInputStream();
|
||||||
|
_din = new DataInputStream(_fin);
|
||||||
_fout = new FramingOutputStream();
|
_fout = new FramingOutputStream();
|
||||||
_dout = new DataOutputStream(_fout);
|
_dout = new DataOutputStream(_fout);
|
||||||
}
|
}
|
||||||
@@ -197,11 +312,74 @@ class Communicator
|
|||||||
// construct an auth request and send it
|
// construct an auth request and send it
|
||||||
AuthRequest req = new AuthRequest(_client.getCredentials());
|
AuthRequest req = new AuthRequest(_client.getCredentials());
|
||||||
sendMessage(req);
|
sendMessage(req);
|
||||||
|
|
||||||
|
// now wait for the auth response
|
||||||
|
AuthResponse rsp = (AuthResponse)receiveMessage();
|
||||||
|
AuthResponseData data = rsp.getData();
|
||||||
|
|
||||||
|
// if the auth request failed, we want to let the communicator
|
||||||
|
// know by throwing a login exception
|
||||||
|
if (!data.code.equals(Codes.SUCCESS)) {
|
||||||
|
throw new LogonException(data.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're all clear. let the communicator know that we're in
|
||||||
|
logonSucceeded(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void listen ()
|
protected void listen ()
|
||||||
{
|
{
|
||||||
|
DownstreamMessage msg = null;
|
||||||
|
|
||||||
|
while (isRunning()) {
|
||||||
|
try {
|
||||||
|
// read the next message from the socket
|
||||||
|
msg = receiveMessage();
|
||||||
|
|
||||||
|
// process the message
|
||||||
|
processMessage(msg);
|
||||||
|
|
||||||
|
} catch (ObjectStreamException ose) {
|
||||||
|
Log.warning("Error decoding message: " + ose);
|
||||||
|
// move on to the next message
|
||||||
|
|
||||||
|
} catch (InterruptedIOException iioe) {
|
||||||
|
// somebody set up us the bomb! we've been interrupted
|
||||||
|
// which means that we're being shut down, so we
|
||||||
|
// simply fall through and isRunning() will return
|
||||||
|
// false next time through the loop
|
||||||
|
Log.info("Reader thread woken up in time to die.");
|
||||||
|
|
||||||
|
} catch (EOFException eofe) {
|
||||||
|
Log.info("Connection closed by peer.");
|
||||||
|
// nothing left for us to do
|
||||||
|
shutdown();
|
||||||
|
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// let the communicator know that our connection
|
||||||
|
// failed
|
||||||
|
connectionFailed(ioe);
|
||||||
|
// and shut ourselves down
|
||||||
|
shutdown();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Error processing message [msg=" + msg +
|
||||||
|
", error=" + e + "].");
|
||||||
|
// move on to the next message
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must access _running via this member function to ensure that we
|
||||||
|
* are Chapter 17 compliant.
|
||||||
|
*/
|
||||||
|
protected synchronized boolean isRunning ()
|
||||||
|
{
|
||||||
|
return _running;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean _running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -213,6 +391,67 @@ class Communicator
|
|||||||
{
|
{
|
||||||
public void run ()
|
public void run ()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
while (isRunning()) {
|
||||||
|
// fetch the next message from the queue
|
||||||
|
UpstreamMessage msg = (UpstreamMessage)_msgq.get();
|
||||||
|
|
||||||
|
// if this is a termination message, we're being
|
||||||
|
// requested to exit, so we want to bail now rather
|
||||||
|
// than continuing
|
||||||
|
if (msg instanceof TerminationMessage) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// write the message out the socket
|
||||||
|
sendMessage(msg);
|
||||||
|
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// let the communicator know if we have any
|
||||||
|
// problems
|
||||||
|
connectionFailed(ioe);
|
||||||
|
// and bail
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
writerDidExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs the writer thread that it's no longer running. The next
|
||||||
|
* time through the write loop, it will exit.
|
||||||
|
*/
|
||||||
|
public synchronized void shutdown ()
|
||||||
|
{
|
||||||
|
_running = false;
|
||||||
|
|
||||||
|
// post a bogus message to the outgoing queue to ensure that
|
||||||
|
// the writer thread notices that it's time to go
|
||||||
|
postMessage(new TerminationMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must access _running via this member function to ensure that we
|
||||||
|
* are Chapter 17 compliant.
|
||||||
|
*/
|
||||||
|
protected synchronized boolean isRunning ()
|
||||||
|
{
|
||||||
|
return _running;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean _running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This is used to terminate the writer thread. */
|
||||||
|
protected static class TerminationMessage extends UpstreamMessage
|
||||||
|
{
|
||||||
|
public short getType ()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,11 +460,15 @@ class Communicator
|
|||||||
protected Writer _writer;
|
protected Writer _writer;
|
||||||
|
|
||||||
protected Socket _socket;
|
protected Socket _socket;
|
||||||
protected DataInputStream _din;
|
protected InputStream _in;
|
||||||
protected OutputStream _out;
|
protected OutputStream _out;
|
||||||
protected Queue _msgq = new Queue();
|
protected Queue _msgq = new Queue();
|
||||||
|
|
||||||
/** We use this to frame our upstream messages. */
|
/** We use this to frame our upstream messages. */
|
||||||
protected FramingOutputStream _fout;
|
protected FramingOutputStream _fout;
|
||||||
protected DataOutputStream _dout;
|
protected DataOutputStream _dout;
|
||||||
|
|
||||||
|
/** We use this to frame our downstream messages. */
|
||||||
|
protected FramedInputStream _fin;
|
||||||
|
protected DataInputStream _din;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: DObject.java,v 1.1 2001/05/22 21:51:29 mdb Exp $
|
// $Id: DObject.java,v 1.2 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.dobj;
|
package com.samskivert.cocktail.cher.dobj;
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ import java.io.DataOutputStream;
|
|||||||
import com.samskivert.cocktail.cher.io.TypedObject;
|
import com.samskivert.cocktail.cher.io.TypedObject;
|
||||||
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
||||||
|
|
||||||
public class DObject extends TypedObject
|
public class DObject implements TypedObject
|
||||||
{
|
{
|
||||||
public static short TYPE = 400;
|
public static short TYPE = 400;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: TypedObject.java,v 1.1 2001/05/22 06:07:59 mdb Exp $
|
// $Id: TypedObject.java,v 1.2 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.io;
|
package com.samskivert.cocktail.cher.io;
|
||||||
|
|
||||||
@@ -10,9 +10,12 @@ import java.io.DataOutputStream;
|
|||||||
/**
|
/**
|
||||||
* A typed object is one that is associated with a particular type code.
|
* A typed object is one that is associated with a particular type code.
|
||||||
* The type code can be communicated on the wire and used by the receiving
|
* The type code can be communicated on the wire and used by the receiving
|
||||||
* end to instantiate the proper typed object class for decoding.
|
* end to instantiate the proper typed object class for decoding (which is
|
||||||
|
* done by the <code>TypedObjectFactory</code>).
|
||||||
|
*
|
||||||
|
* @see TypedObjectFactory
|
||||||
*/
|
*/
|
||||||
public abstract class TypedObject
|
public interface TypedObject
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Each typed object class must associate itself with a type value via
|
* Each typed object class must associate itself with a type value via
|
||||||
@@ -22,28 +25,17 @@ public abstract class TypedObject
|
|||||||
*
|
*
|
||||||
* @return The type code associated with this object.
|
* @return The type code associated with this object.
|
||||||
*/
|
*/
|
||||||
public abstract short getType ();
|
public short getType ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each typed object class must be able to write itself to a stream.
|
* Each typed object class must be able to write itself to a stream.
|
||||||
* It should first call <code>super.writeTo()</code> before writing
|
|
||||||
* its own fields to the stream.
|
|
||||||
*/
|
*/
|
||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
throws IOException;
|
||||||
{
|
|
||||||
out.writeShort(getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each typed object class must be able to read itself from a stream.
|
* Each typed object class must be able to read itself from a stream.
|
||||||
* It should first call <code>super.readFrom()</code> before reading
|
|
||||||
* its own fields from the stream.
|
|
||||||
*/
|
*/
|
||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
throws IOException
|
throws IOException;
|
||||||
{
|
|
||||||
// nothing to do because the TypedObjectFactory already read our
|
|
||||||
// type value from the stream
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: TypedObjectFactory.java,v 1.2 2001/05/22 21:51:29 mdb Exp $
|
// $Id: TypedObjectFactory.java,v 1.3 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.io;
|
package com.samskivert.cocktail.cher.io;
|
||||||
|
|
||||||
@@ -37,6 +37,19 @@ public class TypedObjectFactory
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes (serializes) a typed object to the supplied data output
|
||||||
|
* stream.
|
||||||
|
*/
|
||||||
|
public static void writeTo (DataOutputStream dout, TypedObject tobj)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// first write the type of the object
|
||||||
|
dout.writeShort(tobj.getType());
|
||||||
|
// then write the object itself
|
||||||
|
tobj.writeTo(dout);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the supplied class with the specified type code. If a
|
* Registers the supplied class with the specified type code. If a
|
||||||
* class is already registered with that type code a runtime exception
|
* class is already registered with that type code a runtime exception
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: AuthRequest.java,v 1.2 2001/05/22 21:51:29 mdb Exp $
|
// $Id: AuthRequest.java,v 1.3 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class AuthRequest extends UpstreamMessage
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
_creds.writeTo(out);
|
TypedObjectFactory.writeTo(out, _creds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: AuthResponse.java,v 1.1 2001/05/22 21:51:29 mdb Exp $
|
// $Id: AuthResponse.java,v 1.2 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -7,7 +7,6 @@ import java.io.IOException;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
import com.samskivert.cocktail.cher.dobj.DObject;
|
|
||||||
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,12 +21,6 @@ public class AuthResponse extends DownstreamMessage
|
|||||||
/** The code for an auth response. */
|
/** The code for an auth response. */
|
||||||
public static final short TYPE = TYPE_BASE + 0;
|
public static final short TYPE = TYPE_BASE + 0;
|
||||||
|
|
||||||
/** The response code key in the data object. */
|
|
||||||
public static final String CODE = "code";
|
|
||||||
|
|
||||||
/** The failure reason key in the data object. */
|
|
||||||
public static final String REASON = "reason";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zero argument constructor used when unserializing an instance.
|
* Zero argument constructor used when unserializing an instance.
|
||||||
*/
|
*/
|
||||||
@@ -39,12 +32,12 @@ public class AuthResponse extends DownstreamMessage
|
|||||||
/**
|
/**
|
||||||
* Constructs a auth response with the supplied credentials.
|
* Constructs a auth response with the supplied credentials.
|
||||||
*/
|
*/
|
||||||
public AuthResponse (DObject data)
|
public AuthResponse (AuthResponseData data)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DObject getData ()
|
public AuthResponseData getData ()
|
||||||
{
|
{
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
@@ -58,15 +51,15 @@ public class AuthResponse extends DownstreamMessage
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
_data.writeTo(out);
|
TypedObjectFactory.writeTo(out, _data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
_data = (DObject)TypedObjectFactory.readFrom(in);
|
_data = (AuthResponseData)TypedObjectFactory.readFrom(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DObject _data;
|
protected AuthResponseData _data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// $Id: AuthResponseData.java,v 1.1 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
|
import com.samskivert.cocktail.cher.dobj.DObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An <code>AuthResponseData</code> object is communicated back to the
|
||||||
|
* client along with an authentication response. It contains an indicator
|
||||||
|
* of authentication success or failure along with bootstrap information
|
||||||
|
* for the client.
|
||||||
|
*/
|
||||||
|
public class AuthResponseData extends DObject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Either the string "success" or a reason code for why authentication
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
public String code;
|
||||||
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
//
|
//
|
||||||
// $Id: Credentials.java,v 1.1 2001/05/22 06:07:59 mdb Exp $
|
// $Id: Credentials.java,v 1.2 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
import com.samskivert.cocktail.cher.io.TypedObject;
|
import com.samskivert.cocktail.cher.io.TypedObject;
|
||||||
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
||||||
|
|
||||||
@@ -17,7 +21,7 @@ import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
|||||||
* that they can be instantiated prior to reconstruction from a data input
|
* that they can be instantiated prior to reconstruction from a data input
|
||||||
* stream.
|
* stream.
|
||||||
*/
|
*/
|
||||||
public abstract class Credentials extends TypedObject
|
public abstract class Credentials implements TypedObject
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* All credential derived classes should base their typed object code
|
* All credential derived classes should base their typed object code
|
||||||
@@ -25,6 +29,28 @@ public abstract class Credentials extends TypedObject
|
|||||||
*/
|
*/
|
||||||
public static final short TYPE_BASE = 300;
|
public static final short TYPE_BASE = 300;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derived classes should override this function to write their fields
|
||||||
|
* out to the supplied data output stream. They <em>must</em> be sure
|
||||||
|
* to first call <code>super.writeTo()</code>.
|
||||||
|
*/
|
||||||
|
public void writeTo (DataOutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// we don't do anything here, but we may want to some day
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derived classes should override this function to read their fields
|
||||||
|
* from the supplied data input stream. They <em>must</em> be sure to
|
||||||
|
* first call <code>super.readFrom()</code>.
|
||||||
|
*/
|
||||||
|
public void readFrom (DataInputStream in)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// we don't do anything here, but we may want to some day
|
||||||
|
}
|
||||||
|
|
||||||
// register our credential classes
|
// register our credential classes
|
||||||
static {
|
static {
|
||||||
TypedObjectFactory.registerClass(UsernamePasswordCreds.TYPE,
|
TypedObjectFactory.registerClass(UsernamePasswordCreds.TYPE,
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
//
|
//
|
||||||
// $Id: DownstreamMessage.java,v 1.2 2001/05/22 21:51:29 mdb Exp $
|
// $Id: DownstreamMessage.java,v 1.3 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
|
||||||
import com.samskivert.cocktail.cher.io.TypedObject;
|
import com.samskivert.cocktail.cher.io.TypedObject;
|
||||||
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
||||||
|
|
||||||
@@ -12,7 +16,7 @@ import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
|||||||
* client. Downstream messages include object subscription, event
|
* client. Downstream messages include object subscription, event
|
||||||
* forwarding and session management.
|
* forwarding and session management.
|
||||||
*/
|
*/
|
||||||
public abstract class DownstreamMessage extends TypedObject
|
public abstract class DownstreamMessage implements TypedObject
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* All downstream message derived classes should base their typed
|
* All downstream message derived classes should base their typed
|
||||||
@@ -41,6 +45,28 @@ public abstract class DownstreamMessage extends TypedObject
|
|||||||
// nothing to do...
|
// nothing to do...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derived classes should override this function to write their fields
|
||||||
|
* out to the supplied data output stream. They <em>must</em> be sure
|
||||||
|
* to first call <code>super.writeTo()</code>.
|
||||||
|
*/
|
||||||
|
public void writeTo (DataOutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// we don't do anything here, but we may want to some day
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derived classes should override this function to read their fields
|
||||||
|
* from the supplied data input stream. They <em>must</em> be sure to
|
||||||
|
* first call <code>super.readFrom()</code>.
|
||||||
|
*/
|
||||||
|
public void readFrom (DataInputStream in)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// we don't do anything here, but we may want to some day
|
||||||
|
}
|
||||||
|
|
||||||
// register our downstream message classes
|
// register our downstream message classes
|
||||||
static {
|
static {
|
||||||
TypedObjectFactory.registerClass(AuthResponse.TYPE,
|
TypedObjectFactory.registerClass(AuthResponse.TYPE,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: ObjectResponse.java,v 1.1 2001/05/22 21:51:29 mdb Exp $
|
// $Id: ObjectResponse.java,v 1.2 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ public class ObjectResponse extends DownstreamMessage
|
|||||||
{
|
{
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeShort(messageId);
|
out.writeShort(messageId);
|
||||||
_dobj.writeTo(out);
|
TypedObjectFactory.writeTo(out, _dobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: UpstreamMessage.java,v 1.2 2001/05/22 21:51:29 mdb Exp $
|
// $Id: UpstreamMessage.java,v 1.3 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ import com.samskivert.cocktail.cher.io.TypedObjectFactory;
|
|||||||
* Upstream messages include object subscription, event forwarding and
|
* Upstream messages include object subscription, event forwarding and
|
||||||
* session management.
|
* session management.
|
||||||
*/
|
*/
|
||||||
public abstract class UpstreamMessage extends TypedObject
|
public abstract class UpstreamMessage implements TypedObject
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* All upstream message derived classes should base their typed object
|
* All upstream message derived classes should base their typed object
|
||||||
@@ -53,7 +53,6 @@ public abstract class UpstreamMessage extends TypedObject
|
|||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.writeTo(out);
|
|
||||||
out.writeShort(messageId);
|
out.writeShort(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +64,6 @@ public abstract class UpstreamMessage extends TypedObject
|
|||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
super.readFrom(in);
|
|
||||||
messageId = in.readShort();
|
messageId = in.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: UsernamePasswordCreds.java,v 1.2 2001/05/22 21:51:29 mdb Exp $
|
// $Id: UsernamePasswordCreds.java,v 1.3 2001/05/23 04:03:40 mdb Exp $
|
||||||
|
|
||||||
package com.samskivert.cocktail.cher.net;
|
package com.samskivert.cocktail.cher.net;
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ public class UsernamePasswordCreds extends Credentials
|
|||||||
public void writeTo (DataOutputStream out)
|
public void writeTo (DataOutputStream out)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
super.writeTo(out);
|
||||||
out.writeUTF(_username);
|
out.writeUTF(_username);
|
||||||
out.writeUTF(_password);
|
out.writeUTF(_password);
|
||||||
}
|
}
|
||||||
@@ -43,6 +44,7 @@ public class UsernamePasswordCreds extends Credentials
|
|||||||
public void readFrom (DataInputStream in)
|
public void readFrom (DataInputStream in)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
super.readFrom(in);
|
||||||
_username = in.readUTF();
|
_username = in.readUTF();
|
||||||
_password = in.readUTF();
|
_password = in.readUTF();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// $Id: CherCodes.java,v 1.1 2001/05/23 04:03:41 mdb Exp $
|
||||||
|
|
||||||
|
package com.samskivert.cocktail.cher.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <code>Codes</code> class serves as a repository for miscellaneous
|
||||||
|
* string and integer constants used by componenets of the Cher system.
|
||||||
|
*/
|
||||||
|
public class Codes
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generally used in responses that can either have the value success,
|
||||||
|
* or a string code explaining the reason for failure.
|
||||||
|
*/
|
||||||
|
public static final String SUCCESS = "success";
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user