dami - 定制“荷载”(payload)
1、使用定制“荷载”(payload)
此处借用框架内置的一个 “荷载” ReceivablePayload (一个普通的实体类),发送可以再接收响应。
public class ReceivablePayload<D,Rec> {
private final D data;
private final transient Rec sink;
public ReceivablePayload(D data, Rec sink) {
AssertUtil.notNull(sink, "The sink can not be null");
this.data = data;
this.sink = sink;
}
public D getData() { return data; }
public Rec getSink() { return sink; }
}
应用示例:
public class DemoApp {
static String topic = "demo.hello";
public static void main(String[] args) throws Exception {
//监听事件
Dami.bus().<ReceivablePayload<String, CompletableFuture<String>>>listen(topic, event -> {
System.err.println(event.getPayload().getData());
event.getPayload().getSink().complete("me to!");
});
//发送事件
String rst = Dami.bus().<ReceivablePayload<String, CompletableFuture<String>>>send(topic, new ReceivablePayload<>("{name:'noear',say:'hello'}", new CompletableFuture<>()))
.getPayload()
.getReceiver()
.get();
System.out.println(rst);
}
}
2、定制的演化
ReceivablePayload 提供了交互基础,但直接使用需要大串的泛型声明。下面使用另一个定制 “荷载” CallPayload,指定了 “接收器” 为 CompletableFuture,这样会简化些:
public class CallPayload<D,R> extends ReceivablePayload<D, CompletableFuture<R>> {
public CallPayload(D data) {
super(data, new CompletableFuture<>());
}
@Override
public CompletableFuture<R> getSink() { return super.getSink(); }
}
应用演进示例:
public class DemoApp {
static String topic = "demo.hello";
public static void main(String[] args) throws Exception {
//监听事件
Dami.bus().<CallPayload<String, String>>listen(topic, event -> {
System.err.println(event.getPayload().getData());
event.getPayload().getSink().complete("me to!");
});
//发送事件
String rst = Dami.bus().<CallPayload<String, String>>send(topic, new CallPayload<>("{name:'noear',say:'hello'}"))
.getPayload()
.getReceiver()
.get();
System.out.println(rst);
}
}
从框架的角度 “请求/响应” 这种模式是常见的存在。需要提供更简洁的体验。所以专门定制了简化接口:
public class DemoApp {
static String topic = "demo.hello";
public static void main(String[] args) throws Exception {
//监听事件
Dami.bus().<String, String>listen(topic, (event, content, receiver) -> {
System.err.println(content);
receiver.complete("me to!");
});
//发送事件
String rst = Dami.bus().<String, String>call(topic, "{name:'noear',say:'hello'}").get();
System.out.println(rst);
}
}
3、演化的终点,定制空接口(定制的过程,主要是固化泛型)
上面的杂乱主要是因为泛型的声明。下面以实现 call 效果为例,定制一个 DamiCall (名字随便取的)接口。
public interface DamiCall {
static DamiBus bus(){
return Dami.bus();
}
//发送调用事件
default <D, R> CompletableFuture<R> call(String topic, D data) {
return call(topic, data, null);
}
//发送调用事件
default <D, R> CompletableFuture<R> call(String topic, D data, Consumer<CompletableFuture<R>> fallback) {
return callAsResult(topic, data, fallback).getPayload().getSink();
}
//发送调用事件
default <D, R> Result<CallPayload<D, R>> callAsResult(String topic, D data) {
return callAsResult(topic, data, null);
}
//发送调用事件
default <D, R> Result<CallPayload<D, R>> callAsResult(String topic, D data, Consumer<CompletableFuture<R>> fallback) {
if (fallback == null) {
return bus().send(topic, new CallPayload<>(data));
} else {
return bus().send(topic, new CallPayload<>(data), r -> {
fallback.accept(r.getSink());
});
}
}
//监听调用事件
default <D, R> void listen(String topic, CallEventHandler<D, R> handler) {
listen(topic, 0, handler);
}
//监听调用事件
default <D, R> void listen(String topic, int index, CallEventHandler<D, R> handler) {
bus().<CallPayload<D, R>>listen(topic, index, event -> {
handler.onCall(event, event.getPayload().getData(), event.getPayload().getSink());
});
}
}
后续的应用效果:
public class DemoApp {
public static void main(String[] args) throws Exception {
DamiCall.<String,String>listen("demo.hello", (event, data, sink) -> {
sink.complete("hello " + data);
});
DamiCall.<String,String>call("demo.hello", "world");
}
}
也可以给 listen 换个名字,比如叫:onCall
(和 call 形成一对)
public class DemoApp {
public static void main(String[] args) throws Exception {
DamiCall.<String,String>onCall("demo.hello", (event, data, sink) -> {
sink.complete("hello " + data);
});
DamiCall.<String,String>call("demo.hello", "world");
}
}