Skip to main content

Examples Communication

Introduction

This article mainly introduces usage examples of the following communication models:

  • request/response, request/void
  • Broadcast
  • EventBus
  • request/multiple_response
tip

Request parameters in the communication model support int, long, bool, String, Object, List<Integer>, List<Long>, List<Boolean>, List<String>, List<YourClass>

Example Source Code

see https://github.com/iohao/ionet-examples

path : ionet-cookbook-code

  • InternalAction, the action used in this document to demonstrate internal requests
  • SendAction
  • FlowContextSendAction
  • CallAction
  • FlowContextCallAction
  • BroadcastAction
  • FlowContextBroadcastAction

Request/Response

In this section, we introduce internal requests, i.e., interaction between logic servers. Here, we explain the request/response series from the caller side. Requests between logic servers are handled through the call and send method families.

  • send corresponds to the request/void communication model.
  • call corresponds to the request/response communication model.

Send

The send series is used for internal requests without responses, corresponding to request/void. send is asynchronous because the request is known to have no response.

@ActionController(SendCmd.cmd)
public class SendAction {
private Communication communication() {
return CommunicationKit.getCommunication();
}

@ActionMethod(SendCmd.sendEmpty)
private boolean sendEmpty() {
var cmdInfo = InternalCmd.of(InternalCmd.sendEmptyAction);
communication().send(cmdInfo);
return true;
}

@ActionMethod(SendCmd.sendInt)
private boolean sendInt() {
var cmdInfo = InternalCmd.of(InternalCmd.sendIntAction);
int data = 1;

communication().send(cmdInfo, data);
return true;
}

@ActionMethod(SendCmd.sendBool)
private boolean sendBool() {
var cmdInfo = InternalCmd.of(InternalCmd.sendBoolAction);
boolean data = true;

communication().send(cmdInfo, data);
return true;
}

@ActionMethod(SendCmd.sendLong)
private boolean sendLong() {
var cmdInfo = InternalCmd.of(InternalCmd.sendLongAction);
long data = 1L;

communication().send(cmdInfo, data);
return true;
}

@ActionMethod(SendCmd.sendString)
private boolean sendString() {
var cmdInfo = InternalCmd.of(InternalCmd.sendStringAction);
String data = "hello";

communication().send(cmdInfo, data);
return true;
}

@ActionMethod(SendCmd.sendObject)
private boolean sendObject() {
var cmdInfo = InternalCmd.of(InternalCmd.sendObjectAction);
var data = new AuthorMessage();
data.authorName = "Joker";

communication().send(cmdInfo, data);
return true;
}

@ActionMethod(SendCmd.sendIntList)
private boolean sendIntList() {
var cmdInfo = InternalCmd.of(InternalCmd.sendIntListAction);
List<Integer> dataList = List.of(1, 2);

communication().sendListInt(cmdInfo, dataList);
return true;
}

@ActionMethod(SendCmd.sendBoolList)
private boolean sendBoolList() {
var cmdInfo = InternalCmd.of(InternalCmd.sendBoolListAction);
List<Boolean> dataList = List.of(true, false);

communication().sendListBool(cmdInfo, dataList);
return true;
}

@ActionMethod(SendCmd.sendLongList)
private boolean sendLongList() {
var cmdInfo = InternalCmd.of(InternalCmd.sendLongListAction);
List<Long> dataList = List.of(1L, 2L);

communication().sendListLong(cmdInfo, dataList);
return true;
}

@ActionMethod(SendCmd.sendStringList)
private boolean sendStringList() {
var cmdInfo = InternalCmd.of(InternalCmd.sendStringListAction);
List<String> dataList = List.of("hello", "ionet");

communication().sendListString(cmdInfo, dataList);
return true;
}

@ActionMethod(SendCmd.sendObjectList)
private boolean sendObjectList() {
var cmdInfo = InternalCmd.of(InternalCmd.sendObjectListAction);

var author1 = new AuthorMessage();
author1.authorName = "David Myers";

var author2 = new AuthorMessage();
author2.authorName = "Gustave Le Bon";

List<AuthorMessage> dataList = List.of(author1, author2);
communication().send(cmdInfo, dataList);
return true;
}
}

Call & CallAsync

The call series is used for internal requests with responses, corresponding to request/response.

  • call: synchronous call.
  • callAsync: asynchronous callback.
@ActionController(CallCmd.cmd)
public class CallAction {
private Communication communication() {
return CommunicationKit.getCommunication();
}

@ActionMethod(CallCmd.callEmpty)
private int callEmpty() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.emptyAction);

