Commit e30cfd1f authored by chiaming2000's avatar chiaming2000
Browse files

Improve multicast heartbeat implementation:

Simulator and Java API implementation will attempt to find a network
interface that supports multicast to send and receive heart beat
messages.  This avoids Java lib to use/bind a non-supported interface to
send and receive multicast messages. 
parent 4d84078b
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;

@@ -75,18 +78,51 @@ public class HeartbeatListener implements Runnable {

    private void init() throws IOException {

        // multicast group address
        // find network interface
        NetworkInterface ni = this.findNetworkInterface();

        // my multicast listening address
        mcastAddress = InetAddress.getByName(mcastDestination);

        // msocket
        mcastSocket = new MulticastSocket(mcastPort);

        // only set it if we are allowed to search
        if (ni != null) {
            mcastSocket.setNetworkInterface(ni);
        }

        // join the m group
        this.mcastSocket.joinGroup(mcastAddress);

        // listen in the background
        this.thread = new Thread(this);

        thread.start();
    }

    private NetworkInterface findNetworkInterface() {
        NetworkInterface ni = null;

        try {
            Enumeration<NetworkInterface> nis = NetworkInterface
                    .getNetworkInterfaces();

            while (nis.hasMoreElements()) {
                ni = nis.nextElement();
                if (ni.supportsMulticast() && ni.isUp()) {
                    logger.info("found interface that supports multicast: "
                            + ni.getDisplayName());
                    break;
                }
            }
        } catch (SocketException e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }

        return ni;
    }

    public void close() {
        this.isClosed = true;
        this.mcastSocket.close();
+36 −14
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -124,18 +125,15 @@ public class MulticastHeartbeatProvider implements HeartbeatProvider {
    private void doInit() {

        try {
            // this host name
            // this.thisHostIp =
            // InetAddress.getByName(thisHostIp).getHostAddress();

            // this host address
            // this.thisHostPort = this.thisHostIp + ":" + config.getPort() +
            // ":"
            // + config.getSslPort();

            // multicast socket
            mcastSocket = new MulticastSocket();

            NetworkInterface mni = findMulticastNetworkInterface();
            if (mni != null) {
                mcastSocket.setNetworkInterface(mni);
            }

            // multicast group address
            mcastAddress = InetAddress.getByName(mcastDestination);

@@ -145,11 +143,6 @@ public class MulticastHeartbeatProvider implements HeartbeatProvider {
            // init heart beat message
            this.initHeartbeatMessage();

            // logger.info("Heart beat initialized., my address="
            // + this.thisHostPort + ", tick time=" + config.getTickTime()
            // + " milli-secs, mcast Address=" + this.mcastDestination
            // + ":" + this.mcastPort);

        } catch (Exception e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }
@@ -255,4 +248,33 @@ public class MulticastHeartbeatProvider implements HeartbeatProvider {
        return sb.toString();
    }

    /**
     * Find a valid network interface that supports multicast.
     * 
     * @return a valid network interface that supports multicast. Or null if no
     *         network interface is found or no permission to do the search.
     */
    public static NetworkInterface findMulticastNetworkInterface() {

        NetworkInterface ni = null;

        try {
            Enumeration<NetworkInterface> nis = NetworkInterface
                    .getNetworkInterfaces();

            while (nis.hasMoreElements()) {
                ni = nis.nextElement();
                if (ni.supportsMulticast() && ni.isUp()) {
                    logger.info("found interface that supports multicast: "
                            + ni.getDisplayName());
                    break;
                }
            }
        } catch (SocketException e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }

        return ni;
    }

}