KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > remoting > detection > multicast > MulticastDetector


1 /***************************************
2  * *
3  * JBoss: The OpenSource J2EE WebOS *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  ***************************************/

9 package org.jboss.remoting.detection.multicast;
10
11 import java.io.ByteArrayInputStream JavaDoc;
12 import java.io.ByteArrayOutputStream JavaDoc;
13 import java.io.ObjectInputStream JavaDoc;
14 import java.io.ObjectOutputStream JavaDoc;
15 import java.net.DatagramPacket JavaDoc;
16 import java.net.InetAddress JavaDoc;
17 import java.net.MulticastSocket JavaDoc;
18 import org.jboss.remoting.detection.AbstractDetector;
19 import org.jboss.remoting.detection.Detection;
20
21 /**
22  * MulticastDetector is a remoting detector that broadcasts detection messages using
23  * muliticast. The default multicast ip is 224.1.9.1 and port 2410.
24  *
25  * @author <a HREF="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
26  * @author <a HREF="mailto:adrian.brock@happeningtimes.com">Adrian Brock</a>
27  * @author <a HREF="mailto:tom.elrod@jboss.com">Tom Elrod</a>
28  * @version $Revision: 1.4 $
29  */

30 public class MulticastDetector extends AbstractDetector implements MulticastDetectorMBean
31 {
32
33    private String JavaDoc defaultIP = "224.1.9.1";
34
35    private InetAddress JavaDoc addr;
36    private InetAddress JavaDoc bindAddr;
37    private int port = 2410;
38    private MulticastSocket JavaDoc socket;
39    private Listener listener = new Listener();
40
41
42    /**
43     * @return The IP that is used to broadcast detection messages on via multicast.
44     */

45    public String JavaDoc getDefaultIP()
46    {
47       return defaultIP;
48    }
49
50    /**
51     * @param defaultIP The IP that is used to broadcast detection messages on via multicast.
52     */

53    public void setDefaultIP(String JavaDoc defaultIP)
54    {
55       this.defaultIP = defaultIP;
56    }
57
58    /**
59     * return the multicast address of the detector
60     *
61     * @return
62     */

63    public InetAddress JavaDoc getAddress()
64    {
65       return addr;
66    }
67
68    /**
69     * set the interface address of the multicast
70     *
71     * @param ip
72     */

73    public void setAddress(InetAddress JavaDoc ip)
74    {
75       this.addr = ip;
76    }
77
78    /**
79     * return the bind address of the detector
80     *
81     * @return
82     */

83    public InetAddress JavaDoc getBindAddress()
84    {
85       return bindAddr;
86    }
87
88    /**
89     * set the bind address of the multicast
90     *
91     * @param ip
92     */

93    public void setBindAddress(InetAddress JavaDoc ip)
94    {
95       this.bindAddr = ip;
96    }
97
98    /**
99     * get the port that the detector is multicasting to
100     *
101     * @return
102     */

103    public int getPort()
104    {
105       return port;
106    }
107
108    /**
109     * set the port for detections to be multicast to
110     *
111     * @param port
112     */

113    public void setPort(int port)
114    {
115       this.port = port;
116    }
117
118    /**
119     * called by MBeanServer to start the mbean lifecycle
120     *
121     * @throws Exception
122     */

123    public void start() throws Exception JavaDoc
124    {
125       if(addr == null)
126       {
127          this.addr = InetAddress.getByName(defaultIP);
128       }
129       // check to see if we're running on a machine with loopback and no NIC
130
InetAddress JavaDoc localHost = InetAddress.getLocalHost();
131       if(bindAddr == null && localHost.getHostAddress().equals("127.0.0.1"))
132       {
133          // use this to bind so multicast will work w/o network
134
this.bindAddr = localHost;
135       }
136       socket = new MulticastSocket JavaDoc(port);
137       if(bindAddr != null)
138       {
139          socket.setInterface(bindAddr);
140       }
141       socket.joinGroup(addr);
142
143       super.start();
144
145       if(listener == null)
146       {
147          listener = new Listener();
148       }
149       listener.start();
150    }
151
152    /**
153     * called by the MBeanServer to stop the mbean lifecycle
154     *
155     * @throws Exception
156     */

157    public void stop() throws Exception JavaDoc
158    {
159       super.stop();
160       listener.running = false;
161       listener.interrupt();
162       listener = null;
163       socket.leaveGroup(addr);
164       socket.close();
165       socket = null;
166    }
167
168    /**
169     * subclasses must implement to provide the specific heartbeat protocol
170     * for this server to send out to other servers on the network
171     */

172    protected void heartbeat()
173    {
174       if(socket != null)
175       {
176          Detection msg = createDetection();
177          try
178          {
179             if(log.isTraceEnabled())
180             {
181                log.trace("sending heartbeat: " + msg);
182             }
183             ByteArrayOutputStream JavaDoc byteOut = new ByteArrayOutputStream JavaDoc();
184             ObjectOutputStream JavaDoc objectOut = new ObjectOutputStream JavaDoc(byteOut);
185             objectOut.writeObject(msg);
186             objectOut.flush();
187             byteOut.flush();
188             byte buf[] = byteOut.toByteArray();
189             DatagramPacket JavaDoc p = new DatagramPacket JavaDoc(buf, buf.length, addr, port);
190             socket.send(p);
191          }
192          catch(Throwable JavaDoc ex)
193          {
194             // its failed
195
log.debug("heartbeat failed", ex);
196          }
197       }
198    }
199
200    private void listen(DatagramPacket JavaDoc p, byte[] buf)
201    {
202       if(socket != null)
203       {
204          try
205          {
206             // should block until we get a multicast
207
socket.receive(p);
208
209             // take the multicast, and deserialize into the detection event
210
ByteArrayInputStream JavaDoc byteInput = new ByteArrayInputStream JavaDoc(buf);
211             ObjectInputStream JavaDoc objectInput = new ObjectInputStream JavaDoc(byteInput);
212             Detection msg = (Detection) objectInput.readObject();
213             if(log.isTraceEnabled())
214             {
215                log.trace("received detection: " + msg);
216             }
217
218             // let the subclass do the hard work off handling detection
219
detect(msg);
220          }
221          catch(Throwable JavaDoc e)
222          {
223             if(e instanceof java.io.InvalidClassException JavaDoc)
224             {
225                return;
226             }
227             if(socket != null)
228             {
229                log.debug("Error receiving detection", e);
230             }
231          }
232       }
233    }
234
235    private final class Listener extends Thread JavaDoc
236    {
237       boolean running = true;
238
239       public void run()
240       {
241          byte[] buf = new byte[4000];
242          DatagramPacket JavaDoc p = new DatagramPacket JavaDoc(buf, 0, buf.length);
243          //p.setAddress(addr);
244
//p.setPort(port);
245
while(running)
246          {
247             listen(p, buf);
248          }
249       }
250    }
251 }
252
Popular Tags