Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Created September 21, 2024 18:09
Show Gist options
  • Save kubukoz/d4446c061762b24175530c11dfb121c6 to your computer and use it in GitHub Desktop.
Save kubukoz/d4446c061762b24175530c11dfb121c6 to your computer and use it in GitHub Desktop.
WebSocket server in http4s that forwards messages from each client to the others
//> using dep org.http4s::http4s-ember-server::0.23.28
import cats.effect.IO
import cats.effect.IOApp
import cats.effect.std.UUIDGen
import cats.syntax.all.*
import fs2.concurrent.Topic
import org.http4s.HttpApp
import org.http4s.ember.server.EmberServerBuilder
import org.http4s.websocket.WebSocketFrame
import java.util.UUID
object ws extends IOApp.Simple:
def run: IO[Unit] =
val srv =
for
messages <- Topic[IO, (UUID, WebSocketFrame)].toResource
_ <- EmberServerBuilder
.default[IO]
.withHttpWebSocketApp: builder =>
HttpApp.liftF[IO]:
builder.build: input =>
fs2.Stream
.eval(UUIDGen[IO].randomUUID)
.flatMap { myId =>
input
.tupleLeft(myId)
.through(messages.publish)
.mergeHaltBoth(
messages.subscribeUnbounded
.filterNot(_._1 == myId)
.map(_._2)
)
}
.build
yield ()
srv.useForever
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment