-
Notifications
You must be signed in to change notification settings - Fork 422
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change default zio-http configuration so that ws close frames are for…
…warded to Tapir's code; also fix vertx (#4242)
- Loading branch information
Showing
18 changed files
with
210 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
examples/src/main/scala/sttp/tapir/examples/websocket/WebSocketZioHttpServer.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// {cat=WebSocket; effects=ZIO; server=zio-http}: Describe and implement a WebSocket endpoint, being notified on the server-side that a client closed the socket | ||
|
||
//> using dep com.softwaremill.sttp.tapir::tapir-core:1.11.11 | ||
//> using dep com.softwaremill.sttp.tapir::tapir-zio-http-server:1.11.11 | ||
//> using dep com.softwaremill.sttp.tapir::tapir-zio:1.11.11 | ||
|
||
package sttp.tapir.examples.websocket | ||
|
||
import sttp.capabilities.WebSockets | ||
import sttp.capabilities.zio.ZioStreams | ||
import sttp.tapir.generic.auto.* | ||
import sttp.tapir.server.ziohttp.ZioHttpInterpreter | ||
import sttp.tapir.ztapir.* | ||
import sttp.tapir.{Codec, CodecFormat, DecodeResult, PublicEndpoint} | ||
import sttp.ws.WebSocketFrame | ||
import zio.http.{Response as ZioHttpResponse, Routes, Server} | ||
import zio.stream.Stream | ||
import zio.{Console, ExitCode, URIO, ZIO, ZIOAppDefault, ZLayer} | ||
|
||
// After running, try opening a ws connection to ws://localhost:8080/ws, sending some text messages, and then closing | ||
// from the client-side. | ||
|
||
object WebSocketZioHttpServer extends ZIOAppDefault: | ||
enum ClientMessage: | ||
case Leave | ||
case Message(text: String) | ||
|
||
val wsEndpoint: PublicEndpoint[Unit, Unit, ZioStreams.Pipe[ClientMessage, Option[String]], ZioStreams & WebSockets] = | ||
endpoint.get | ||
.in("ws") | ||
.out( | ||
webSocketBody[ClientMessage, CodecFormat.TextPlain, Option[String], CodecFormat.TextPlain](ZioStreams) | ||
// the schema for the `ClientMessage` type is derived as non-optional, that's why we need to explicitly | ||
// request that close frames should be passed for decoding as well | ||
// the response type is optional, so we don't need to do that, and a `None` will be encoded as a close | ||
// frame using the default codec | ||
.decodeCloseRequests(true) | ||
) | ||
|
||
val wsServerEndpoint = wsEndpoint.zServerLogic[Any](_ => | ||
ZIO.succeed { (clientMessageStream: Stream[Throwable, ClientMessage]) => | ||
clientMessageStream.mapZIO { | ||
case ClientMessage.Leave => Console.printLine("Received a 'leave' message, the socket was closed by the client").map(_ => None) | ||
case ClientMessage.Message(text) => Console.printLine(s"Received: '$text' message").map(_ => Some("OK")) | ||
} | ||
} | ||
) | ||
|
||
// as we are using a custom high-level type for representing incoming requests from the client, we need to provide | ||
// a codec which knows how to translate WebSocket frames to instances of ClientMessage | ||
given wsFrameCodec: Codec[WebSocketFrame, ClientMessage, CodecFormat.TextPlain] = | ||
val baseStringCodec = Codec.textWebSocketFrame[String, CodecFormat.TextPlain] | ||
|
||
Codec.fromDecodeAndMeta[WebSocketFrame, ClientMessage, CodecFormat.TextPlain](CodecFormat.TextPlain()) { | ||
case WebSocketFrame.Close(code, reason) => DecodeResult.Value(ClientMessage.Leave) | ||
case frame => baseStringCodec.decode(frame).map(ClientMessage.Message.apply(_)) | ||
} { | ||
case ClientMessage.Leave => WebSocketFrame.close | ||
case ClientMessage.Message(msg) => baseStringCodec.encode(msg) | ||
} | ||
|
||
// interpreting the endpoints & exposing them | ||
val routes: Routes[Any, ZioHttpResponse] = ZioHttpInterpreter().toHttp(List(wsServerEndpoint)) | ||
|
||
override def run: URIO[Any, ExitCode] = | ||
Server | ||
.serve(routes) | ||
.provide(ZLayer.succeed(Server.Config.default.port(8080)), Server.live) | ||
.exitCode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 22 additions & 1 deletion
23
server/jdkhttp-server/src/test/scala/sttp/tapir/server/jdkhttp/JdkHttpServerTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.