Java Rsocket流式客户端
这是线程的延续。这是我的例子 我们目前有三个CORBA对象,如图中所示:Java Rsocket流式客户端,java,protocol-buffers,rsocket,Java,Protocol Buffers,Rsocket,这是线程的延续。这是我的例子 我们目前有三个CORBA对象,如图中所示: LoginObject(通过NamingService检索引用)。客户端可以调用login()方法来获取会话 Session对象有各种方法用于查询有关当前serivce上下文的详细信息,最重要的是用于获取事务对象 事务对象可以通过一个通用方法来执行各种命令,该方法将commandName和键值对列表作为参数。客户机执行n个命令后,他可以提交或回滚事务(也可以通过事务对象上的方法) 因此,这里我们使用会话对象在服务上执
- LoginObject(通过NamingService检索引用)。客户端可以调用login()方法来获取会话
- Session对象有各种方法用于查询有关当前serivce上下文的详细信息,最重要的是用于获取事务对象
- 事务对象可以通过一个通用方法来执行各种命令,该方法将commandName和键值对列表作为参数。客户机执行n个命令后,他可以提交或回滚事务(也可以通过事务对象上的方法)
message LoginRequest {
string username = 1;
string password = 2;
}
message LoginResponse {
bool success = 1;
}
message Command {
string command = 1;
}
message TransactionResult {
string result = 1;
}
service SimpleService {
rpc login (LoginRequest) returns (LoginResponse) {}
rpc transaction (stream Command) returns (TransactionResult) {}
}
这个想法是,一旦用户登录,他将开始将命令流传输到服务器。最后,客户端将提交或删除更改
下面是开始向服务器发送值的客户端代码:
public class SimpleClientWrapper {
SimpleServiceClient client;
...
public void runClient() {
SimpleServiceProto.LoginRequest login_request= SimpleServiceProto.LoginRequest.newBuilder().setUsername(this.username).setPassword(this.pass).build();
System.out.println("Trying to log in...");
client.login(login_request).doOnNext(response->{
if(response.getSuccess()) {
runCommands();
}else {
disconnect();
}
}).block();
}
public void runCommands() {
System.out.println("Login successfull. About to run some commands.");
Flux<Command> requests =
Flux.range(1, 11)
.map(i -> "sending -> " + i)
.map(s -> Command.newBuilder().setCommand(s).build());
TransactionResult response = client.transaction(requests).block();
System.out.println("Result was: " + response.getResult());
}
...
}
然而,我的问题不是它不工作,而是我希望每个客户机都有一个与服务器的会话,对于每个客户机,服务器都应该保持事务状态。以下是完整代码的git链接:
写了这么多之后,我的问题是:建立事务会话的正确方法是什么?我知道我的代码非常业余,所以我愿意接受任何类型的建议
@Override
public Mono<TransactionResult> transaction(Publisher<Command> messages, ByteBuf metadata) {
return Flux.from(messages)
.windowTimeout(10, Duration.ofSeconds(500))
.take(1)
.flatMap(Function.identity())
.reduce(
new ConcurrentHashMap<Character, AtomicInteger>(),
(map, s) -> {
char[] chars = s.getCommand().toCharArray();
for (char c : chars) {
map.computeIfAbsent(c, _c -> new AtomicInteger()).incrementAndGet();
}
return map;
})
.map(
map -> {
StringBuilder builder = new StringBuilder();
map.forEach(
(character, atomicInteger) -> {
builder
.append("character -> ")
.append(character)
.append(", count -> ")
.append(atomicInteger.get())
.append("\n");
});
String s = builder.toString();
return TransactionResult.newBuilder().setResult(s).build();
});
}
Exception in thread "main" java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-tcp-nio-4