3

i am new to akka websockets and learning akka client side websockets https://doc.akka.io/docs/akka-http/current/client-side/websocket-support.html

i am using websockets for my webrtc janus server for that i have URL and i need to send many messages to it and receive a different response each time and send further messages based on that response here i am confused how can we do that by looking at the example code i think i need to repeat the below code every time i need to send a message to the server but it does not seemed correct si what is the right approach?

example in my case websocket server is running at ws://0.0.0.0:8188

first i will send a message to the server for initiating the sessionID

request# 1

{
        "janus" : "create",
        "transaction" : "<random alphanumeric string>"
}

the server will respond with the session id

response #1 
{
   "janus": "success",
   "session_id": 2630959283560140,
   "transaction": "asqeasd4as3d4asdasddas",
   "data": {
        "id": 4574061985075210
   }
}

then based on id 4574061985075210 i will send another message and receive further info

request # 02 {
 }

response # 02 {
}
----

how can i achieve this with akka client side websockets

here is my code

import akka.http.scaladsl.model.ws._

import scala.concurrent.Future

object WebSocketClientFlow {
  def main(args: Array[String]) = {
    implicit val system = ActorSystem()
    implicit val materializer = ActorMaterializer()
    import system.dispatcher

    val incoming: Sink[Message, Future[Done]] =
      Sink.foreach[Message] {
        case message: TextMessage.Strict =>
          println(message.text)
//suppose here based on the server response i need to send another message to the server and so on do i need to repeat this same code here again ?????   

      }

    val outgoing = Source.single(TextMessage("hello world!"))

    val webSocketFlow = Http().webSocketClientFlow(WebSocketRequest("ws://echo.websocket.org"))

    val (upgradeResponse, closed) =
      outgoing
        .viaMat(webSocketFlow)(Keep.right) // keep the materialized Future[WebSocketUpgradeResponse]
        .toMat(incoming)(Keep.both) // also keep the Future[Done]
        .run()

    val connected = upgradeResponse.flatMap { upgrade =>
      if (upgrade.response.status == StatusCodes.SwitchingProtocols) {
        Future.successful(Done)
      } else {
        throw new RuntimeException(s"Connection failed: ${upgrade.response.status}")
      }
    }

    connected.onComplete(println)
    closed.foreach(_ => println("closed"))
  }
}
swaheed
  • 3,671
  • 10
  • 42
  • 103
  • I personally prefer to use a different approach than akka-streams directly, which is to create an actor that represents the websocket connection to your server, there you should have a reference to an actor that represents the actual ws connection to the server, I haven't done this for the client side, but if this comment isn't enough, I can try playing a bit with it. The actor plays nicer because most times you have a mutable state between the connection to the websocket server. – AlexITC Aug 19 '20 at 02:14
  • It's been a long time since I touched akka-streams, another way could be to define the `outgoing` source before the `incoming` sink, so that the source is visible on the function processing the incoming messages, then, it should be hopefully simple to feed another item to such source stream (which would be automatically sent to your websocket server). – AlexITC Aug 19 '20 at 02:19
  • Apparently, this is what I was referring to in the first comment: https://doc.akka.io/docs/akka/current/stream/operators/ActorSource/actorRef.html – AlexITC Aug 19 '20 at 02:26
  • can you please explain your first comment with an example ,it might be more clearer for me and very helpful – swaheed Aug 19 '20 at 08:49
  • @AlexITC can you please look at it https://stackoverflow.com/questions/63505847/how-to-use-flow-map-in-akka-client-side-websocket-in-akka-streams – swaheed Aug 20 '20 at 13:24
  • I think this example does what you need, personally I feel is overcomplicated: https://github.com/ticofab/akka-http-websocket-example/blob/master/src/main/scala/io/ticofab/example/AkkaHttpWSExampleApp.scala – AlexITC Aug 20 '20 at 14:35

1 Answers1

0

I would recommend you goto this website and check out the documentation. IT has all the information you need.

https://doc.akka.io/docs/akka/current/typed/actors.html

Omar
  • 53
  • 7