Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No documentation or examples for sending websocket messages #1418

Closed
danellis opened this issue Sep 5, 2022 · 8 comments · Fixed by #2567
Closed

No documentation or examples for sending websocket messages #1418

danellis opened this issue Sep 5, 2022 · 8 comments · Fixed by #2567
Labels
💎 Bounty documentation Improvements or additions to documentation 💰 Rewarded

Comments

@danellis
Copy link

danellis commented Sep 5, 2022

I'd like to be able to start sending messages on a websocket as soon as it's opened (i.e. not in response to incoming messages). I don't see anything in the documentation or examples that shows how this would be done.

@gregor-rayman
Copy link
Contributor

gregor-rayman commented Nov 4, 2022

Here a small sample of a web socket chat app.

Here it start sending right after the connection is established:

          case HandshakeComplete =>
            ...
              ch.writeAndFlush(WebSocketFrame.text(s"Hello $name")) *>

Here the whole chat app:

import zio.*
import zio.Console.printLine
import zhttp.http.*
import zhttp.service.*
import zhttp.service.ChannelEvent.UserEvent.{ HandshakeComplete, HandshakeTimeout }
import zhttp.service.ChannelEvent.{ ChannelRead, ChannelUnregistered, UserEventTriggered }
import zhttp.socket.*
import zio.*
import zio.stream.ZStream

object WebSocketEcho extends ZIOAppDefault {

  private val portConfig = System.env("port").map(_.flatMap(_.toIntOption).getOrElse(9009))

  private def chat(socketsRef: Ref[Map[String, Channel[WebSocketFrame]]], name: String) =
    def broadcast(from: Channel[WebSocketFrame], msg: String) =
      for
        sockets <- socketsRef.get
        _       <- ZIO.foreachParDiscard(sockets.filterNot(_._1 == from.id).values) { c =>
                     c.writeAndFlush(WebSocketFrame.text(msg))
                   }
      yield ()

    Http.collectZIO[WebSocketChannelEvent] {
      case ChannelEvent(ch, UserEventTriggered(event))             =>
        event match
          case HandshakeTimeout  =>
            ZIO.logInfo("Connection failed!")
          case HandshakeComplete =>
            broadcast(ch, s"$name joined") *>
              ch.writeAndFlush(WebSocketFrame.text(s"Hello $name")) *>
              socketsRef.update(ss => ss + (ch.id -> ch))
      case ChannelEvent(ch, ChannelRead(WebSocketFrame.Text(msg))) =>
        broadcast(ch, s"$name says: $msg")
      case ChannelEvent(ch, ChannelUnregistered)                   =>
        socketsRef.update(ss => ss - ch.id) *>
          broadcast(ch, s"$name left")
    }

  private def chatRoom(socketsRef: Ref[Map[String, Channel[WebSocketFrame]]]): Http[Any, Nothing, Request, Response] =
    Http.collectZIO[Request] { case Method.GET -> !! / "chat" / name =>
      chat(socketsRef, name).toSocketApp.toResponse
    }

  override val run: ZIO[Any, Throwable, ExitCode] = for
    port       <- portConfig
    _          <- Console.printLine(s"Starting server on http://localhost:$port")
    socketsRef <- Ref.make(Map[String, Channel[WebSocketFrame]]())
    _          <- Server.start(port, chatRoom(socketsRef))
  yield ExitCode.success

}

@vigoo vigoo added the documentation Improvements or additions to documentation label Mar 13, 2023
@jdegoes
Copy link
Member

jdegoes commented Apr 18, 2023

/bounty $125

For a number of examples, documented and written according to best-practices.

@algora-pbc
Copy link

algora-pbc bot commented Apr 18, 2023

💎 $125 bounty created by ZIO
🙋 If you start working on this, comment /attempt #1418 to notify everyone
👉 To claim this bounty, submit a pull request that includes the text /claim #1418 somewhere in its body
📝 Before proceeding, please make sure you can receive payouts in your country
💵 Payment arrives in your account 2-5 days after the bounty is rewarded
💯 You keep 100% of the bounty award
🙏 Thank you for contributing to zio/zio-http!

Attempt Started (GMT+0) Solution
🟢 @JatinSharma32 #2134
🟢 @987Nabil #2567

@JatinSharma32
Copy link

Working on it...

@algora-pbc
Copy link

algora-pbc bot commented May 1, 2023

💡 JatinSharma32 submitted a pull request that claims the bounty. You can visit your org dashboard to reward.
👉 @JatinSharma32: To receive payouts, sign up on Algora, link your Github account and connect with Stripe on your dashboard.

@JatinSharma32
Copy link

I have submitted a pull request #2134 . Could you please review it?
In the meantime, would it be possible to assign me to this issue?

Copy link

algora-pbc bot commented Dec 24, 2023

💡 @987Nabil submitted a pull request that claims the bounty. You can visit your bounty board to reward.

Copy link

algora-pbc bot commented Dec 25, 2023

🎉🎈 @987Nabil has been awarded $125! 🎈🎊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💎 Bounty documentation Improvements or additions to documentation 💰 Rewarded
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants