使用ActorPublisher源和重新连接WebSocketClientFlow时出现多个订户错误

时间:2018-05-18 20:45:17

标签: scala websocket akka actor akka-http

我正在使用Akka HTTP将 Actor WebSocket 客户端连接起来。该actor实现ActorPublisher[A]并将A的实例发布到源,该源在客户端WebSocket流中读取。

class Actor(...) extends Actor with ActorPublisher[A]

构建流程的代码如下:

import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.ws._
import akka.stream.ActorMaterializer
import akka.stream.actor.ActorPublisher
import akka.stream.scaladsl._

val actor = ...

// This method gets the actor and builds its the Akka Source
// Then opens the WebSocket using that source
def connect(): Unit = {
    val publisher = ActorPublisher[A](actor)
    val source = Source.fromPublisher(publisher)
    openWebSocket(source)
}

def openWebSocket(source: Source[A, NotUsed]): Unit = {
    val flow = Http().webSocketClientFlow(WebSocketRequest(URL))
    val (response, closed) = source
        .map { instanceOfA =>
            // Transform the instances of A to a message to send it through the websocket
            TextMessage(instanceOfA.asJson)
        }
        .viaMat(flow)(Keep.right)
        // Simple sink to print all incoming messages
        .toMat(Sink.foreach {
            case message: TextMessage.Strict => println(message.text)
        })(Keep.both)
        .run()

    // Reconnect if the socket is closed
    closed.foreach { _ =>
        connect()
    }
}

webSocketClientFlow是使用actor源和一个简单的非相关接收器构建的。它在插座关闭之前工作得很好。此时,再次调用connect方法。它从同一代理构建另一个并创建一个新的WebSocket流。问题是关闭的WebSocket流仍然订阅给actor,我得到以下错误创建新的:

java.lang.IllegalStateException: ActorPublisher only supports one subscriber (which is allowed, see reactive-streams specification, rule 1.12)
    at akka.stream.impl.ReactiveStreamsCompliance$.rejectAdditionalSubscriber(ReactiveStreamsCompliance.scala:59)
    at akka.stream.actor.ActorPublisher.aroundReceive(ActorPublisher.scala:312)
    at akka.stream.actor.ActorPublisher.aroundReceive$(ActorPublisher.scala:272)
    ...

如何告知代理商的取消订阅旧流程或来源?我正在停止代理并用新代理替换它,但这不是必需的。

0 个答案:

没有答案