• Main Page
  • Related Pages
  • Classes
  • Files
  • File List

ChatServerClient.java

Go to the documentation of this file.
00001 
00002 import java.io.BufferedReader;
00003 import java.io.IOException;
00004 import java.io.InputStreamReader;
00005 import java.io.OutputStreamWriter;
00006 import java.io.PrintWriter;
00007 import java.net.Socket;
00008 
00009 import net.chayden.Eliza.Eliza;
00010 
00011 /**
00012  *  Chat server's threaded back-end for clients.
00013  *  
00014  *  @author Mikica B Kocic
00015  */
00016 public class ChatServerClient extends Thread
00017 {
00018     /**
00019      *  Instance of the server to which this client belongs
00020      */
00021     private ChatServer  server;
00022     
00023     /**
00024      *  Output stream to remote client
00025      */
00026     private PrintWriter out;
00027 
00028     /**
00029      *  Identifier of the client (remote ip addre + remote port)
00030      */
00031     private String clientName;
00032     
00033     /**
00034      *  Connection socket to server
00035      */
00036     private Socket socket;
00037     
00038     /**
00039      *  Indicates if thread is (or should be) running
00040      */
00041     private volatile boolean running;
00042 
00043     /**
00044      *  Instance of Joseph Weizenbaum's Eliza, a simulation of a Rogerian shrink.
00045      *  Eliza may talk to user (if called up) if user is alone in the chat room.
00046      */
00047     private Eliza eliza;
00048 
00049     /**
00050      *  Creates instance of chat server's threaded back-end for specific client
00051      *  
00052      *  @param server   instance of the chat server, i.e. owner of this back-end
00053      *  @param socket   socket to remote chat client accepted by the server earlier
00054      */
00055     public ChatServerClient( ChatServer server, Socket socket )
00056     {
00057         this.server     = server;
00058         this.socket     = socket;
00059         this.out        = null;
00060         this.running    = true;
00061         this.eliza      = null;
00062 
00063         /* Setup initial client name as <addr>:<port>.
00064          * It will be resolved later in <hostname>:<port>, when the thread starts.
00065          */
00066         this.clientName = socket.getInetAddress ().getHostAddress () 
00067                         + ":" + socket.getPort ();
00068     }
00069 
00070     /**
00071      *  Gets identifier of the client
00072      */
00073     public String getClientName ()
00074     {
00075         return clientName;
00076     }
00077     
00078     /**
00079      *  Sends message (appended with new-line) to chat server
00080      *  
00081      *  @param message
00082      */
00083     public void send( String message )
00084     {
00085         synchronized( this )
00086         {
00087             if ( out == null || message == null ) {
00088                 return;
00089             }
00090             
00091             out.println( message );
00092             out.flush ();
00093         }
00094     }
00095 
00096     /**
00097      *  Sends messages from Eliza
00098      */
00099     private void sendFromEliza( String messageFromEliza )
00100     {
00101         server.logEliza( messageFromEliza, this );
00102         send( "Eliza :: " + messageFromEliza );
00103     }
00104     
00105     /**
00106      *  Broadcasts message, talks to Eliza, responds to "wwhhoo" command etc.
00107      */
00108     private void respondToMessage( String message )
00109     {
00110         /* Parse input with syntax: [ [ <userId> ] ":: " ] <message>
00111          * where default userId is [Anonymous].
00112          */
00113         String textPart = message;
00114         String[] parts = message.split( ":: ", 2 );
00115         // String userId = "[Anonymous]";
00116         
00117         if ( parts.length == 0 ) {
00118             textPart = parts[0];
00119         } else if ( parts[0].trim().length () == 0 && parts.length >= 2 ) {
00120             textPart = parts[1];
00121         } else if ( parts.length >= 2 ) {
00122             // userId  = parts[0].trim();
00123             textPart = parts[1];
00124         } else {
00125             textPart = parts[0];
00126         }
00127 
00128         if ( textPart.equals( "wwhhoo" ) ) 
00129         {
00130             server.wwhhoo( this );
00131         }
00132         else if ( server.getClientCount () == 1 && eliza != null )
00133         {
00134             server.broadcast( this, message );
00135             sendFromEliza( eliza.processInput( textPart ) );
00136         }
00137         else if ( eliza == null && textPart.equalsIgnoreCase( "talk eliza" ) ) 
00138         {
00139             server.broadcast( this, message );
00140             if ( server.getClientCount () > 1 )
00141             {
00142                 sendFromEliza( "We are not alone!" );
00143             }
00144             else
00145             {
00146                 eliza = new Eliza( /*local=*/true, "eliza-script.txt" );
00147                 sendFromEliza( "Hello! My name is Eliza and I am the psychoterapist. " );
00148                 sendFromEliza( " It seems that we are alone... "
00149                                + "Please tell me your problem." );
00150             }
00151         }
00152         else
00153         {
00154             server.broadcast( this, message );
00155         }
00156     }
00157 
00158     /**
00159      * 
00160      */
00161     @Override
00162     public void run ()
00163     {
00164         // Create i/o buffers on client socket
00165         //
00166         BufferedReader in = null;
00167         try
00168         {
00169             this.clientName = socket.getInetAddress ().getHostName () 
00170                 + ":" + socket.getPort ();
00171 
00172             in = new BufferedReader(
00173                     new InputStreamReader( socket.getInputStream (), "utf-8" ) );
00174 
00175             out = new PrintWriter(
00176                     new OutputStreamWriter( socket.getOutputStream(), "utf-8" ),
00177                     /*autoflush*/ true );
00178 
00179             // Live and well if reached following line
00180             //
00181             server.broadcast( null, "New client [" + getClientName() + "]" );
00182             
00183             if ( server.getClientCount() == 1 && eliza == null )
00184             {
00185                 send( "[System] :: It seems that you are alone in the chat room. "
00186                         + "Reply with 'talk eliza' if you want to bring up Eliza..." );
00187             }
00188         }
00189         catch (IOException ex)
00190         {
00191             running = false;
00192         }
00193 
00194         while( running )
00195         {
00196             try
00197             {
00198                 String message = in.readLine ();
00199                 if ( message == null ) {
00200                     running = false;
00201                     break;
00202                 }
00203 
00204                 respondToMessage( message );
00205             }
00206             catch( IOException ex )
00207             {
00208                 running = false;
00209             }
00210         }
00211 
00212         // On socket error or regular disconnect
00213         //
00214         server.removeClient( this );
00215         server.broadcast( null, "Client [" + getClientName() + "] disconnected" );
00216     }
00217 
00218 }

Generated on Thu Dec 16 2010 14:26:32 for Chat Server by  doxygen 1.7.2