1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.util.transport;
24  
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  
28  import java.io.IOException;
29  
30  import java.net.DatagramPacket;
31  import java.net.InetAddress;
32  import java.net.MulticastSocket;
33  
34  /**
35   * <a href="MulticastTransport.java.html"><b><i>View Source</i></b></a>
36   *
37   * <p>
38   * The MulticastTransport will send strings across a specified multicast
39   * address. It will also listen for messages and hand them to the appropriate
40   * DatagramHandler.
41   * </p>
42   *
43   * @author Michael C. Han
44   *
45   */
46  public class MulticastTransport extends Thread implements Transport {
47  
48      public MulticastTransport(DatagramHandler handler, String host, int port) {
49          super("MulticastListener-" + host + port);
50  
51          setDaemon(true);
52          _handler = handler;
53          _host = host;
54          _port = port;
55      }
56  
57      public synchronized void connect() throws IOException {
58          if (_socket == null) {
59              _socket = new MulticastSocket(_port);
60          }
61          else if (_socket.isConnected() && _socket.isBound()) {
62              return;
63          }
64  
65          _address = InetAddress.getByName(_host);
66  
67          _socket.joinGroup(_address);
68  
69          _connected = true;
70  
71          start();
72      }
73  
74      public synchronized void disconnect() {
75  
76          // Interrupt all processing
77  
78          if (_address != null) {
79              try {
80                  _socket.leaveGroup(_address);
81                  _address = null;
82              }
83              catch (IOException e) {
84                  _log.error("Unable to leave group", e);
85              }
86          }
87  
88          _connected = false;
89  
90          interrupt();
91  
92          _socket.close();
93      }
94  
95      public synchronized void sendMessage(String msg) throws IOException {
96          _outboundPacket.setData(msg.getBytes());
97          _outboundPacket.setAddress(_address);
98          _outboundPacket.setPort(_port);
99  
100         _socket.send(_outboundPacket);
101     }
102 
103     public boolean isConnected() {
104         return _connected;
105     }
106 
107     public void run() {
108         try {
109             while (_connected) {
110                 _socket.receive(_inboundPacket);
111                 _handler.process(_inboundPacket);
112             }
113         }
114         catch (IOException e) {
115             _log.error("Unable to process ", e);
116 
117             _socket.disconnect();
118 
119             _connected = false;
120 
121             _handler.errorReceived(e);
122         }
123     }
124 
125     private static Log _log = LogFactoryUtil.getLog(MulticastTransport.class);
126 
127     private byte[] _inboundBuffer = new byte[4096];
128     private DatagramPacket _inboundPacket =
129         new DatagramPacket(_inboundBuffer, _inboundBuffer.length);
130     private byte[] _outboundBuffer = new byte[4096];
131     private DatagramPacket _outboundPacket =
132         new DatagramPacket(_outboundBuffer, _outboundBuffer.length);
133     private String _host;
134     private DatagramHandler _handler;
135     private int _port;
136     private boolean _connected;
137     private MulticastSocket _socket;
138     private InetAddress _address;
139 
140 }