View Javadoc
1   package otherTests.multicast;
2   
3   import java.io.BufferedReader;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.io.InputStreamReader;
7   import java.io.OutputStream;
8   import java.io.PrintWriter;
9   import java.net.Socket;
10  
11  public final class Message {
12      private static final int CLIENT_PORT = 8000;
13  
14      private final Client[] to;
15      private final String contents;
16      private final StatusListener listener;
17  
18      public Message(Client[] to, String contents, StatusListener listener) {
19          this.to = to;
20          this.contents = contents;
21          this.listener = listener;
22      }
23  
24      /**
25       * Sends the message contents to all clients, notifying the status listener about the corresponding events as they
26       * occur.
27       * <p>
28       * Network communication with clients occurs asynchronously, without ever blocking the caller. Status notifications
29       * are executed on the Swing EDT (Event Dispatching Thread), so that the UI can be safely updated.
30       */
31      public void dispatch() {
32          for (Client client : to) {
33              MessageDispatcher dispatcher = new MessageDispatcher(client);
34              new Thread(dispatcher).start();
35          }
36      }
37  
38      private final class MessageDispatcher implements Runnable {
39          private final Client client;
40  
41          MessageDispatcher(Client client) {
42              this.client = client;
43          }
44  
45          @Override
46          public void run() {
47              try {
48                  communicateWithClient();
49              } catch (IOException e) {
50                  throw new RuntimeException(e);
51              }
52          }
53  
54          private void communicateWithClient() throws IOException {
55              try (Socket connection = new Socket(client.getAddress(), CLIENT_PORT)) {
56                  sendMessage(connection.getOutputStream());
57                  readRequiredReceipts(connection.getInputStream());
58              }
59          }
60  
61          private void sendMessage(OutputStream output) {
62              new PrintWriter(output, true).println(contents);
63              listener.messageSent(client);
64          }
65  
66          private void readRequiredReceipts(InputStream input) throws IOException {
67              BufferedReader in = new BufferedReader(new InputStreamReader(input));
68  
69              // Wait for display receipt:
70              in.readLine();
71              listener.messageDisplayedByClient(client);
72  
73              // Wait for read receipt:
74              in.readLine();
75              listener.messageReadByClient(client);
76          }
77      }
78  }