001package edu.pdx.cs410J.net; 002 003import java.io.*; 004import java.util.*; 005import java.net.*; 006 007/** 008 * A <code>ChatSpeaker</code> runs in the background and sends 009 * <code>ChatMessage</code>s over a <code>Socket</code>. 010 */ 011public class ChatSpeaker implements Runnable { 012 private static PrintStream err = System.err; 013 014 private List outgoing; // Outgoing messages 015 private BufferedOutputStream bos; // Send messages here 016 017 /** 018 * Creates a new <code>ChatSpeaker</code> 019 */ 020 public ChatSpeaker() { 021 this.outgoing = new ArrayList(); 022 } 023 024 /** 025 * Sets the socket to which this <code>ChatSpeaker</code> sends 026 * messages. 027 */ 028 public void setSocket(Socket socket) { 029// System.out.println("Making output stream"); 030 031 try { 032 // Make streams for reading and writing 033// System.out.println("OutputStream"); 034 035 this.bos = new BufferedOutputStream(socket.getOutputStream()); 036 037 } catch (IOException ex) { 038 err.println("** IOException: " + ex); 039 System.exit(1); 040 } 041 } 042 043 /** 044 * A <code>ChatSpeaker</code> uses wait/notify on its 045 * <code>incoming</code> list to know when to send a message. For 046 * the sake of symmetry, we interrupt it to tell it to stop. 047 */ 048 public void run() { 049// System.out.println("ChatSpeaker starting"); 050 051 while (true) { 052 try { 053 // Is there a message to send? 054 synchronized(this.outgoing) { 055 if (!this.outgoing.isEmpty()) { 056 ChatMessage m = (ChatMessage) this.outgoing.remove(0); 057 058// System.out.println("Sending: " + m); 059 060 ObjectOutputStream out = new ObjectOutputStream(bos); 061 out.writeObject(m); 062 out.flush(); 063 064 if (m.isLastMessage()) { 065 // Send the last message and then go home 066 break; 067 } 068 069 } 070 071 // Wait for a message 072 this.outgoing.wait(); 073 } 074 075 } catch (IOException ex) { 076 err.println("** IOException: " + ex); 077 System.exit(1); 078 break; 079 080 } catch (InterruptedException ex) { 081// System.out.println("Done sending messages"); 082 break; 083 } 084 } 085 086// System.out.println("ChatSpeaker stopping"); 087 } 088 089 /** 090 * Queues a message to be sent. This method will be called by a 091 * thread other than the one running run(). 092 */ 093 public void sendMessage(ChatMessage message) { 094 synchronized(this.outgoing) { 095// System.out.println("Adding message: " + message); 096 this.outgoing.add(message); 097 this.outgoing.notify(); 098 } 099 } 100}