Mercurial > code > home > repos > homeauto
diff service/rfid_pn532/graphserver.nim @ 1199:87283af13f15
starting pn532 rfid reader in nim
Ignore-this: ee51d4acec4b7f88bb7f0e7491da7b8f
darcs-hash:43821dc27f532f22fe549ad05e5cd15e08395c52
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Tue, 19 Feb 2019 12:08:22 -0800 |
parents | |
children | 0bc26b4fc427 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/rfid_pn532/graphserver.nim Tue Feb 19 12:08:22 2019 -0800 @@ -0,0 +1,89 @@ +import asynchttpserver, asyncdispatch, asyncnet, strtabs, sequtils, times, os, strutils, strformat + +type + GraphServer* = ref object of RootObj + port*: int + clients: seq[AsyncSocket] + previousUpdateTime: int + httpServer: AsyncHttpServer + serverReady: Future[void] + +proc handleCORS(req: Request) {.async.} = + await req.respond(Http204, "", newHttpHeaders({ + "Access-Control-Allow-Origin": "*", + "Connection": "close"})) + +proc handle404(req: Request) {.async.} = + let headers = newHttpHeaders({"Content-Type": "text/plain", + "Connection": "close"}) + + await req.respond(Http404, "File not found", headers) + req.client.close() + +proc handleSSE(self: GraphServer, req: Request) {.async.} = + let headers = newHttpHeaders({"Content-Type": "text/event-stream", + "Access-Control-Allow-Origin": "*", + "Cache-Control": "no-cache", + "Connection": "keep-alive"}) + + await req.client.send("HTTP/1.1 200 OK\c\L") + await req.sendHeaders(headers) + await req.client.send("\c\L:ok\n\n") + self.clients.add(req.client) + +proc handleConnections(self: GraphServer, req: Request) {.async.} = + let clientCount = self.clients.len + let headers = newHttpHeaders({"Content-Type": "text/plain", + "Access-Control-Allow-Origin": "*", + "Cache-Control": "no-cache", + "Connection": "close"}) + + await req.respond(Http200, $clientCount, headers) + req.client.close() + +proc requestCallback(self: GraphServer, req: Request) {.async.} = + if req.reqMethod == HttpOptions: + asyncCheck handleCORS(req) + else: + case req.url.path + of "/connections": asyncCheck self.handleConnections(req) + of "/sse": asyncCheck self.handleSSE(req) + else: asyncCheck handle404(req) + +proc newGraphServer*(port: int): GraphServer = + new(result) + result.port = port + result.previousUpdateTime = toInt(epochTime() * 1000) + + result.httpServer = newAsyncHttpServer(true) + let self = result + self.serverReady = self.httpServer.serve( + Port(self.port), + proc (req: Request): Future[void] = self.requestCallback(req), + address="0.0.0.0") + asyncCheck self.serverReady + echo "Listening on " & $self.port + + +proc checkClients(self: GraphServer) = + self.clients = self.clients.filterIt(not it.isClosed()) + +proc pingClients(self: GraphServer) {.async.} = + let currentTime = toInt(epochTime() * 1000) + + if currentTime - self.previousUpdateTime < 1000: + return + + for client in self.clients: + if not client.isClosed(): + asyncCheck client.send("data: " & $currentTime & "\n\n") + + self.previousUpdateTime = toInt(epochTime() * 1000) + +proc run*(self: GraphServer) = + while true: + self.checkClients() + asyncCheck self.pingClients() + poll() + +