@@ -6,13 +6,13 @@ import sttp.monad.syntax._
6
6
7
7
/** Effectful interactions with a web socket. Interactions can happen:
8
8
*
9
- * - on the frame level, by sending and receiving raw [[WebSocketFrame ]]s
10
- * - using the provided `receive*` methods to obtain concatenated data frames, or string/byte payloads, and the
11
- * `send*` method to send string/binary frames.
9
+ * - on the frame level, by sending and receiving raw [[WebSocketFrame ]] s
10
+ * - using the provided `receive*` methods to obtain concatenated data frames, or string/byte payloads, and the
11
+ * `send*` method to send string/binary frames.
12
12
*
13
13
* The `send*` and `receive*` methods may result in a failed effect, with either one of [[WebSocketException ]]
14
- * exceptions, or a backend-specific exception. Specifically, they will fail with [[WebSocketClosed ]] if the
15
- * web socket is closed.
14
+ * exceptions, or a backend-specific exception. Specifically, they will fail with [[WebSocketClosed ]] if the web socket
15
+ * is closed.
16
16
*
17
17
* See the `either` and `eitherClose` method to lift web socket closed events to the value level.
18
18
*/
@@ -23,8 +23,8 @@ trait WebSocket[F[_]] {
23
23
* happen.
24
24
*
25
25
* However, not all implementations expose the close frame, and web sockets might also get closed without the proper
26
- * close frame exchange. In such cases, as well as when invoking `receive`/`send` after receiving a close frame,
27
- * this effect will fail with the [[WebSocketClosed ]] exception.
26
+ * close frame exchange. In such cases, as well as when invoking `receive`/`send` after receiving a close frame, this
27
+ * effect will fail with the [[WebSocketClosed ]] exception.
28
28
*
29
29
* *Should be only called sequentially!* (from a single thread/fiber). Because web socket frames might be fragmented,
30
30
* calling this method concurrently might result in threads/fibers receiving fragments of the same frame.
@@ -38,12 +38,13 @@ trait WebSocket[F[_]] {
38
38
def send (f : WebSocketFrame , isContinuation : Boolean = false ): F [Unit ]
39
39
def isOpen (): F [Boolean ]
40
40
41
- /** Receive a single data frame, ignoring others. The frame might be a fragment.
42
- * Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
41
+ /** Receive a single data frame, ignoring others. The frame might be a fragment. Will fail with [[ WebSocketClosed ]] if
42
+ * the web socket is closed, or if a close frame is received.
43
43
*
44
44
* *Should be only called sequentially!* (from a single thread/fiber).
45
45
*
46
- * @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
46
+ * @param pongOnPing
47
+ * Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
47
48
*/
48
49
def receiveDataFrame (pongOnPing : Boolean = true ): F [WebSocketFrame .Data [_]] =
49
50
receive().flatMap {
@@ -54,62 +55,66 @@ trait WebSocket[F[_]] {
54
55
case _ => receiveDataFrame(pongOnPing)
55
56
}
56
57
57
- /** Receive a single text data frame, ignoring others. The frame might be a fragment. To receive whole messages,
58
- * use [[receiveText ]].
59
- * Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
58
+ /** Receive a single text data frame, ignoring others. The frame might be a fragment. To receive whole messages, use
59
+ * [[receiveText ]]. Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
60
60
*
61
61
* *Should be only called sequentially!* (from a single thread/fiber).
62
62
*
63
- * @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
63
+ * @param pongOnPing
64
+ * Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
64
65
*/
65
66
def receiveTextFrame (pongOnPing : Boolean = true ): F [WebSocketFrame .Text ] =
66
67
receiveDataFrame(pongOnPing).flatMap {
67
68
case t : WebSocketFrame .Text => t.unit
68
69
case _ => receiveTextFrame(pongOnPing)
69
70
}
70
71
71
- /** Receive a single binary data frame, ignoring others. The frame might be a fragment. To receive whole messages,
72
- * use [[receiveBinary ]].
73
- * Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
72
+ /** Receive a single binary data frame, ignoring others. The frame might be a fragment. To receive whole messages, use
73
+ * [[receiveBinary ]]. Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is
74
+ * received.
74
75
*
75
76
* *Should be only called sequentially!* (from a single thread/fiber).
76
77
*
77
- * @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
78
+ * @param pongOnPing
79
+ * Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
78
80
*/
79
81
def receiveBinaryFrame (pongOnPing : Boolean = true ): F [WebSocketFrame .Binary ] =
80
82
receiveDataFrame(pongOnPing).flatMap {
81
83
case t : WebSocketFrame .Binary => t.unit
82
84
case _ => receiveBinaryFrame(pongOnPing)
83
85
}
84
86
85
- /** Receive a single text message (which might come from multiple, fragmented frames).
86
- * Ignores non-text frames and returns combined results.
87
- * Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
87
+ /** Receive a single text message (which might come from multiple, fragmented frames). Ignores non-text frames and
88
+ * returns combined results. Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is
89
+ * received.
88
90
*
89
91
* *Should be only called sequentially!* (from a single thread/fiber).
90
92
*
91
- * @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
93
+ * @param pongOnPing
94
+ * Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
92
95
*/
93
96
def receiveText (pongOnPing : Boolean = true ): F [String ] =
94
97
receiveConcat(() => receiveTextFrame(pongOnPing), _ + _)
95
98
96
- /** Receive a single binary message (which might come from multiple, fragmented frames).
97
- * Ignores non-binary frames and returns combined results.
98
- * Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
99
+ /** Receive a single binary message (which might come from multiple, fragmented frames). Ignores non-binary frames and
100
+ * returns combined results. Will fail with [[ WebSocketClosed ]] if the web socket is closed, or if a close frame is
101
+ * received.
99
102
*
100
103
* *Should be only called sequentially!* (from a single thread/fiber).
101
104
*
102
- * @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
105
+ * @param pongOnPing
106
+ * Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
103
107
*/
104
108
def receiveBinary (pongOnPing : Boolean ): F [Array [Byte ]] =
105
109
receiveConcat(() => receiveBinaryFrame(pongOnPing), _ ++ _)
106
110
107
- /** Extracts the received close frame (if available) as the left side of an either, or returns the original result
108
- * on the right.
111
+ /** Extracts the received close frame (if available) as the left side of an either, or returns the original result on
112
+ * the right.
109
113
*
110
114
* Will fail with [[WebSocketClosed ]] if the web socket is closed, but no close frame is available.
111
115
*
112
- * @param f The effect describing web socket interactions.
116
+ * @param f
117
+ * The effect describing web socket interactions.
113
118
*/
114
119
def eitherClose [T ](f : => F [T ]): F [Either [WebSocketFrame .Close , T ]] =
115
120
f.map(t => Right (t): Either [WebSocketFrame .Close , T ]).handleError { case WebSocketClosed (Some (close)) =>
@@ -118,12 +123,13 @@ trait WebSocket[F[_]] {
118
123
119
124
/** Returns an effect computing a:
120
125
*
121
- * - `Left` if the web socket is closed - optionally with the received close frame (if available).
122
- * - `Right` with the original result otherwise.
126
+ * - `Left` if the web socket is closed - optionally with the received close frame (if available).
127
+ * - `Right` with the original result otherwise.
123
128
*
124
129
* Will never fail with a [[WebSocketClosed ]].
125
130
*
126
- * @param f The effect describing web socket interactions.
131
+ * @param f
132
+ * The effect describing web socket interactions.
127
133
*/
128
134
def either [T ](f : => F [T ]): F [Either [Option [WebSocketFrame .Close ], T ]] =
129
135
f.map(t => Right (t): Either [Option [WebSocketFrame .Close ], T ]).handleError { case WebSocketClosed (close) =>
0 commit comments