diff --git a/docs/examples/websocket.md b/docs/examples/websocket.md index 52d568361..a49a85ef6 100644 --- a/docs/examples/websocket.md +++ b/docs/examples/websocket.md @@ -21,12 +21,12 @@ Our WebSocketApp will handle the following events send by the client: * If the client sends "end", we will close the connection. * If the client sends any other message, we will send the same message back to the client 10 times. -For the client to establish a connection with the server, we offer the `/subscriptions` endpoint. +For the client to establish a connection with the server, we offer the `/subscriptions` endpoint: ```scala mdoc:passthrough import utils._ -printSource("zio-http-example/src/main/scala/example/WebSocketAdvanced.scala", lines=Seq((3, 7), (9, 60)), showLineNumbers=false) +printSource("zio-http-example/src/main/scala/example/websocket/WebSocketServerAdvanced.scala") ``` A few things worth noting: @@ -47,7 +47,7 @@ All we need for that, is the URL of the server. In our case it's `"ws://localhos ```scala mdoc:passthrough import utils._ -printSource("zio-http-example/src/main/scala/example/WebSocketAdvanced.scala", lines=Seq((3, 7), (62, 99)), showLineNumbers=false) +printSource("zio-http-example/src/main/scala/example/websocket/WebSocketClientAdvanced.scala") ``` While we access here `Queue[String]` via the ZIO environment, you should use a service in a real world application, that requires a queue as one of its constructor dependencies. @@ -59,5 +59,5 @@ See [ZIO Services](https://zio.dev/reference/service-pattern/) for more informat ```scala mdoc:passthrough import utils._ -printSource("zio-http-example/src/main/scala/example/WebSocketEcho.scala") +printSource("zio-http-example/src/main/scala/example/websocket/WebSocketEcho.scala") ``` diff --git a/docs/reference/client.md b/docs/reference/client.md index e334de922..fad0a1a28 100644 --- a/docs/reference/client.md +++ b/docs/reference/client.md @@ -511,5 +511,5 @@ This example represents a WebSocket client application that automatically attemp ```scala mdoc:passthrough import utils._ -printSource("zio-http-example/src/main/scala/example/WebSocketReconnectingClient.scala") +printSource("zio-http-example/src/main/scala/example/websocket/WebSocketReconnectingClient.scala") ``` diff --git a/zio-http-example/src/main/scala/example/websocket/WebSocketClientAdvanced.scala b/zio-http-example/src/main/scala/example/websocket/WebSocketClientAdvanced.scala new file mode 100644 index 000000000..8247b0195 --- /dev/null +++ b/zio-http-example/src/main/scala/example/websocket/WebSocketClientAdvanced.scala @@ -0,0 +1,48 @@ +package example.websocket +import scala.annotation.nowarn + +import zio._ + +import zio.http.ChannelEvent.Read +import zio.http._ + +object WebSocketSimpleClientAdvanced extends ZIOAppDefault { + + def sendChatMessage(message: String): ZIO[Queue[String], Throwable, Unit] = + ZIO.serviceWithZIO[Queue[String]](_.offer(message).unit) + + def processQueue(channel: WebSocketChannel): ZIO[Queue[String], Throwable, Unit] = { + for { + queue <- ZIO.service[Queue[String]] + msg <- queue.take + _ <- channel.send(Read(WebSocketFrame.Text(msg))) + } yield () + }.forever.forkDaemon.unit + + private def webSocketHandler: ZIO[Queue[String] with Client with Scope, Throwable, Response] = + Handler.webSocket { channel => + for { + _ <- processQueue(channel) + _ <- channel.receiveAll { + case Read(WebSocketFrame.Text(text)) => + Console.printLine(s"Server: $text") + case _ => + ZIO.unit + } + } yield () + }.connect("ws://localhost:8080/subscriptions") + + @nowarn("msg=dead code") + override val run = + ZIO + .scoped(for { + _ <- webSocketHandler + _ <- Console.readLine.flatMap(sendChatMessage).forever.forkDaemon + _ <- ZIO.never + } yield ()) + .provide( + Client.default, + ZLayer(Queue.bounded[String](100)), + ) + +} diff --git a/zio-http-example/src/main/scala/example/WebSocketEcho.scala b/zio-http-example/src/main/scala/example/websocket/WebSocketEcho.scala similarity index 97% rename from zio-http-example/src/main/scala/example/WebSocketEcho.scala rename to zio-http-example/src/main/scala/example/websocket/WebSocketEcho.scala index 245c722f3..0ba5dc00f 100644 --- a/zio-http-example/src/main/scala/example/WebSocketEcho.scala +++ b/zio-http-example/src/main/scala/example/websocket/WebSocketEcho.scala @@ -1,4 +1,4 @@ -package example +package example.websocket import zio._ diff --git a/zio-http-example/src/main/scala/example/WebSocketReconnectingClient.scala b/zio-http-example/src/main/scala/example/websocket/WebSocketReconnectingClient.scala similarity index 98% rename from zio-http-example/src/main/scala/example/WebSocketReconnectingClient.scala rename to zio-http-example/src/main/scala/example/websocket/WebSocketReconnectingClient.scala index 289267524..599ac554e 100644 --- a/zio-http-example/src/main/scala/example/WebSocketReconnectingClient.scala +++ b/zio-http-example/src/main/scala/example/websocket/WebSocketReconnectingClient.scala @@ -1,4 +1,4 @@ -package example +package example.websocket import zio._ diff --git a/zio-http-example/src/main/scala/example/WebSocketAdvanced.scala b/zio-http-example/src/main/scala/example/websocket/WebSocketServerAdvanced.scala similarity index 61% rename from zio-http-example/src/main/scala/example/WebSocketAdvanced.scala rename to zio-http-example/src/main/scala/example/websocket/WebSocketServerAdvanced.scala index 72b90aab7..19a98f343 100644 --- a/zio-http-example/src/main/scala/example/WebSocketAdvanced.scala +++ b/zio-http-example/src/main/scala/example/websocket/WebSocketServerAdvanced.scala @@ -1,4 +1,4 @@ -package example +package example.websocket import scala.annotation.nowarn @@ -8,7 +8,7 @@ import zio.http.ChannelEvent.{ExceptionCaught, Read, UserEvent, UserEventTrigger import zio.http._ import zio.http.codec.PathCodec.string -object WebSocketAdvanced extends ZIOAppDefault { +object WebSocketServerAdvanced extends ZIOAppDefault { val socketApp: WebSocketApp[Any] = Handler.webSocket { channel => @@ -60,44 +60,3 @@ object WebSocketAdvanced extends ZIOAppDefault { override val run = Server.serve(routes).provide(Server.default) } - -object WebSocketAdvancedClient extends ZIOAppDefault { - - def sendChatMessage(message: String): ZIO[Queue[String], Throwable, Unit] = - ZIO.serviceWithZIO[Queue[String]](_.offer(message).unit) - - def processQueue(channel: WebSocketChannel): ZIO[Queue[String], Throwable, Unit] = { - for { - queue <- ZIO.service[Queue[String]] - msg <- queue.take - _ <- channel.send(Read(WebSocketFrame.Text(msg))) - } yield () - }.forever.forkDaemon.unit - - private def webSocketHandler: ZIO[Queue[String] with Client with Scope, Throwable, Response] = - Handler.webSocket { channel => - for { - _ <- processQueue(channel) - _ <- channel.receiveAll { - case Read(WebSocketFrame.Text(text)) => - Console.printLine(s"Server: $text") - case _ => - ZIO.unit - } - } yield () - }.connect("ws://localhost:8080/subscriptions") - - @nowarn("msg=dead code") - override val run = - ZIO - .scoped(for { - _ <- webSocketHandler - _ <- Console.readLine.flatMap(sendChatMessage).forever.forkDaemon - _ <- ZIO.never - } yield ()) - .provide( - Client.default, - ZLayer(Queue.bounded[String](100)), - ) - -} diff --git a/zio-http-example/src/main/scala/example/WebSocketSimpleClient.scala b/zio-http-example/src/main/scala/example/websocket/WebSocketSimpleClient.scala similarity index 97% rename from zio-http-example/src/main/scala/example/WebSocketSimpleClient.scala rename to zio-http-example/src/main/scala/example/websocket/WebSocketSimpleClient.scala index 9e7dd8f17..798935e6c 100644 --- a/zio-http-example/src/main/scala/example/WebSocketSimpleClient.scala +++ b/zio-http-example/src/main/scala/example/websocket/WebSocketSimpleClient.scala @@ -1,4 +1,4 @@ -package example +package example.websocket import zio._