package org.rzo.netty.mcast;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.socket.DatagramChannel;
import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory;
public class MulticastEndpoint
{
private String mcastGroupIp = "228.10.10.10";
private int mcastGroupPort = 12345;
private String bindAddress = "192.168.0.10";
private DatagramChannel datagramChannel;
private ConnectionlessBootstrap connectionlessBootstrap;
private InetSocketAddress multicastAddress;
private static Executor executor = Executors.newCachedThreadPool();
byte[] id;
boolean init = false;
public void init(ChannelPipelineFactory factory) throws Exception
{
id = String.format("%1$020d", Math.abs(new Random(System.currentTimeMillis()).nextLong())).getBytes();
DatagramChannelFactory datagramChannelFactory = new
OioDatagramChannelFactory(executor);
connectionlessBootstrap = new
ConnectionlessBootstrap(datagramChannelFactory);
connectionlessBootstrap.setOption("broadcast", true);
connectionlessBootstrap.setPipelineFactory(factory);
datagramChannel = (DatagramChannel)
connectionlessBootstrap.bind(new InetSocketAddress(mcastGroupPort));
multicastAddress = new InetSocketAddress(mcastGroupIp, mcastGroupPort);
NetworkInterface networkInterface =
NetworkInterface.getByInetAddress(InetAddress.getByName(bindAddress));
datagramChannel.joinGroup(multicastAddress, networkInterface);
init = true;
}
public boolean isInit()
{
return init;
}
public void send(ChannelBuffer msg) throws Exception
{
ChannelBuffer idbuf = ChannelBuffers.wrappedBuffer(id);
datagramChannel.write(ChannelBuffers.wrappedBuffer(idbuf, msg), multicastAddress);
}
public String getMcastGroupIp()
{
return mcastGroupIp;
}
public int getMcastGroupPort()
{
return mcastGroupPort;
}
public String getBindAddress()
{
return bindAddress;
}
public void setMcastGroupIp(String mcastGroupIp)
{
this.mcastGroupIp = mcastGroupIp;
}
public void setMcastGroupPort(int mcastGroupPort)
{
this.mcastGroupPort = mcastGroupPort;
}
public void setBindAddress(String bindAddress)
{
this.bindAddress = bindAddress;
}
public void close()
{
datagramChannel.close();
connectionlessBootstrap.releaseExternalResources();
}
public ChannelBuffer getMessage(MessageEvent e)
{
if (checkMessage(e))
{
ChannelBuffer m = (ChannelBuffer) e.getMessage();
return m.slice(id.length, m.readableBytes()-id.length);
}
return null;
}
public String getStringMessage(MessageEvent e)
{
ChannelBuffer m = getMessage(e);
if (m == null)
return null;
return m.toString(Charset.defaultCharset());
}
public boolean checkMessage(MessageEvent e)
{
byte[] eId = new byte[id.length];
((ChannelBuffer) e.getMessage()).getBytes(0, eId, 0, eId.length);
return (! Arrays.equals(id, eId));
}
}