2014-08-19 14:02:23 +03:00
|
|
|
/**
|
2017-01-04 17:37:10 +01:00
|
|
|
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
2014-08-19 14:02:23 +03:00
|
|
|
*/
|
|
|
|
|
|
2017-03-16 09:30:00 +01:00
|
|
|
package jdocs.io;
|
2014-08-19 14:02:23 +03:00
|
|
|
|
|
|
|
|
//#imports
|
|
|
|
|
import akka.actor.ActorRef;
|
2017-02-04 11:51:30 +05:00
|
|
|
import akka.actor.AbstractActor;
|
2014-08-19 14:02:23 +03:00
|
|
|
import akka.event.Logging;
|
|
|
|
|
import akka.event.LoggingAdapter;
|
|
|
|
|
import akka.io.Inet;
|
|
|
|
|
import akka.io.Udp;
|
|
|
|
|
import akka.io.UdpMessage;
|
|
|
|
|
import akka.util.ByteString;
|
|
|
|
|
|
|
|
|
|
import java.net.InetAddress;
|
|
|
|
|
import java.net.InetSocketAddress;
|
|
|
|
|
import java.net.NetworkInterface;
|
|
|
|
|
import java.net.StandardProtocolFamily;
|
2015-04-30 09:23:18 +02:00
|
|
|
import java.net.DatagramSocket;
|
2014-08-19 14:02:23 +03:00
|
|
|
import java.nio.channels.DatagramChannel;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
//#imports
|
|
|
|
|
|
|
|
|
|
public class JavaUdpMulticast {
|
|
|
|
|
//#inet6-protocol-family
|
|
|
|
|
public static class Inet6ProtocolFamily extends Inet.DatagramChannelCreator {
|
|
|
|
|
@Override
|
|
|
|
|
public DatagramChannel create() throws Exception {
|
|
|
|
|
return DatagramChannel.open(StandardProtocolFamily.INET6);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#inet6-protocol-family
|
|
|
|
|
|
|
|
|
|
//#multicast-group
|
2015-04-30 09:23:18 +02:00
|
|
|
public static class MulticastGroup extends Inet.AbstractSocketOptionV2 {
|
2014-08-19 14:02:23 +03:00
|
|
|
private String address;
|
|
|
|
|
private String interf;
|
|
|
|
|
|
|
|
|
|
public MulticastGroup(String address, String interf) {
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.interf = interf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2015-04-30 09:23:18 +02:00
|
|
|
public void afterBind(DatagramSocket s) {
|
2014-08-19 14:02:23 +03:00
|
|
|
try {
|
|
|
|
|
InetAddress group = InetAddress.getByName(address);
|
|
|
|
|
NetworkInterface networkInterface = NetworkInterface.getByName(interf);
|
2015-04-30 09:23:18 +02:00
|
|
|
s.getChannel().join(group, networkInterface);
|
2014-08-19 14:02:23 +03:00
|
|
|
} catch (Exception ex) {
|
|
|
|
|
System.out.println("Unable to join multicast group.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#multicast-group
|
|
|
|
|
|
2017-02-04 11:51:30 +05:00
|
|
|
public static class Listener extends AbstractActor {
|
2017-03-16 09:30:00 +01:00
|
|
|
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
|
2014-08-19 14:02:23 +03:00
|
|
|
|
|
|
|
|
ActorRef sink;
|
|
|
|
|
|
|
|
|
|
public Listener(String iface, String group, Integer port, ActorRef sink) {
|
|
|
|
|
this.sink = sink;
|
|
|
|
|
|
|
|
|
|
//#bind
|
|
|
|
|
List<Inet.SocketOption> options = new ArrayList<>();
|
|
|
|
|
options.add(new Inet6ProtocolFamily());
|
|
|
|
|
options.add(new MulticastGroup(group, iface));
|
|
|
|
|
|
2017-03-16 09:30:00 +01:00
|
|
|
final ActorRef mgr = Udp.get(getContext().getSystem()).getManager();
|
2014-08-19 14:02:23 +03:00
|
|
|
// listen for datagrams on this address
|
|
|
|
|
InetSocketAddress endpoint = new InetSocketAddress(port);
|
2017-03-16 09:30:00 +01:00
|
|
|
mgr.tell(UdpMessage.bind(self(), endpoint, options), getSelf());
|
2014-08-19 14:02:23 +03:00
|
|
|
//#bind
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2017-02-04 11:51:30 +05:00
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(Udp.Bound.class, bound -> {
|
|
|
|
|
log.info("Bound to {}", bound.localAddress());
|
2017-03-16 09:30:00 +01:00
|
|
|
sink.tell(bound, getSelf());
|
2017-02-04 11:51:30 +05:00
|
|
|
})
|
|
|
|
|
.match(Udp.Received.class, received -> {
|
|
|
|
|
final String txt = received.data().decodeString("utf-8");
|
|
|
|
|
log.info("Received '{}' from {}", txt, received.sender());
|
2017-03-16 09:30:00 +01:00
|
|
|
sink.tell(txt, getSelf());
|
2017-02-04 11:51:30 +05:00
|
|
|
})
|
|
|
|
|
.build();
|
2014-08-19 14:02:23 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-04 11:51:30 +05:00
|
|
|
public static class Sender extends AbstractActor {
|
2017-03-16 09:30:00 +01:00
|
|
|
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
|
2014-08-19 14:02:23 +03:00
|
|
|
|
2014-09-05 10:17:57 +02:00
|
|
|
String iface;
|
2014-08-19 14:02:23 +03:00
|
|
|
String group;
|
|
|
|
|
Integer port;
|
|
|
|
|
String message;
|
|
|
|
|
|
2014-09-05 10:17:57 +02:00
|
|
|
public Sender(String iface, String group, Integer port, String msg) {
|
|
|
|
|
this.iface = iface;
|
2014-08-19 14:02:23 +03:00
|
|
|
this.group = group;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.message = msg;
|
|
|
|
|
|
|
|
|
|
List<Inet.SocketOption> options = new ArrayList<>();
|
|
|
|
|
options.add(new Inet6ProtocolFamily());
|
|
|
|
|
|
2017-03-16 09:30:00 +01:00
|
|
|
final ActorRef mgr = Udp.get(getContext().getSystem()).getManager();
|
|
|
|
|
mgr.tell(UdpMessage.simpleSender(options), getSelf());
|
2014-08-19 14:02:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2017-02-04 11:51:30 +05:00
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(Udp.SimpleSenderReady.class, x -> {
|
|
|
|
|
InetSocketAddress remote = new InetSocketAddress(group + "%" + iface, port);
|
|
|
|
|
log.info("Sending message to " + remote);
|
2017-03-16 09:30:00 +01:00
|
|
|
getSender().tell(UdpMessage.send(ByteString.fromString(message), remote), getSelf());
|
2017-02-04 11:51:30 +05:00
|
|
|
})
|
|
|
|
|
.build();
|
2014-08-19 14:02:23 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|