//----------------------------------------------------------------------------- // Copyright (c) 1994,1995 Southeastern Universities Research Association, // Continuous Electron Beam Accelerator Facility // // This software was developed under a United States Government license // described in the NOTICE file included as part of this distribution. // // Jefferson Lab HPC Group, 12000 Jefferson Ave., Newport News, VA 23606 //----------------------------------------------------------------------------- // // Description: // rsvcClient Reader that is reading data out of socket // // Author: // Jie Chen // Jefferson Lab HPC Group // // Revision History: // $Log: rsvcClientReader.java,v $ // Revision 1.1.1.1 2000/05/23 15:12:50 pal // cdev_psi_1.7.2 // // Revision 1.2 1999/12/14 15:38:15 chen // Add scrollbar to display // // Revision 1.1 1999/10/18 17:12:39 chen // *** empty log message *** // // // // import java.io.*; import java.net.*; import java.util.*; import rsvcData; import rsvcEvent; import rsvcEventHandler; import rsvcClient; public final class rsvcClientReader implements Runnable { // disconnection callback list (list of event handler) private Vector discCbkList_ = null; // all send/get command callback list private Hashtable cmdCbkList_ = null; // monitor callback list private Hashtable monitorCbkTable_ = null; // Input and output buffer private DataInputStream input_ = null; // Pointer back to rsvcClient private rsvcClient client_; /** * Construct a rsvcClientReader from a established client object */ public rsvcClientReader (rsvcClient client) { client_ = client; // create lists and a table for event handlers discCbkList_ = new Vector (); cmdCbkList_ = new Hashtable (20, (float)0.25); monitorCbkTable_ = new Hashtable (20, (float)0.25); InputStream tinput = null; Socket socket = null; try { socket = client_.getSocket(); }catch (NullPointerException e) { System.err.print (e); System.exit (-1); } try { tinput = socket.getInputStream(); }catch (IOException e) { System.err.print (e); System.exit (-1); } input_ = new DataInputStream (tinput); } /** * Add an event handler to handle disconnection event. * Return true if this event handler is registered successfully. * Return false if this event handler is already here. */ public boolean addDisconnectHandler (rsvcEventHandler handler) { if (discCbkList_.contains (handler) == true) return false; discCbkList_.addElement (handler); return true; } /** * Clean up all event handlers */ public void cleanupEventHandlers () { discCbkList_.removeAllElements (); cmdCbkList_.clear (); monitorCbkTable_.clear (); } /** * Add an event handler to command event handler list */ public void addCommandEventHandler (int id, rsvcEvent oevent) { // vector is thread safe cmdCbkList_.put (new Integer(id), oevent); } /** * Add an event handler to monitor event handler table */ public void addMonitorEventHandler (int id, rsvcEvent oevent) { // vector is thread safe monitorCbkTable_.put (new Integer(id), oevent); } /** * Find out whether a particular event is already in the * monitor event handler table */ public boolean containsMonitorEvent (rsvcEvent event) { Integer key = new Integer (event.getEventid ()); return monitorCbkTable_.containsKey (key); } /** * Dispatch all event handlers when the server goes down */ public void dispatchDiscEventHandlers () { Enumeration list = discCbkList_.elements (); rsvcEventHandler handler = null; rsvcEvent event = new rsvcEvent (); event.setStatus (rsvcConfig.RSVC_DISCONNECTED); while (list.hasMoreElements ()) { handler = (rsvcEventHandler)(list.nextElement()); handler.handleEvent (event); } } public void run () { // buffer for header int headerlen = rsvcEvent.headerLen (); byte[] header = new byte[headerlen]; ByteArrayInputStream bainput = new ByteArrayInputStream (header); // buffer for payload int datasize = 4096; int prevsize = 4096; byte[] payload = new byte[datasize]; ByteArrayInputStream plinput = new ByteArrayInputStream (payload); // event data object rsvcEvent event = new rsvcEvent (); while (true) { // read header try { input_.readFully (header); }catch (IOException e) { System.err.println ("Server is down"); client_.handleClose (); break; } // reset input stream buffer bainput.reset (); try { datasize = rsvcEvent.readHeader (bainput); }catch (IOException e) { System.err.println ("Receiving header error" + e); client_.handleClose (); break; } if (datasize > prevsize) { datasize = 2*datasize; prevsize = datasize; payload = new byte[datasize]; plinput = new ByteArrayInputStream (payload); } // read raw bytes of length 'datasize' try { input_.readFully (payload, 0, datasize); }catch (IOException e) { System.err.println ("Server is down here"); client_.handleClose (); break; } // convert above raw bytes into an event plinput.reset (); try { event.streamIn (plinput); }catch (IOException e) { System.err.println ("Payload data format error: " + e); client_.handleClose (); break; } // dispatch this event to an appropriate destination if (dispatchEvent (event) != 0) { client_.handleClose (); break; } } System.out.println ("rsvcClientReader Thread is finished"); } private int dispatchEvent (rsvcEvent event) { int op = event.getOpcode (); int status = 0; if (op < rsvcConfig.RSVC_MONITOR_ON) // all simple command transaction events status = dispatchCmdEventFromServer (event); else if (op < rsvcConfig.RSVC_OP_UNKNOWN) // all monitor events status = dispatchMonitorEventFromServer (event); else { System.err.println ("rsvcClient: Invalid option code: " + String.valueOf(op)); status = -1; } return status; } private int dispatchCmdEventFromServer (rsvcEvent event) { Integer key = new Integer (event.getEventid()); int status = event.getStatus (); Object obj = null; rsvcEventHandler handler = null; rsvcEvent oevent = null; // retrieve object from event which has key value obj = cmdCbkList_.get (key); if (obj != null) { oevent = (rsvcEvent)obj; if (oevent.match (event) == false) { System.err.println ("Incoming and outgoing events are not match"); return -1; } try { handler = oevent.getHandler (); } catch (NullPointerException e) { System.err.println (e); return -1; } handler.handleEvent (event); if (status != rsvcConfig.RSVC_INCOMPLETE) cmdCbkList_.remove (event); } else { System.out.println ("rsvcClient: Event from server does not match"); } return 0; } private int dispatchMonitorEventFromServer (rsvcEvent event) { Integer key = new Integer (event.getEventid ()); int status = event.getStatus(); Object obj = null; rsvcEventHandler handler = null; rsvcEvent oevent = null; obj = monitorCbkTable_.get (key); if (obj != null) { oevent = (rsvcEvent)obj; try { handler = oevent.getHandler (); }catch (NullPointerException e) { System.err.println (e); return -1; } handler.handleEvent (event); if (status != rsvcConfig.RSVC_SUCCESS && status != rsvcConfig.RSVC_INCOMPLETE) { // if an event is bad or finished, remove it monitorCbkTable_.remove (event); } } else if (status != rsvcConfig.RSVC_SUCCESS) { System.out.println ("rsvcClient: monitor event from server does not match any"); System.out.println (event.toString()); } return 0; } }