参数回调

    通过参数回调从服务器端调用客户端逻辑

    参数回调方式与调用本地 callback 或 listener 相同,只需要在 Spring 的配置文件中声明哪个参数是 callback 类型即可。Dubbo 将基于长连接生成反向代理,这样就可以从服务器端调用客户端逻辑。可以参考 dubbo 项目中的示例代码

    服务接口示例

    CallbackService.java
    package com.callback;
     
    public interface CallbackService {
        void addListener(String key, CallbackListener listener);
    }
    
    CallbackListener.java
    package com.callback;
     
    public interface CallbackListener {
        void changed(String msg);
    }
    

    服务提供者接口实现示例

    package com.callback.impl;
     
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
     
    import com.callback.CallbackListener;
    import com.callback.CallbackService;
     
    public class CallbackServiceImpl implements CallbackService {
         
        private final Map<String, CallbackListener> listeners = new ConcurrentHashMap<String, CallbackListener>();
      
        public CallbackServiceImpl() {
            Thread t = new Thread(new Runnable() {
                public void run() {
                    while(true) {
                        try {
                            for(Map.Entry<String, CallbackListener> entry : listeners.entrySet()){
                               try {
                                   entry.getValue().changed(getChanged(entry.getKey()));
                               } catch (Throwable t) {
                                   listeners.remove(entry.getKey());
                               }
                            }
                            Thread.sleep(5000); // 定时触发变更通知
                        } catch (Throwable t) { // 防御容错
                            t.printStackTrace();
                        }
                    }
                }
            });
            t.setDaemon(true);
            t.start();
        }
      
        public void addListener(String key, CallbackListener listener) {
            listeners.put(key, listener);
            listener.changed(getChanged(key)); // 发送变更通知
        }
         
        private String getChanged(String key) {
            return "Changed: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        }
    }
    

    服务提供者配置示例

    <bean id="callbackService" class="com.callback.impl.CallbackServiceImpl" />
    <dubbo:service interface="com.callback.CallbackService" ref="callbackService" connections="1" callbacks="1000">
        <dubbo:method name="addListener">
            <dubbo:argument index="1" callback="true" />
            <!--也可以通过指定类型的方式-->
            <!--<dubbo:argument type="com.demo.CallbackListener" callback="true" />-->
        </dubbo:method>
    </dubbo:service>
    

    服务消费者配置示例

    <dubbo:reference id="callbackService" interface="com.callback.CallbackService" />
    

    服务消费者调用示例

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
    context.start();
     
    CallbackService callbackService = (CallbackService) context.getBean("callbackService");
     
    callbackService.addListener("foo.bar", new CallbackListener(){
        public void changed(String msg) {
            System.out.println("callback1:" + msg);
        }
    });