这里把 （request / reponse）模式，或者（call / return）简称为：调用（call）。


### 1、发送（调用事件）与监听（调用事件）


```java
public class DemoApp {
    static String topic = "demo.hello";

    public static void main(String[] args) {
        //监听调用事件
        Dami.bus().listen(topic, (event, data, sink) -> {
            System.err.println(data);
            sink.complete("hi!");
        });
        
        //发送调用事件 - 等待风格
        String rst = Dami.bus().<String, String>call(topic, "hello").get();
        System.err.println(rst);
    
        //发送调用事件 - 回调风格
        bus.<String, String>call(topic, "world").whenComplete((rst, err) -> {
            System.out.println(rst);
        });
    }
}
```


提醒：事件监听的参数差别（开发工具通过参数个数，推断为不同的类型）：


| 事件      | 监听 lambda 参数                 | 对应监听器接口 |
| ------ | ----------------------- | -------- |
| send      | `(event)->{}`                         | EventListener     |
| call        | `(event, data, sink)->{}`         | CallEventListener     |
| stream   | `(event, att, data, sink)->{}`    | StreamEventListener     |



### 2、调用事件的内部处理

调用事件的内部同样是“通用事件”（仅是一种体验简化）。改成“通用事件”如下：


```java
public class DemoApp {
    static String topic = "demo.hello";

    public static void main(String[] args) {
        //监听调用事件
        Dami.bus().<CallPayload<String, String>>listen(topic, event -> {
            System.err.println(event.getPayload().getData());
            event.getPayload().getSink().complete("hi!");
        });

        //发送调用事件
        String rst = Dami.bus().<CallPayload<String, String>>send(topic, new CallPayload<>("hello"))
                               .getPayload()
                               .getSink() //:CompletableFuture<String>
                               .get();
        System.err.println(rst);
    }
}
```

如果要用通用事件监听所有事件（通过 payload 类型进行识别，并对应处理）：

```java
public class UniEventListener implements EventListener<Object> {
    @Override
    public void onEvent(Event<Object> event) throws Throwable {
        if (event.getPayload() instanceof CallPayload) {
            //is call
            System.err.println(event.<CallPayload>getPayloadAs().getData());
            event.<CallPayload>getPayloadAs().getSink().complete("hi!");
        } else if (event.getPayload() instanceof StreamPayload) {
            //is stream
        } else {
            //is send
        }
    }
}

//或者 lambda 方式：
public class DemoApp {
    static String topic = "demo.hello";
    
    public static void main(String[] args) {
        Dami.bus().listen(topic, event -> {
            if (event.getPayload() instanceof CallPayload) {
                //is call
                System.err.println(event.<CallPayload>getPayloadAs().getData());
                event.<CallPayload>getPayloadAs().getSink().complete("hi!");
            } else if (event.getPayload() instanceof StreamPayload) {
                //is stream
            } else {
                //is send
            }
        });
    }
}
```
