-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWebSocket.fs
77 lines (62 loc) · 2.57 KB
/
WebSocket.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
namespace FSharpPlayground
open System.Text
open System.Threading
open Suave
open Suave.Sockets
open Suave.Sockets.Control
open Suave.WebSocket
type SocketMessageEvent () =
let socketMessage = new Event<string>()
[<CLIEvent>]
member this.Event = socketMessage.Publish
member this.Send(message) =
socketMessage.Trigger (message)
module WebSocket =
let socketMessage = new SocketMessageEvent ()
let (|Success|Failure|) result =
match result with
| Choice1Of2 a -> Success a
| Choice2Of2 b -> Failure b
// These choices don't contain any message yet
let (|KeepAlive|Invalid|) msg =
let message = Encoding.UTF8.GetString msg
if (message = "keep-alive") then
KeepAlive
else
Invalid
let response (message : string) =
message
|> Encoding.ASCII.GetBytes
|> ByteSegment
let handleSocketError (error : Choice<'a, Error>) =
match error with // TODO: handle these errors
| Success a -> printfn "%O" a // Loop stopped early, but no warning.
// Should never happen. print result for debugging
| Failure error ->
match error with
| SocketError systemSocketError -> ()
| InputDataError (code, message) -> ()
| ConnectionError message -> ()
let websocket (webSocket : WebSocket) (httpContext : HttpContext) =
socket {
let sendKeepAlive () =
webSocket.send Text (response "{\"action\": \"keep-alive\"}") true
let rec listen (socket : WebSocket) = async {
let! message = socket.read ()
match message with
| Success (_, KeepAlive, _) ->
let result = Async.RunSynchronously (sendKeepAlive ())
match result with
| Success () -> return! listen socket
| Failure error -> return Choice2Of2 error
| Success (_, Invalid, _) -> // TODO: handle succesful read but invalid message
return! listen socket
| Failure error -> return Choice2Of2 error
}
socketMessage.Event.Subscribe (fun message -> webSocket.send Text (response message) true
|> Async.RunSynchronously
|> handleSocketError)
|> ignore
Async.RunSynchronously (listen webSocket)
|> handleSocketError
}