2013-02-15 11:47:46 +01:00
|
|
|
/**
|
2017-01-04 17:37:10 +01:00
|
|
|
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
2013-02-15 11:47:46 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package docs.io;
|
|
|
|
|
|
|
|
|
|
//#imports
|
|
|
|
|
import akka.actor.ActorRef;
|
2013-05-26 18:29:23 +02:00
|
|
|
import akka.actor.PoisonPill;
|
2017-02-04 11:51:30 +05:00
|
|
|
import akka.actor.AbstractActor;
|
2013-03-25 10:02:50 +01:00
|
|
|
import akka.io.Udp;
|
2013-05-26 18:29:23 +02:00
|
|
|
import akka.io.UdpConnected;
|
|
|
|
|
import akka.io.UdpConnectedMessage;
|
2013-03-25 10:02:50 +01:00
|
|
|
import akka.io.UdpMessage;
|
2013-05-26 18:29:23 +02:00
|
|
|
import akka.japi.Procedure;
|
2013-02-15 11:47:46 +01:00
|
|
|
import akka.util.ByteString;
|
|
|
|
|
|
|
|
|
|
import java.net.InetSocketAddress;
|
|
|
|
|
//#imports
|
|
|
|
|
|
2013-03-25 10:02:50 +01:00
|
|
|
public class UdpDocTest {
|
2013-05-02 17:12:36 +02:00
|
|
|
|
2013-05-26 18:29:23 +02:00
|
|
|
//#sender
|
2017-02-04 11:51:30 +05:00
|
|
|
public static class SimpleSender extends AbstractActor {
|
2013-05-26 18:29:23 +02:00
|
|
|
final InetSocketAddress remote;
|
2013-05-02 17:12:36 +02:00
|
|
|
|
2013-05-26 18:29:23 +02:00
|
|
|
public SimpleSender(InetSocketAddress remote) {
|
|
|
|
|
this.remote = remote;
|
|
|
|
|
|
|
|
|
|
// request creation of a SimpleSender
|
|
|
|
|
final ActorRef mgr = Udp.get(getContext().system()).getManager();
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
mgr.tell(UdpMessage.simpleSender(), self());
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2017-02-04 11:51:30 +05:00
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(Udp.SimpleSenderReady.class, message -> {
|
|
|
|
|
getContext().become(ready(sender()));
|
|
|
|
|
//#sender
|
|
|
|
|
sender().tell(UdpMessage.send(ByteString.fromString("hello"), remote), self());
|
|
|
|
|
//#sender
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-04 11:51:30 +05:00
|
|
|
private Receive ready(final ActorRef send) {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(String.class, message -> {
|
|
|
|
|
send.tell(UdpMessage.send(ByteString.fromString(message), remote), self());
|
|
|
|
|
//#sender
|
|
|
|
|
if (message.equals("world")) {
|
|
|
|
|
send.tell(PoisonPill.getInstance(), self());
|
|
|
|
|
}
|
|
|
|
|
//#sender
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2013-02-15 11:47:46 +01:00
|
|
|
}
|
2013-05-02 17:12:36 +02:00
|
|
|
}
|
2013-05-26 18:29:23 +02:00
|
|
|
//#sender
|
|
|
|
|
|
|
|
|
|
//#listener
|
2017-02-04 11:51:30 +05:00
|
|
|
public static class Listener extends AbstractActor {
|
2013-05-26 18:29:23 +02:00
|
|
|
final ActorRef nextActor;
|
|
|
|
|
|
|
|
|
|
public Listener(ActorRef nextActor) {
|
|
|
|
|
this.nextActor = nextActor;
|
|
|
|
|
|
|
|
|
|
// request creation of a bound listen socket
|
|
|
|
|
final ActorRef mgr = Udp.get(getContext().system()).getManager();
|
|
|
|
|
mgr.tell(
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
UdpMessage.bind(self(), new InetSocketAddress("localhost", 0)),
|
|
|
|
|
self());
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
2013-02-15 11:47:46 +01:00
|
|
|
|
2013-05-26 18:29:23 +02:00
|
|
|
@Override
|
2017-02-04 11:51:30 +05:00
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(Udp.Bound.class, bound -> {
|
|
|
|
|
//#listener
|
|
|
|
|
nextActor.tell(bound.localAddress(), sender());
|
|
|
|
|
//#listener
|
|
|
|
|
getContext().become(ready(sender()));
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
2017-02-04 11:51:30 +05:00
|
|
|
|
|
|
|
|
private Receive ready(final ActorRef socket) {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(Udp.Received.class, r -> {
|
|
|
|
|
// echo server example: send back the data
|
|
|
|
|
socket.tell(UdpMessage.send(r.data(), r.sender()), self());
|
|
|
|
|
// or do some processing and forward it on
|
|
|
|
|
final Object processed = // parse data etc., e.g. using PipelineStage
|
|
|
|
|
// #listener
|
|
|
|
|
r.data().utf8String();
|
|
|
|
|
//#listener
|
|
|
|
|
nextActor.tell(processed, self());
|
|
|
|
|
})
|
|
|
|
|
.matchEquals(UdpMessage.unbind(), message -> {
|
|
|
|
|
socket.tell(message, self());
|
|
|
|
|
})
|
|
|
|
|
.match(Udp.Unbound.class, message -> {
|
|
|
|
|
getContext().stop(self());
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#listener
|
|
|
|
|
|
|
|
|
|
//#connected
|
2017-02-04 11:51:30 +05:00
|
|
|
public static class Connected extends AbstractActor {
|
2013-05-26 18:29:23 +02:00
|
|
|
final InetSocketAddress remote;
|
|
|
|
|
|
|
|
|
|
public Connected(InetSocketAddress remote) {
|
|
|
|
|
this.remote = remote;
|
|
|
|
|
|
|
|
|
|
// create a restricted a.k.a. “connected” socket
|
|
|
|
|
final ActorRef mgr = UdpConnected.get(getContext().system()).getManager();
|
improve AbstractActor, #21717
* Receive class that wraps PartialFunction, to avoid
scary scala types
* move AbstractActorContext to AbstractActor.ActorContext
* converting docs, many, many UntypedActor
* removing UntypedActor docs
* add unit test for ReceiveBuilder
* MiMa filters
* consistent use of getContext(), self(), sender()
* rename cross references
* migration guide
* skip samples for now
* improve match type safetyi, add matchUnchecked
* the `? extends P` caused code like this to compile:
`match(String.class, (Integer i) -> {})`
* added matchUnchecked, since it can still be useful (um, convenient)
to be able to do:
`matchUnchecked(List.class, (List<String> list) -> {})`
* eleminate some scala.Option
* preRestart
* findChild
* ActorIdentity.getActorRef
2016-12-13 10:59:29 +01:00
|
|
|
mgr.tell(UdpConnectedMessage.connect(self(), remote), self());
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
2017-02-04 11:51:30 +05:00
|
|
|
|
2013-05-26 18:29:23 +02:00
|
|
|
@Override
|
2017-02-04 11:51:30 +05:00
|
|
|
public Receive createReceive() {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(UdpConnected.Connected.class, message -> {
|
|
|
|
|
getContext().become(ready(sender()));
|
|
|
|
|
//#connected
|
|
|
|
|
sender()
|
2013-05-26 18:29:23 +02:00
|
|
|
.tell(UdpConnectedMessage.send(ByteString.fromString("hello")),
|
2017-02-04 11:51:30 +05:00
|
|
|
self());
|
|
|
|
|
//#connected
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
2017-02-04 11:51:30 +05:00
|
|
|
|
|
|
|
|
private Receive ready(final ActorRef connection) {
|
|
|
|
|
return receiveBuilder()
|
|
|
|
|
.match(UdpConnected.Received.class, r -> {
|
|
|
|
|
// process data, send it on, etc.
|
|
|
|
|
// #connected
|
|
|
|
|
if (r.data().utf8String().equals("hello")) {
|
|
|
|
|
connection.tell(
|
|
|
|
|
UdpConnectedMessage.send(ByteString.fromString("world")),
|
|
|
|
|
self());
|
|
|
|
|
}
|
|
|
|
|
// #connected
|
|
|
|
|
})
|
|
|
|
|
.match(String.class, str -> {
|
|
|
|
|
connection
|
|
|
|
|
.tell(UdpConnectedMessage.send(ByteString.fromString(str)),
|
|
|
|
|
self());
|
|
|
|
|
})
|
|
|
|
|
.matchEquals(UdpConnectedMessage.disconnect(), message -> {
|
|
|
|
|
connection.tell(message, self());
|
|
|
|
|
})
|
|
|
|
|
.match(UdpConnected.Disconnected.class, x -> {
|
|
|
|
|
getContext().stop(self());
|
|
|
|
|
})
|
|
|
|
|
.build();
|
2013-05-26 18:29:23 +02:00
|
|
|
}
|
2013-05-02 17:12:36 +02:00
|
|
|
}
|
2013-05-26 18:29:23 +02:00
|
|
|
//#connected
|
2013-02-15 11:47:46 +01:00
|
|
|
|
|
|
|
|
}
|