[racket] Implementing long polling ajax
Hello,
I was wondering how can i implement a long polling ajax technique (aka
comet) (https://en.wikipedia.org/wiki/Long_polling#Long_polling) using the
web-server lib.
So i need build a servlet that don't directly send a response but hold on in
place and wait for being wake up.
The only solution i ends up is using semaphore:
#lang racket
(require web-server/web-server
web-server/http
net/url
web-server/managers/none
(prefix-in seq:
web-server/dispatchers/dispatch-sequencer)
(prefix-in filter:
web-server/dispatchers/dispatch-filter)
web-server/servlet-dispatch)
(provide
interface-version
start
manager)
(define interface-version 'v2)
(define manager
(create-none-manager
(lambda (req)
(response/xexpr
`(html (head (title "No continuation here"))
(body (h1 "fycj you biiii")))))))
(define poll-hash (make-hash))
(define (poll1 req)
(define params (map path/param-path (url-path (request-uri req))))
(define id (second params))
(define message (third params))
(with-handlers ([(lambda (_) #t) (quick-response "fail" (format "There is no ~a" id))])
(let ([sem (hash-ref poll-hash id)])
(hash-set! poll-hash id message)
(semaphore-post sem))
(quick-response "ok" "message transmitted")))
(define (push1 req)
(define params (map path/param-path (url-path (request-uri req))))
(define id (first params))
(define sem (make-semaphore 0))
(hash-set! poll-hash id sem)
(semaphore-wait sem)
(begin0
(quick-response
"ok"
(hash-ref poll-hash id))
(hash-remove! poll-hash id)))
(serve
#:port 8080
#:dispatch
(seq:make
(filter:make
#rx"/poll"
(dispatch/servlet poll1))
(dispatch/servlet push1)))
(do-not-return)
A bit of explanation of the code:
- we hit push1 with a request of type /ID
- there is no response from the server
- we hit poll1 with a request of type /ID/MESSAGE
- this increment the semaphore associated with ID and pass MESSAGE inside the poll-hash
- then the previous push1 request can return
Is there other way to do?
I first think using a continuation, but capture continuation still return
something and don't hold the computation.
What is the cost of using a semaphore?
Thanks you in advance for your responses.