// Asynchronous callback
communication().callAsync(cmdInfo, response -> {
log.info("{}", response.getInt());
});

// Synchronous call
var response = communication().call(cmdInfo);
return response.getInt();
}

@ActionMethod(CallCmd.callInt)
private int callInt() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.intAction);
int data = 1;

// Asynchronous callback
communication().callAsync(cmdInfo, data, response -> {
log.info("{}", response.getInt());
});

// Synchronous call
var response = communication().call(cmdInfo, data);
return response.getInt();
}

@ActionMethod(CallCmd.callBool)
private boolean callBool() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.boolAction);
boolean data = true;

// Asynchronous callback
communication().callAsync(cmdInfo, data, response -> {
log.info("{}", response.getBoolean());
});

// Synchronous call
var response = communication().call(cmdInfo, data);
return response.getBoolean();
}

@ActionMethod(CallCmd.callLong)
private long callLong() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.longAction);
long data = 1L;

// Asynchronous callback
communication().callAsync(cmdInfo, data, response -> {
log.info("{}", response.getLong());
});

// Synchronous call
var response = communication().call(cmdInfo, data);
return response.getLong();
}

@ActionMethod(CallCmd.callString)
private String callString() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.stringAction);
String data = "hello";

// Asynchronous callback
communication().callAsync(cmdInfo, data, response -> {
log.info("{}", response.getString());
});

// Synchronous call
var response = communication().call(cmdInfo, data);
return response.getString();
}

@ActionMethod(CallCmd.callObject)
private BookMessage callObject() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.objectAction);
var data = new AuthorMessage();

// Asynchronous callback
communication().callAsync(cmdInfo, data, response -> {
log.info("{}", response.getValue(BookMessage.class));
});

// Synchronous call
var response = communication().call(cmdInfo, data);
return response.getValue(BookMessage.class);
}

@ActionMethod(CallCmd.callIntList)
private List<Integer> callIntList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.intListAction);
List<Integer> dataList = List.of(1, 2);

// Asynchronous callback
communication().callAsyncListInt(cmdInfo, dataList, response -> {
log.info("{}", response.listInt());
});

// Synchronous call
var response = communication().callListInt(cmdInfo, dataList);
return response.listInt();
}

@ActionMethod(CallCmd.callBoolList)
private List<Boolean> callBoolList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.boolListAction);
List<Boolean> dataList = List.of(true, false);

// Asynchronous callback
communication().callAsyncListBool(cmdInfo, dataList, response -> {
log.info("{}", response.listBoolean());
});

// Synchronous call
var response = communication().callListBool(cmdInfo, dataList);
return response.listBoolean();
}

@ActionMethod(CallCmd.callLongList)
private List<Long> callLongList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.longListAction);
List<Long> dataList = List.of(1L, 2L);

// Asynchronous callback
communication().callAsyncListLong(cmdInfo, dataList, response -> {
log.info("{}", response.listLong());
});

// Synchronous call
var response = communication().callListLong(cmdInfo, dataList);
return response.listLong();
}

@ActionMethod(CallCmd.callStringList)
private List<String> callStringList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.stringListAction);
List<String> dataList = List.of("hello", "ionet");

// Asynchronous callback
communication().callAsyncListString(cmdInfo, dataList, response -> {
log.info("{}", response.listString());
});

// Synchronous call
var response = communication().callListString(cmdInfo, dataList);
return response.listString();
}

@ActionMethod(CallCmd.callObjectList)
private List<BookMessage> callObjectList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.objectListAction);

var author1 = new AuthorMessage();
author1.authorName = "David Myers";

var author2 = new AuthorMessage();
author2.authorName = "Gustave Le Bon";

List<AuthorMessage> dataList = List.of(author1, author2);

// Asynchronous callback
communication().callAsync(cmdInfo, dataList, response -> {
log.info("{}", response.listValue(BookMessage.class));
});

// Synchronous call
var response = communication().call(cmdInfo, dataList);
return response.listValue(BookMessage.class);
}
}

Broadcast

This section demonstrates Broadcast, which is commonly used to actively send data to one user, multiple users, or all users on the server. For example:

  1. broadcastUser (single user): send rewards to a specified online user.
  2. broadcastUsers (multiple users): broadcast data to users in the same room. For example, when one user shoots a bullet, broadcast bullet data to other users in the room.
  3. broadcastMulticast (full server): broadcast messages to all online users on the server, such as announcements or maintenance notices.

broadcastUser

Broadcast to a specified single user. API names start with broadcastUser.

