	1	// Fig. 24.22: MessageReceiver java
	2	// MessageReceiver é um executável que ouve mensagens a partir de um
	3	// cliente particular e envia mensagens para um MessageListener.
	4	package com.deitel.messenger.sockets.server;
	5	
	6	import java.io.BufferedReader;
	7	import java.io.IOException;
	8	import java.io.InputStreamReader;
	9	import java.net.Socket;
	10	import java.net.SocketTimeoutException;
	11	import java.util.StringTokenizer;
	12	
	13	import com.deitel.messenger.MessageListener;
	14	import static com.deitel.messenger.sockets.SocketMessengerConstants.*;
	15	
	16	public class MessageReceiver implements Runnable
	17	{
	18	   private BufferedReader input; // fluxo de entrada
	19	   private MessageListener messageListener; // ouvinte da mensagem
	20	   private boolean keepListening = true; // quando false, termina o executável
	21	   
	22	   // Construtor de MessageReceiver
	23	   public MessageReceiver( MessageListener listener, Socket clientSocket ) 
	24	   {
	25	      // configura o ouvinte ao qual novas mensagens devem ser enviadas
	26	      messageListener = listener;
	27	      
	28	      try 
	29	      {
	30	         // configura o tempo limite para leitura do cliente            
	31	         clientSocket.setSoTimeout( 5000 ); // cinco segundos
	32	         
	33	         // cria BufferedReader para ler mensagens entrantes
	34	         input = new BufferedReader( new InputStreamReader( 
	35	            clientSocket.getInputStream() ) );
	36	      } // fim do try
	37	      catch ( IOException ioException ) 
	38	      {
	39	         ioException.printStackTrace();
	40	      } // fim do catch
	41	   } // fim do construtor MessageReceiver
	42	   
	43	   // ouve novas mensagens e as envia para o MessageListener
	44	   public void run() 
	45	   {    
	46	      String message; // String para mensagens entrantes
	47	      
	48	      // ouve mensagens até ser parado
	49	      while ( keepListening ) 
	50	      {   
	51	         try                                                         
	52	         {                                                           
	53	            message = input.readLine(); // lê a mensagem do cliente  
	54	         } // fim do try
	55	         catch ( SocketTimeoutException socketTimeoutException )     
	56	         {                                                           
	57	            continue; // continua para a próxima iteração para se manter ouvindo
	58	         } // fim do catch
	59	         catch ( IOException ioException ) 
	60	         {
	61	            ioException.printStackTrace();
	62	            break;
	63	         } // fim do catch
	64	
	65	         // assegura que a mensagem não seja nula
	66	         if ( message != null ) 
	67	         {
	68	            // divide a mensagem em tokens para recuperar o nome do usuário e corpo da mensagem
	69	            StringTokenizer tokenizer = new StringTokenizer(          
	70	               message, MESSAGE_SEPARATOR );                          
	71	
	72	            // ignora as mensagens que não contêm um nome de usuário
	73	            // e um corpo de mensagem
	74	            if ( tokenizer.countTokens() == 2 ) 
	75	            {  
	76	               // envia a mensagem para MessageListener         
	77	               messageListener.messageReceived(           
	78	                  tokenizer.nextToken(), // nome de usuário     
	79	                  tokenizer.nextToken() ); // corpo de mensagem
	80	            } // fim do if
	81	            else
	82	            {
	83	               // se recebeu mensagem de desconexão, pára de ouvir
	84	               if ( message.equalsIgnoreCase(                   
	85	                  MESSAGE_SEPARATOR + DISCONNECT_STRING ) )     
	86	                  stopListening();                              
	87	            } // fim de else
	88	         } // fim do if
	89	      } // fim do while
	90	      
	91	      try
	92	      {  
	93	         input.close(); // fecha o BufferedReader (também fecha o Socket)
	94	      } // fim do try
	95	      catch ( IOException ioException ) 
	96	      {
	97	         ioException.printStackTrace();
	98	      } // fim do catch
	99	   } // fim do método run
	100	   
	101	   // pára de ouvir mensagens entrantes
	102	   public void stopListening() 
	103	   {
	104	      keepListening = false;
	105	   } // fim do método stopListening
	106	} // fim da classe MessageReceiver

