从socko移动到akka-http websockets

时间:2016-05-26 19:12:54

标签: scala websocket akka akka-stream akka-http

我有一个基于socko websockets的现有akka应用程序。与套接字的通信发生在单个actor内,并且离开和进入actor的消息(分别是传入和传出消息)都标有套接字id,这是socko websocket的第一类属性(在socko中连接请求到达)用id标记,并且所有生命周期转换(如握手,断开连接,传入帧等)都标记为类似标记)

我想使用akka-http重新实现这个单独的演员(socko现在或多或少是放弃软件,显而易见的原因)但这并不简单,因为这两个库在概念上非常不同; akka-http隐藏了握手,断开连接等的较低级别细节,只需向http服务器绑定哪个actor即为UpgradeToWebsocket请求头。头对象包含一个方法,该方法将物化的Flow作为与客户端交换的所有消息的处理程序。

到目前为止,这么好;我能够在Web套接字上接收消息并直接回复它们。官方示例都假设某种无状态请求 - 回复模型,所以我正在努力理解如何为物化流程分配标签,管理其生命周期和连接状态(我需要通知其他参与者)的下一步客户端断开连接时的应用程序,以及标记消息。)

替代方案(使用akka-streams重新整理整个应用程序)是一项太大的工作,因此任何有关如何跟踪套接字的建议都将非常受欢迎。

2 个答案:

答案 0 :(得分:3)

要与现有的基于actor的系统连接,您应该查看Source.actorRefSink.actorRefSource.actorRef创建一个可以发送消息的ActorRef,Sink.actorRef允许您使用actor处理传入的消息,并检测websocket的关闭。

要将Source.actorRef创建的actor连接到现有的长寿演员,请使用Flow#mapMaterializedValue。这也是为套接字连接分配唯一ID的好地方。

answer to a related question可能会让您入门。

有一点需要注意。当使用websocket close message关闭客户端到服务器流时,当前的websocket实现关闭服务器到客户端流。有issue可以实现这一点,但在实施之前,您必须自己完成此操作。例如,在协议栈中使用something like this

答案 1 :(得分:2)

RüdigerKlaehn的回答是一个有用的起点,谢谢!

最后,我在此处阅读了另一个问题后tableView.keyboardDismissMode = .onDrag ActorPublisher。{/ p>

关键是在akka-http的引导下,Flow已经“物化”了,所以你需要将UpgradeToWebSocket.handleMessagesWithSinkSource传递给已经知道现有actor的Source / Sink对。所以我创建了一个actor(实现ActorPublisher[TextMessage.Strict]),然后将其包装在Source.fromPublisher(ActorPublisher(myActor))中。

如果要从actor的receive方法向流中注入消息,首先要检查totalDemand > 0(即流是否愿意接受输入),如果是,请调用{{1}与消息的内容。