Socket.D v2.5.11

Listener 的增强应用

</> markdown
内置监听器
SimpleListener简单监听器Listener 的空实现
PipelineListener管道监听器Listener 的链式组织实现
EventListener事件监听器,根据消息事件路由(message::event)相当于消息的路由器
PathListener路径监听器,根据连接地址路由(session::path)相当于路径(频道)的路由器

1、SimpleListener(简单监听器)

就是一个空实现,上面已经有大量的使用示例。下面的都是链式写法,有些小伙伴可能不喜欢。

2、 EventListener(事件监听器,根据消息事件路由)

它相当于是事件(event)的路由器。可以直接在上面配置事件监听,也可以通过它做分发处理。

public class Demo {
    public static void main(String[] args) throws Throwable {
        //::启动服务端
        SocketD.createServer("sd:tcp")
                .config(c -> c.port(8602))
                .listen(new EventListener().doOnMessage((s,m)->{
                    System.out.println(m);
                    s.send("/demo", new StringEntity("Me too!"));
                }).doOn("/order", (s,m)->{ //根据消息事件路由
                    System.out.println(m); //在 onMessage 时已打印一次,这算第二次打印
                }).doOn("/user", (s,m)->{ //根据消息事件路由
                    System.out.println(m); //在 onMessage 时已打印一次,这算第二次打印
                }))
                .start();

        Thread.sleep(1000); //等会儿,确保服务端启动完成

        //::打开客户端会话
        ClientSession clientSession = SocketD.createClient("sd:tcp://127.0.0.1:8602/?u=a&p=2")
                .listen(new EventListener().doOnMessage((s, m) -> {
                    System.out.println(m);
                }).doOn("/demo", (s, m) -> { //根据消息事件路由
                    System.out.println(m);
                }))
                .open();
        
        clientSession.send("/order", new StringEntity("Hi"));
        clientSession.send("/user", new StringEntity("Hi"));
    }
}

3、 PipelineListener(管道监听器)

public class Demo {
    public static void main(String[] args) throws Throwable {
        //::启动服务端
        SocketD.createServer("sd:udp")
                .config(c -> c.port(8602))
                .listen(new PipelineListener().next(new EventListener().doOnMessage((s, m) -> {
                    //这里可以做拦截
                    System.out.println("拦截打印::" + m);
                })).next(new EventListener().doOnMessage((s, m) -> {
                    //这里可以做业务处理
                    System.out.println(m);
                })))
                .start();

        Thread.sleep(1000); //等会儿,确保服务端启动完成

        //::打开客户端会话
        ClientSession clientSession = SocketD.createClient("sd:udp://127.0.0.1:8602/hello?u=a&p=2")
                .open();

        clientSession.send("/demo", new StringEntity("Hi"));
    }
}

4、 PathListener(路径监听器,根据连接地址路由)

它相当于是连接地址(path)的路由器,可以起到频道隔离的效果。不过,在 Broker 集群模式下可能用处不大。

public class Demo04_Router {
    public static void main(String[] args) throws Throwable {
        //::启动服务端
        SocketD.createServer("sd:tcp")
            .config(c -> c.port(8602))
            .listen(new PathListener()
                    .doOf("/", new EventListener().doOnMessage((s, m) -> {
                        //用户频道
                        System.out.println("user::" + m);
                    }))
                    .doOf("/admin", new EventListener()
                            .doOnOpen(s -> {
                                //管理员频道
                                if ("admin".equals(s.param("u")) == false) {
                                    s.close();
                                }
                            }).doOnMessage((s, m) -> {
                                System.out.println("admin::" + m);
                            })
                    )
            )
            .start();

        Thread.sleep(1000); //等会儿,确保服务端启动完成

        //::打开客户端会话
        //用户频道(链接地址的 path ,算为频道)
        ClientSession clientSession1 = SocketD.createClient("sd:tcp://127.0.0.1:8602/?u=a&p=2").open();
        clientSession1.send("/demo", new StringEntity("Hi"));

        //管理员频道(链接地址的 path ,算为频道)
        ClientSession clientSession2 = SocketD.createClient("sd:tcp://127.0.0.1:8602/admin?u=a&p=2").open();
        clientSession2.send("/demo", new StringEntity("Hi"));
    }
}