将WebSocket从Play移动到Akka HTTP

时间:2016-09-20 14:22:30

标签: websocket akka-stream akka-http

我在Play应用程序中有一个WebSocket服务器,我想将它移动到akka-http服务。我目前正在使用ActorFlow.actorRef,这是Play中不存在的一部分。

当接受WebSocket时,我订阅了RabbitMQ队列,并将每条消息转发给WebSocket。当我收到来自WebSocket的消息时,我在本地处理一些消息并将其他人转发到RabbitMQ交换机。

我如何使用akka-http做同样的事情?我可以使用Sink.actorRef创建一个接收器并在那里处理入站消息,但是源代码呢?

我可以使用Source.actorRef创建一个源代码,但是如何获取访问者以便在实现时发送消息?是否有一种不同类型的源我应该用来从我的RabbitMQ订阅的foreach发送消息?

有了这些,看起来我可以使用Flow.fromSinkAndSource返回所需的流量。

1 个答案:

答案 0 :(得分:0)

我会解释你的要求

你有一个需要

的websocket终点
  1. 在本地处理一些请求并将响应发送回客户端
  2. 将一些请求转发给RabbitMQ
  3. 订阅rabbitMQ,并将来自rabbitMQ的消息转发给websocket客户端。
  4. 我的建议是,除非必要,避免演员,演员才是强大的,但我发现流更容易阅读并推理它何时适合模型

    下面是如何在没有actor

    的情况下管道Source和Sink的方法
    def wshandler: Flow[Message, Message, _] = {
        val rabbit = new Rabbit()
        val src =
          Source
            .actorRef(100, OverflowStrategy.dropBuffer)
            .mapMaterializedValue(ref => {
              rabbit
                .subscribe[String]("updates", queueName, topics) { 
                  (body, topic) =>
                    log.debug("Received from rabbit")
    
                    // here you forward everything from rabbitmq to    
                    // client using materialized actorRef
                    ref ! TextMessage(body)
                }
            })
    
        // you need to implement your own pattern matching logic to differentiate between request to process 
        // locally and request to route to rabbitMQ
        val sink = Sink.foreach[Message](m => m match {
          case localReq => // your request response processing logic
    
          case rabbitMq => // publish to rabbitMQ
        })
    
        Flow.fromSinkAndSource(sink, src)
      }
    

    此代码段并未实现您展示的任何要点,希望它能解决您的问题