Java SDK支持链上信使协议AMOP(Advanced Messages Onchain Protocol),用户可以通过AMOP协议与其它机构互传消息。从这个表述上看,我们的应用可以当做即时消息系统使用,只不过这是依托链节点运行,类似于Kafka。
参考代码:
java-sdk-demo/src/main/java/org/fisco/bcos/sdk/demo/amop at main · FISCO-BCOS/java-sdk-demo · GitHub
本文完成了AMOP消息话题创建、发布、广播、订阅、应答功能代码实例,据此可以应用在项目工作中。
1 amop的功能流程图
2 广播消息特点
要说明的是单播消息具备回调函数,可以接收应答消息。广播消息不具备回调函数。
当只有一个链节点时, 广播一条消息,订阅者收到1条消息, 内容如下:
广播的消息:
==> try to broadcast message: welcome Mini!
订阅者收到的消息:
==> receive message from client
==> endpoint: 192.168.2.231:20200
==> seq: 724333b8512940ad9fb80245fccb26b5
==> data: welcome Mini!
当有2个节点时, 广播出来的消息变多了, 两个节点都广播一遍,还掺杂了seq为空的消息。因此,应用要对收到的广播消息去重。
广播的消息:
==> try to broadcast message: welcome Mini!
订阅者收到的消息:
==> receive message from client
==> endpoint: 192.168.2.231:20201
==> seq:
==> data: welcome Mini!
==> receive message from client
==> endpoint: 192.168.2.231:20200
==> seq:
==> data: welcome Mini!
==> receive message from client
==> endpoint: 192.168.2.231:20200
==> seq: 765b6a2769e64857b6b741daf40fd70c
==> data: welcome Mini!
==> receive message from client
==> endpoint: 192.168.2.231:20201
==> seq: 765b6a2769e64857b6b741daf40fd70c
==> data: welcome Mini!
3 示例代码
订阅者代码
package org.fisco.bcos.amop;
import org.fisco.bcos.node.FiscoBcos;
import org.fisco.bcos.sdk.jni.amop.AmopRequestCallback;
import org.fisco.bcos.sdk.v3.amop.Amop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Subscribe {
private static final Logger logger = LoggerFactory.getLogger(Subscribe.class);
public static void main(String[] args) throws Exception {
String topic = "HelloWorld";
System.out.println(" ====== AMOP subscribe, topic: " + topic);
FiscoBcos.initialize();
Amop amop = FiscoBcos.bcosSDK.getAmop();
amop.start();
// 简化写法
// amop.subscribeTopic(
// topic,
// (endpoint, seq, data) -> {
// System.out.println(" ==> receive message from client");
// System.out.println(" \t==> endpoint: " + endpoint);
// System.out.println(" \t==> seq: " + seq);
// System.out.println(" \t==> data: " + new String(data));
//
// amop.sendResponse(endpoint, seq, data);
// });
amop.subscribeTopic(
topic,
new AmopRequestCallback() {
@Override
public void onRequest(String endpoint, String seq, byte[] data) {
System.out.println(" ==> receive message from client");
System.out.println(" \t==> endpoint: " + endpoint);
System.out.println(" \t==> seq: " + seq);
System.out.println(" \t==> data: " + new String(data));
amop.sendResponse(endpoint, seq, data);
}
});
while (true) {
Thread.sleep(5000);
}
}
}
单播消息代码
package org.fisco.bcos.amop;
import org.fisco.bcos.node.FiscoBcos;
import org.fisco.bcos.sdk.jni.amop.AmopResponseCallback;
import org.fisco.bcos.sdk.jni.common.Response;
import org.fisco.bcos.sdk.v3.amop.Amop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Publish {
private static final Logger logger = LoggerFactory.getLogger(Publish.class);
public static void main(String[] args)
throws Exception {
String topic = "HelloWorld";
String msg = " welcome Tom!";
System.out.println(" ====== AMOP publish, topic: " + topic + " ,msg: " + msg);
FiscoBcos.initialize();
Amop amop = FiscoBcos.bcosSDK.getAmop();
amop.start();
//每5秒发送一次消息
while (true) {
System.out.println(" ====== AMOP publish send message");
amop.sendAmopMsg(
topic,
msg.getBytes(),
0,
new AmopResponseCallback() {
@Override
public void onResponse(Response response) {
System.out.println(" ==> receive response message from server");
if (response.getErrorCode() == 0) {
System.out.println(
" \t responseData: " + new String(response.getData()));
} else {
System.out.println(" \t errorCode: " + response.getErrorCode());
System.out.println(
" \t errorMessage: " + response.getErrorMessage());
}
}
});
Thread.sleep(5000);
}
}
}
广播消息代码:
package org.fisco.bcos.amop;
import org.fisco.bcos.node.FiscoBcos;
import org.fisco.bcos.sdk.v3.amop.Amop;
public class Broadcast {
public static void main(String[] args)
throws Exception {
String topic = "HelloWorld";
String msg = " welcome Mini!";
System.out.println(" ====== AMOP broadcast, topic: " + topic + " ,msg: " + msg);
FiscoBcos.initialize();
Amop amop = FiscoBcos.bcosSDK.getAmop();
amop.start();
while (true) {
System.out.println(" ==> try to broadcast message: " + msg);
amop.broadcastAmopMsg(topic, msg.getBytes());
Thread.sleep(10000);
}
}
}