@@ -4,7 +4,13 @@ import sttp.model.Headers
4
4
import sttp .monad .MonadError
5
5
import sttp .monad .syntax ._
6
6
7
- /** The `send*` and `receive*` methods may result in a failed effect, with either one of [[WebSocketException ]]
7
+ /** Effectful interactions with a web socket. Interactions can happen:
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.
12
+ *
13
+ * The `send*` and `receive*` methods may result in a failed effect, with either one of [[WebSocketException ]]
8
14
* exceptions, or a backend-specific exception. Specifically, they will fail with [[WebSocketClosed ]] if the
9
15
* web socket is closed.
10
16
*
@@ -19,13 +25,24 @@ trait WebSocket[F[_]] {
19
25
* However, not all implementations expose the close frame, and web sockets might also get closed without the proper
20
26
* close frame exchange. In such cases, as well as when invoking `receive`/`send` after receiving a close frame,
21
27
* this effect will fail with the [[WebSocketClosed ]] exception.
28
+ *
29
+ * *Should be only called sequentially!* (from a single thread/fiber). Because web socket frames might be fragmented,
30
+ * calling this method concurrently might result in threads/fibers receiving fragments of the same frame.
22
31
*/
23
32
def receive (): F [WebSocketFrame ]
33
+
34
+ /** Sends a web socket frame. Can be safely called from multiple threads.
35
+ *
36
+ * May result in a failed effect, in case of a network error, or if the socket is closed.
37
+ */
24
38
def send (f : WebSocketFrame , isContinuation : Boolean = false ): F [Unit ]
25
39
def isOpen (): F [Boolean ]
26
40
27
41
/** Receive a single data frame, ignoring others. The frame might be a fragment.
28
42
* Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
43
+ *
44
+ * *Should be only called sequentially!* (from a single thread/fiber).
45
+ *
29
46
* @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
30
47
*/
31
48
def receiveDataFrame (pongOnPing : Boolean = true ): F [WebSocketFrame .Data [_]] =
@@ -40,6 +57,9 @@ trait WebSocket[F[_]] {
40
57
/** Receive a single text data frame, ignoring others. The frame might be a fragment. To receive whole messages,
41
58
* use [[receiveText ]].
42
59
* Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
60
+ *
61
+ * *Should be only called sequentially!* (from a single thread/fiber).
62
+ *
43
63
* @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
44
64
*/
45
65
def receiveTextFrame (pongOnPing : Boolean = true ): F [WebSocketFrame .Text ] =
@@ -51,6 +71,9 @@ trait WebSocket[F[_]] {
51
71
/** Receive a single binary data frame, ignoring others. The frame might be a fragment. To receive whole messages,
52
72
* use [[receiveBinary ]].
53
73
* Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
74
+ *
75
+ * *Should be only called sequentially!* (from a single thread/fiber).
76
+ *
54
77
* @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
55
78
*/
56
79
def receiveBinaryFrame (pongOnPing : Boolean = true ): F [WebSocketFrame .Binary ] =
@@ -62,6 +85,9 @@ trait WebSocket[F[_]] {
62
85
/** Receive a single text message (which might come from multiple, fragmented frames).
63
86
* Ignores non-text frames and returns combined results.
64
87
* Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
88
+ *
89
+ * *Should be only called sequentially!* (from a single thread/fiber).
90
+ *
65
91
* @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
66
92
*/
67
93
def receiveText (pongOnPing : Boolean = true ): F [String ] =
@@ -70,6 +96,9 @@ trait WebSocket[F[_]] {
70
96
/** Receive a single binary message (which might come from multiple, fragmented frames).
71
97
* Ignores non-binary frames and returns combined results.
72
98
* Will fail with [[WebSocketClosed ]] if the web socket is closed, or if a close frame is received.
99
+ *
100
+ * *Should be only called sequentially!* (from a single thread/fiber).
101
+ *
73
102
* @param pongOnPing Should a [[WebSocketFrame.Pong ]] be sent when a [[WebSocketFrame.Ping ]] is received.
74
103
*/
75
104
def receiveBinary (pongOnPing : Boolean ): F [Array [Byte ]] =
@@ -114,7 +143,16 @@ trait WebSocket[F[_]] {
114
143
}
115
144
}
116
145
146
+ /** Sends a web socket frame with the given payload. Can be safely called from multiple threads.
147
+ *
148
+ * May result in a failed effect, in case of a network error, or if the socket is closed.
149
+ */
117
150
def sendText (payload : String ): F [Unit ] = send(WebSocketFrame .text(payload))
151
+
152
+ /** Sends a web socket frame with the given payload. Can be safely called from multiple threads.
153
+ *
154
+ * May result in a failed effect, in case of a network error, or if the socket is closed.
155
+ */
118
156
def sendBinary (payload : Array [Byte ]): F [Unit ] = send(WebSocketFrame .binary(payload))
119
157
120
158
/** Idempotent when used sequentially.
0 commit comments