@ActionController(BroadcastCmd.cmd)
public class BroadcastAction {
AtomicInteger inc = new AtomicInteger();

@ActionMethod(triggerBroadcastUser)
private void triggerBroadcastUser(long userId) {
var communication = CommunicationKit.getCommunication();

// ---------- empty ----------
communication.broadcastUser(userId, BroadcastCmd.broadcastUserEmpty);

// ---------- int ----------
int dataInt = inc.getAndIncrement();
communication.broadcastUser(userId, BroadcastCmd.broadcastUserInt, dataInt);

// ---------- boolean ----------
boolean dataBool = inc.getAndIncrement() % 2 == 0;
communication.broadcastUser(userId, BroadcastCmd.broadcastUserBool, dataBool);

// ---------- long ----------
long dataLong = inc.getAndIncrement();
communication.broadcastUser(userId, BroadcastCmd.broadcastUserLong, dataLong);

// ---------- string ----------
String dataString = "ionet-" + inc.getAndIncrement();
communication.broadcastUser(userId, BroadcastCmd.broadcastUserString, dataString);

// ---------- object ----------
BookMessage dataObject = new BookMessage();
dataObject.authorName = "ionet";
dataObject.bookName = "book-" + inc.getAndIncrement();
communication.broadcastUser(userId, BroadcastCmd.broadcastUserObject, dataObject);

// ---------- list int ----------
List<Integer> dataListInt = List.of(inc.getAndIncrement(), inc.getAndIncrement());
communication.broadcastUserListInt(userId, BroadcastCmd.broadcastUserIntList, dataListInt);

// ---------- list boolean ----------
List<Boolean> dataListBool = List.of(
inc.getAndIncrement() % 2 == 0,
inc.getAndIncrement() % 2 == 0
);

communication.broadcastUserListBool(userId, BroadcastCmd.broadcastUserBoolList, dataListBool);

// ---------- list long ----------
List<Long> dataListLong = List.of(
(long) inc.getAndIncrement(),
(long) inc.getAndIncrement()
);

communication.broadcastUserListLong(userId, BroadcastCmd.broadcastUserLongList, dataListLong);

// ---------- list string ----------
List<String> dataListString = List.of(
"ionet-" + inc.getAndIncrement(),
"ionet-" + inc.getAndIncrement()
);

communication.broadcastUserListString(userId, BroadcastCmd.broadcastUserStringList, dataListString);

// ---------- list object ----------
BookMessage message1 = new BookMessage();
message1.authorName = "ionet";
message1.bookName = "book-" + inc.getAndIncrement();

BookMessage message2 = new BookMessage();
message2.authorName = "ionet";
message2.bookName = "book-" + inc.getAndIncrement();

List<BookMessage> dataList = List.of(message1, message2);
communication.broadcastUser(userId, BroadcastCmd.broadcastUserObjectList, dataList);
}
}

broadcastUsers

Broadcast to specified multiple users. API names start with broadcastUsers.

@ActionController(BroadcastCmd.cmd)
public class BroadcastAction {
AtomicInteger inc = new AtomicInteger();

@ActionMethod(triggerBroadcastUsers)
private void triggerBroadcastUsers(List<Long> userIdList) {
var communication = CommunicationKit.getCommunication();
// ---------- empty ----------
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersEmpty);
// ---------- int ----------
int dataInt = inc.getAndIncrement();
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersInt, dataInt);

// ---------- boolean ----------
boolean dataBool = inc.getAndIncrement() % 2 == 0;
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersBool, dataBool);

// ---------- long ----------
long dataLong = inc.getAndIncrement();
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersLong, dataLong);

// ---------- string ----------
String dataString = "ionet-" + inc.getAndIncrement();
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersString, dataString);

// ---------- object ----------
BookMessage dataObject = new BookMessage();
dataObject.authorName = "ionet";
dataObject.bookName = "book-" + inc.getAndIncrement();
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersObject, dataObject);

// ---------- list int ----------
List<Integer> dataListInt = List.of(inc.getAndIncrement(), inc.getAndIncrement());
communication.broadcastUsersListInt(userIdList, BroadcastCmd.broadcastUsersIntList, dataListInt);

// ---------- list boolean ----------
List<Boolean> dataListBool = List.of(
inc.getAndIncrement() % 2 == 0,
inc.getAndIncrement() % 2 == 0
);

communication.broadcastUsersListBool(userIdList, BroadcastCmd.broadcastUsersBoolList, dataListBool);

// ---------- list long ----------
List<Long> dataListLong = List.of(
(long) inc.getAndIncrement(),
(long) inc.getAndIncrement()
);

