服务端对客户端进行回调

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

特性说明

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

使用场景

回调函数通知客户端执行结果,或发送通知,在方法执行时间比较长时,类似异步调用,审批工作流中回调客户端审批结果。

使用方式

服务接口示例

CallbackService.java

1. package com.callback;

3. public interface CallbackService {
4. void addListener(String key, CallbackListener listener);
5. }

CallbackListener.java

1. package com.callback;

3. public interface CallbackListener {
4. void changed(String msg);
5. }

服务提供者接口实现示例

1. package com.callback.impl;

3. import java.text.SimpleDateFormat;
4. import java.util.Date;
5. import java.util.Map;
6. import java.util.concurrent.ConcurrentHashMap;

8. import com.callback.CallbackListener;
9. import com.callback.CallbackService;

11. public class CallbackServiceImpl implements CallbackService {

13. private final Map<String, CallbackListener> listeners = new ConcurrentHashMap<String, CallbackListener>();

15. public CallbackServiceImpl() {
16. Thread t = new Thread(new Runnable() {
17. public void run() {
18. while(true) {
19. try {
20. for(Map.Entry<String, CallbackListener> entry : listeners.entrySet()){
21. try {
22. entry.getValue().changed(getChanged(entry.getKey()));
23. } catch (Throwable t) {
24. listeners.remove(entry.getKey());
25. }
26. }
27. Thread.sleep(5000); // 定时触发变更通知
28. } catch (Throwable t) { // 防御容错
29. t.printStackTrace();
30. }
31. }
32. }
33. });
34. t.setDaemon(true);
35. t.start();
36. }

38. public void addListener(String key, CallbackListener listener) {
39. listeners.put(key, listener);
40. listener.changed(getChanged(key)); // 发送变更通知
41. }

43. private String getChanged(String key) {
44. return "Changed: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
45. }
46. }

服务提供者配置示例

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

服务消费者配置示例

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

服务消费者调用示例

1. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
2. context.start();

4. CallbackService callbackService = (CallbackService) context.getBean("callbackService");

6. callbackService.addListener("foo.bar", new CallbackListener(){
7. public void changed(String msg) {
8. System.out.println("callback1:" + msg);
9. }
10. });

最后修改 September 13, 2024: Refactor website structure (#2860) (1a4b998f54b)