You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

40 lines
1.1 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package outwatch.util
  2. import cats.effect.Sync
  3. import colibri._
  4. import org.scalajs.dom.Event
  5. import org.scalajs.dom.MessageEvent
  6. import outwatch.helpers._
  7. object WebSocketF {
  8. implicit def toObserver[F[_]: Sync](
  9. socket: WebSocketF[F]
  10. ): F[Observer[String]] =
  11. socket.sink
  12. implicit def toObservable[F[_]: Sync](
  13. socket: WebSocketF[F]
  14. ): Observable[MessageEvent] =
  15. socket.source
  16. }
  17. class WebSocketF[F[_]](val url: String)(implicit F: Sync[F]) {
  18. val ws = new org.scalajs.dom.WebSocket(url)
  19. val source: Observable[MessageEvent] =
  20. Observable.create[MessageEvent] { observer =>
  21. ws.onmessage = (e: MessageEvent) => observer.onNext(e)
  22. ws.onerror =
  23. (e: Event) => observer.onError(new Exception(s"Error in WebSocket: $e"))
  24. Cancelable(() => ws.close())
  25. }
  26. val sink: F[Observer[String]] = {
  27. F.delay {
  28. new Observer[String] {
  29. override def onNext(elem: String): Unit = ws.send(elem)
  30. override def onError(ex: Throwable): Unit =
  31. OutwatchTracing.errorSubject.onNext(ex)
  32. }
  33. }
  34. }
  35. }