communication.broadcastUsersListLong(userIdList, BroadcastCmd.broadcastUsersLongList, dataListLong);

// ---------- list string ----------
List<String> dataListString = List.of(
"ionet-" + inc.getAndIncrement(),
"ionet-" + inc.getAndIncrement()
);

communication.broadcastUsersListString(userIdList, BroadcastCmd.broadcastUsersStringList, dataListString);

// ---------- list object ----------
BookMessage message1 = new BookMessage();
message1.authorName = "ionet";
message1.bookName = "book-" + inc.getAndIncrement();

BookMessage message2 = new BookMessage();
message2.authorName = "ionet";
message2.bookName = "book-" + inc.getAndIncrement();

List<BookMessage> dataList = List.of(message1, message2);
communication.broadcastUsers(userIdList, BroadcastCmd.broadcastUsersObjectList, dataList);
}
}

broadcastMulticast

Broadcast to everyone. API names start with broadcastMulticast.

@ActionController(BroadcastCmd.cmd)
public class BroadcastAction {
AtomicInteger inc = new AtomicInteger();

@ActionMethod(triggerBroadcastMulticast)
private void triggerBroadcastMulticast() {
var communication = CommunicationKit.getCommunication();
// ---------- empty ----------
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastEmpty);

// ---------- int ----------
int dataInt = inc.getAndIncrement();
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastInt, dataInt);

// ---------- boolean ----------
boolean dataBool = inc.getAndIncrement() % 2 == 0;
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastBool, dataBool);

// ---------- long ----------
long dataLong = inc.getAndIncrement();
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastLong, dataLong);

// ---------- string ----------
String dataString = "ionet-" + inc.getAndIncrement();
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastString, dataString);

// ---------- object ----------
BookMessage dataObject = new BookMessage();
dataObject.authorName = "ionet";
dataObject.bookName = "book-" + inc.getAndIncrement();
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastObject, dataObject);

// ---------- list int ----------
List<Integer> dataListInt = List.of(inc.getAndIncrement(), inc.getAndIncrement());
communication.broadcastMulticastListInt(BroadcastCmd.broadcastMulticastIntList, dataListInt);

// ---------- list boolean ----------
List<Boolean> dataListBool = List.of(
inc.getAndIncrement() % 2 == 0,
inc.getAndIncrement() % 2 == 0
);

communication.broadcastMulticastListBool(BroadcastCmd.broadcastMulticastBoolList, dataListBool);

// ---------- list long ----------
List<Long> dataListLong = List.of(
(long) inc.getAndIncrement(),
(long) inc.getAndIncrement()
);

communication.broadcastMulticastListLong(BroadcastCmd.broadcastMulticastLongList, dataListLong);

// ---------- list string ----------
List<String> dataListString = List.of(
"ionet-" + inc.getAndIncrement(),
"ionet-" + inc.getAndIncrement()
);

communication.broadcastMulticastListString(BroadcastCmd.broadcastMulticastStringList, dataListString);

// ---------- list object ----------
BookMessage message1 = new BookMessage();
message1.authorName = "ionet";
message1.bookName = "book-" + inc.getAndIncrement();

BookMessage message2 = new BookMessage();
message2.authorName = "ionet";
message2.bookName = "book-" + inc.getAndIncrement();

List<BookMessage> dataList = List.of(message1, message2);
communication.broadcastMulticast(BroadcastCmd.broadcastMulticastObjectList, dataList);
}
}

EventBus

warning

This is an enterprise feature

This section demonstrates usage of distributed event bus EventBus. With EventBus, lightweight cross-service event communication can be achieved.

@ActionController(EventBusCmd.cmd)
public class EventBusAction {
@ActionMethod(EventBusCmd.fire)
private boolean fire(FlowContext flowContext) {
long userId = flowContext.getUserId();

var message = UserLoginEventMessage.of(userId);
flowContext.fire(message);

return true;
}

@ActionMethod(EventBusCmd.fireAny)
private boolean fireAny(FlowContext flowContext) {
long userId = flowContext.getUserId();

var message = UserLoginEventMessage.of(userId);
flowContext.fireAny(message);

return true;
}

@ActionMethod(EventBusCmd.fireMe)
private boolean fireMe(FlowContext flowContext) {
long userId = flowContext.getUserId();

var message = UserLoginEventMessage.of(userId);
flowContext.fireMe(message);

return true;
}
}

RequestMultipleResponse

warning

This is an enterprise feature

This section introduces usage examples of request/multiple_response, which can collect results from multiple logic servers of the same type.

