简体   繁体   English

Scala akka-http WebSocket:如何保存客户端连接并在需要时将消息推送到客户端?

[英]Scala akka-http WebSocket: How to save the client connection and push message to the client when needed?

How to keep the client (web) connection in a memory variable and then send outgoing messages to the client (web) when needed? 如何将客户端(Web)连接保存在内存变量中,然后在需要时将外发消息发送到客户端(Web)?

I already have some simple code for pushing back message to the client once the server receives messages from the client. 我已经有一些简单的代码,用于在服务器从客户端接收消息后将消息推回客户端。 How to modify the code below for the outgoing messaging part? 如何为传出消息传递部分修改下面的代码?

implicit val actorSystem = ActorSystem("akka-system")
implicit val flowMaterializer = ActorMaterializer()
implicit val executionContext = actorSystem.dispatcher

val ip = "127.0.0.1"
val port = 32000

val route = get {
    pathEndOrSingleSlash {
        complete("Welcome to websocket server")
    }
} ~
path("hello") {
    get {
        handleWebSocketMessages(echoService)
    }
}

def sendMessageToClient(msg : String) {

    // *** How to implement this?
    // *** How to save the client connection when it is first connected?
    //     Then how to send message to this connection?

}

val echoService = Flow[Message].collect {

    // *** Here the server push back messages when receiving msg from client

    case tm : TextMessage => TextMessage(Source.single("Hello ") ++ tm.textStream)
    case _ => TextMessage("Message type unsupported")
}

val binding = Http().bindAndHandle(route, ip, port)

You can look into pipelining the sink flow via .map call. 您可以通过.map调用来查看对sink流进行流水线操作。 Inside the .map call you can capture the value and then return the same message. .map调用内,您可以捕获该值,然后返回相同的消息。 For example: 例如:

  Flow[Message].collect {
    case tm : TextMessage =>
      TextMessage(Source.single("Hello ") ++ tm.textStream.via(
        Flow[String].map((message) => {println(message) /* capture value here*/; message})))
    case _ => TextMessage("Message type unsupported")
  }

Now, if your intention is to process those values and send out values later, what you want is not a single source-to-sink flow, but two separate streams for sink and source, for which you can use Flow.fromSinkAndSource eg 现在,如果您打算处理这些值并稍后发送值,那么您想要的不是单个源到接收流,而是用于接收器和源的两个单独的流,您可以使用Flow.fromSinkAndSource例如

Flow.fromSinkAndSource[Message, Message](
  Flow[Message].collect { /* capture values */},
    // Or send stream to other sink for more processing
  source
)

In all likelihood, this source will be either constructed out of graph DSL, a hand-rolled actor, or you can look into utilizing reusable helpers such as MergeHub . 很有可能,这个源代码可以用图形DSL构建,也可以是手工制作的演员,也可以考虑使用MergeHub等可重用的助手。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM