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