@ActionController(CallCollectCmd.cmd)
public class CallCollectAction {
private Communication communication() {
return CommunicationKit.getCommunication();
}

@ActionMethod(CallCollectCmd.callCollectEmpty)
private List<Integer> callCollectEmpty() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.intAction);

// Asynchronous callback
communication().callCollectAsync(cmdInfo, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.getInt());
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.map(Response::getInt)
.toList();
}

@ActionMethod(CallCollectCmd.callCollectInt)
private List<Integer> callInt() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.intAction);
int data = 1;

// Asynchronous callback
communication().callCollectAsync(cmdInfo, data, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.getInt());
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo, data);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.map(Response::getInt)
.toList();
}

@ActionMethod(CallCollectCmd.callCollectBool)
private List<Boolean> callBool() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.boolAction);
boolean data = true;

// Asynchronous callback
communication().callCollectAsync(cmdInfo, data, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.getBoolean());
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo, data);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.map(Response::getBoolean)
.toList();
}

@ActionMethod(CallCollectCmd.callCollectLong)
private List<Long> callLong() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.longAction);
long data = 1L;

// Asynchronous callback
communication().callCollectAsync(cmdInfo, data, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.getLong());
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo, data);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.map(Response::getLong)
.toList();
}

@ActionMethod(CallCollectCmd.callCollectString)
private List<String> callString() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.stringAction);
String data = "hello";

// Asynchronous callback
communication().callCollectAsync(cmdInfo, data, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.getString());
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo, data);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.map(Response::getString)
.toList();
}

@ActionMethod(CallCollectCmd.callCollectObject)
private List<BookMessage> callObject() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.objectAction);
var data = new AuthorMessage();

// Asynchronous callback
communication().callCollectAsync(cmdInfo, data, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.getValue(BookMessage.class));
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo, data);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.map(response -> response.getValue(BookMessage.class))
.toList();
}

@ActionMethod(CallCollectCmd.callCollectIntList)
private List<Integer> callIntList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.intListAction);
List<Integer> dataList = List.of(1, 2);

// Asynchronous callback
communication().callCollectAsyncListInt(cmdInfo, dataList, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.listInt());
}
});

var responseCollect = communication().callCollectListInt(cmdInfo, dataList);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.flatMap(response -> response.listInt().stream())
.toList();
}

@ActionMethod(CallCollectCmd.callCollectBoolList)
private List<Boolean> callBoolList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.boolListAction);
List<Boolean> dataList = List.of(true, false);

// Asynchronous callback
communication().callCollectAsyncListBool(cmdInfo, dataList, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.listBoolean());
}
});

// Synchronous call
var responseCollect = communication().callCollectListBool(cmdInfo, dataList);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.flatMap(response -> response.listBoolean().stream())
.toList();
}

@ActionMethod(CallCollectCmd.callCollectLongList)
private List<Long> callLongList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.longListAction);
List<Long> dataList = List.of(1L, 2L);

// Asynchronous callback
communication().callCollectAsyncListLong(cmdInfo, dataList, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.listLong());
}
});

// Synchronous call
var responseCollect = communication().callCollectListLong(cmdInfo, dataList);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.flatMap(response -> response.listLong().stream())
.toList();
}

@ActionMethod(CallCollectCmd.callCollectStringList)
private List<String> callStringList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.stringListAction);
List<String> dataList = List.of("hello", "ionet");

// Asynchronous callback
communication().callCollectAsyncListString(cmdInfo, dataList, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.listString());
}
});

// Synchronous call
var responseCollect = communication().callCollectListString(cmdInfo, dataList);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.flatMap(response -> response.listString().stream())
.toList();
}

@ActionMethod(CallCollectCmd.callCollectObjectList)
private List<BookMessage> callObjectList() {
// The two below are equivalent, one is synchronous and the other is asynchronous.
var cmdInfo = InternalCmd.of(InternalCmd.objectListAction);

var author1 = new AuthorMessage();
author1.authorName = "David Myers";

var author2 = new AuthorMessage();
author2.authorName = "Gustave Le Bon";

List<AuthorMessage> dataList = List.of(author1, author2);

// Asynchronous callback
communication().callCollectAsync(cmdInfo, dataList, responseCollect -> {
List<Response> responseList = responseCollect.getResponseList();
for (Response response : responseList) {
log.info("{}", response.listValue(BookMessage.class));
}
});

// Synchronous call
var responseCollect = communication().callCollect(cmdInfo, dataList);
List<Response> responseList = responseCollect.getResponseList();
return responseList.stream()
.flatMap(response -> response.listValue(BookMessage.class).stream())
.toList();
}
}