有状态Rsocket应用

时间:2019-05-03 11:15:31

标签: java reactive-programming rsocket

在我的项目中,我希望有多个客户端连接到服务。我正在使用Java Rsocket实现。

服务应为每个客户端维护一个状态。现在,我可以通过某些标识符来管理客户端。我已经实现了此选项。但是我不想使用字符串手动管理会话。

所以另一个想法是通过Rsocket连接来识别客户端。有没有一种方法可以使用Rsocket通道来识别特定客户端?

想象一个示例服务和几个客户。每个客户端都有Rsocket通道,其中的服务已启动并正在运行。有没有一种方法可以使用Rsocket通道在服务器端识别这些客户端?如果您可以显示此类行为的程序化示例,那就太神奇了。 谢谢!

编辑(更详细地说明情况)

这是我的例子。

我们目前有三个CORBA对象,如图所示:

  • LoginObject(通过NamingService检索引用)。客户可以调用login()方法来获取会话
  • Session对象具有多种方法来查询有关当前服务上下文的详细信息,并且最重要的是获取Transaction对象
  • 可以通过通用方法使用Transaction对象来执行各种命令,这些方法将commandName和键值对列表作为参数。 客户端执行n条命令后,他可以提交或回滚事务(也可以通过Transaction对象上的方法)。

enter image description here

所以在这里我们使用会话对象在我们的服务上执行事务。

现在,我们决定从CORBA转移到Rsocket。因此,我们需要Rsocket微服务能够存储会话的状态,否则我们将无法知道将要提交或回滚的内容。是否可以只为每个客户使用单独的Publisher?

3 个答案:

答案 0 :(得分:3)

这是我前几天做的一个示例,它将使用Netifi的代理创建有状态的RSocket: https://github.com/netifi/netifi-stateful-socket

不幸的是,您需要在本地构建我们的developer分支以进行尝试(https://github.com/netifi/netifi-java)-如果您不想在本地构建它,则应在本周末之前发布包含代码的版本。

我也正在研究一个纯RSocket示例,但是如果您想了解它如何看待示例中的StatefulSocket。它应该为您提供一个如何使用纯RSocket处理会话的线索。

关于交易管理器的其他问题-您需要将交易与正在发出的Reactive Streams信号相关联-如果收到取消,onError将回滚,并且收到onComplete提交交易。 Flux / Mono有一些副作用方法,应该可以轻松解决。根据您的操作,您还可以使用BaseSubscriber,因为它具有处理不同的Reactive Streams信号的钩子。

谢谢, 罗伯特

答案 1 :(得分:2)

恢复连接(即在服务器上维护状态)的示例已落入rsocket-java存储库

https://github.com/rsocket/rsocket-java/commit/d47629147dd1a4d41c7c8d5af3d80838e01d3ba5

简历将恢复整个连接,包括与每个单独通道等相关联的任何状态。

有一个rsocket-cli项目,您可以尝试一下。启动和停止socat进程,并观察客户端和服务器的进度。

$ socat -d TCP-LISTEN:5001,fork,reuseaddr TCP:localhost:5000
$ ./rsocket-cli --debug --resume --server -i cli:time tcp://localhost:5000
$ ./rsocket-cli -i client --stream --resume tcp://localhost:5001

答案 2 :(得分:0)

根据您的描述,channel似乎效果最好,我之前没有使用过频道,所以我不能保证(抱歉)。但是我建议您尝试这样的事情:

交易控制器:

public class TransactionController implements Publisher<Payload> {

    List<Transaction> transcations = new ArrayList<>();

    @Override
    public void subscribe(Subscriber<? super Payload> subscriber) {

    }

    public void processPayload(Payload payload) {
        // handle transcations...
    }
}

在您的RSocket实现中,请覆盖requestChannel

@Override
public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
    // Create new controller for each channel
    TranscationController cntrl = new TranscationController();
    Flux.from(payloads)
      .subscribe(cntrl::processPayload);
    return Flux.from(cntrl);
}