-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.rkt
64 lines (56 loc) · 1.82 KB
/
server.rkt
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
#lang racket/base
(require "./mpd.rkt")
(require racket/match
racket/async-channel
net/rfc6455
json)
(ws-idle-timeout 600)
(define clients 0)
(define mpd-channel (make-async-channel))
(define mpd-conn (mpd-connect))
(define (resp-info)
(hash 'current (mpd-currentsong mpd-conn) 'next (mpd-nextsong mpd-conn)))
(define mpd-worker
(thread (λ ()
(let loop ([previnfo #f])
(when (not (mpd-connection-alive? mpd-conn))
(set! mpd-conn (mpd-connect)))
(define currinfo (resp-info))
(when (and (not (equal? previnfo currinfo))
(> clients 0))
(displayln (format "mpd: updating info ~a" currinfo))
(async-channel-put mpd-channel currinfo))
(sleep 1)
(loop currinfo)))))
(define (connection-handler c state)
(define id (gensym 'conn))
(displayln (format "~a: connection received" id))
(set! clients (add1 clients))
; initial message
(ws-send! c (jsexpr->bytes (resp-info)))
(define worker
(thread (λ ()
(let loop ()
(define mpd-info (async-channel-try-get mpd-channel))
(when mpd-info
(ws-send! c (jsexpr->bytes mpd-info)))
(sleep 1)
(loop)))))
(let loop ()
(match (ws-recv c #:payload-type 'text)
[(? eof-object?) (void)]
["ping"
(displayln (format "~a: recv ping" id))
(ws-send! c "pong")
(loop)]))
(displayln (format "~a: connection lost" id))
(kill-thread worker)
(ws-close! c)
(set! clients (sub1 clients)))
(define stop-service
(ws-serve #:port (string->number (vector-ref (current-command-line-arguments)
0))
connection-handler))
(printf "Server running. Hit enter to stop service.\n")
(void (read-line))
(stop-service)