package org.menacheri.zombie; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.channel.ChannelHandler; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.socket.DatagramChannel; import org.jboss.netty.channel.socket.DatagramChannelFactory; import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; import org.menacheri.jetserver.event.Events; import org.menacheri.jetserver.handlers.netty.EventDecoder; import org.menacheri.jetserver.util.NettyUtils; import org.menacheri.zombie.domain.IAM; public class UDPClient { private static final EventDecoder EVENT_DECODER = new EventDecoder(); private final ConnectionlessBootstrap b; private final IAM iam; private final SocketAddress serverAddress; public UDPClient(ChannelHandler businessHandler, IAM iam,String remoteHost, int remotePort,ExecutorService executorService) { this.iam = iam; this.serverAddress = new InetSocketAddress(remoteHost,remotePort); DatagramChannelFactory f = new NioDatagramChannelFactory(executorService); // Create only one bootstrap per instance. But use it to make multiple udp channels. b = new ConnectionlessBootstrap(f); ChannelPipeline p = b.getPipeline(); p.addLast("eventDecoder",EVENT_DECODER); p.addLast("businessHandler", businessHandler); b.setOption("broadcast", "true"); } public ConnectionlessBootstrap getConnectionlessBootstrap() { return b; } /** * Method used to create a datagram channel from the bootstrap instance. * @return * @throws UnknownHostException */ public DatagramChannel createDatagramChannel() throws UnknownHostException { String localHost = InetAddress.getLocalHost().getHostAddress(); DatagramChannel c = (DatagramChannel) b.bind( new InetSocketAddress(localHost,0)); return c; } public InetSocketAddress getLocalAddress(DatagramChannel c) { InetSocketAddress add = (InetSocketAddress)c.getLocalAddress(); return add; } public void start(DatagramChannel c) { try{ if(c.isBound()) { // Write the connect statement. TODO repeat till we get start. System.out.println("Events.CONNECT: " + Events.CONNECT); ChannelBuffer buf = NettyUtils.createBufferForOpcode(Events.CONNECT); ChannelFuture future = c.write(buf, serverAddress); future.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if(!future.isSuccess()) { System.out.println("CONNECT_UDP write to server unsuccessful: " + future.getCause().getMessage()); } } }); future.awaitUninterruptibly(); WriteByte write = new WriteByte(c, serverAddress,iam); ZombieClient.SERVICE.scheduleAtFixedRate(write,10000l,5000l, TimeUnit.MILLISECONDS); } else { System.out.println("Error: datagram channel is not bound"); } }catch(Exception e){ e.printStackTrace(); } } }