From 33c8f70ab67745bf3b7b9b2e8404e4d30b0461e7 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 4 Nov 2018 23:00:32 +0000 Subject: [PATCH] Flesh out WebSocket support --- packages/driver-http-node/src/index.js | 76 ++++++++++++------------ packages/syntax-playground/src/server.js | 11 +++- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/packages/driver-http-node/src/index.js b/packages/driver-http-node/src/index.js index 5b536ff..6ee7d19 100644 --- a/packages/driver-http-node/src/index.js +++ b/packages/driver-http-node/src/index.js @@ -83,15 +83,15 @@ function _server(host, port, httpsOptions) { } } - during Observe(WebSocket(_, server, $path, _)) { - path = encodePath(path); + during Observe(WebSocket(_, server, $pathPattern, _)) { + const path = encodePath(pathPattern); on start { - if (!(path in wsHandlerMap)) wsHandlerMap[path] = 0; - wsHandlerMap[path]++; + if (!(path in wsHandlerMap)) wsHandlerMap[path] = {_count: 0, _path: pathPattern}; + wsHandlerMap[path]._count++; } on stop { - wsHandlerMap[path]--; - if (wsHandlerMap[path] === 0) delete wsHandlerMap[path]; + wsHandlerMap[path]._count--; + if (wsHandlerMap[path]._count === 0) delete wsHandlerMap[path]; } } @@ -178,45 +178,47 @@ function _server(host, port, httpsOptions) { function checkWSConnection(info, callback) { let url = parseUrl(info.req.url, true); let pieces = reqUrlPieces(url); - let handlerCount = mapLookup(wsHandlerMap, pieces); - if (!handlerCount) { + if (!mapLookup(wsHandlerMap, pieces)) { callback(false, 404, "Not found", {}); } else { callback(true); } } - wss.on('connection', (ws, req) => { - let url = parseUrl(info.req.url, true); + wss.on('connection', Dataspace.wrapExternal((ws, req) => { + let url = parseUrl(req.url, true); let pieces = reqUrlPieces(url); - // react { - // let id = nextId++; - // assert WebSocket(id, server, pieces, url.query); + let { _path: pathPattern } = mapLookup(wsHandlerMap, pieces); - // stop on retracted Observe(Request(_, server, method, pathPattern, _, _)) { - // res.writeHead(500, "Internal server error", {}); - // res.end(); - // } - // stop on asserted Response( - // id, $code, $message, $headers, $detail) - // { - // res.writeHead(code, message, headers.toJS()); - // if (detail === null) { - // react { - // stop on retracted Response(id, code, message, headers, detail) { - // res.end(); - // } - // on message ResponseData(id, $chunk) { - // res.write(chunk); - // } - // } - // } else { - // res.end(detail); - // } - // } - // } - }); + react { + const facet = Dataspace.currentFacet(); + let id = nextId++; + assert WebSocket(id, server, pieces, url.query); + + on stop ws.close(); + + ws.on('close', Dataspace.wrapExternal(() => { + facet.stop(); + })); + + on asserted Observe(RequestData(id, _)) { + ws.on('message', Dataspace.wrapExternal((message) => { + ^ RequestData(id, message); + })); + } + + on message ResponseData(id, $message) { + ws.send(message); + } + + stop on retracted Observe(WebSocket(_, server, pathPattern, _)); + stop on retracted Observe(WebSocket(id, server, pieces, _)); + } + })); on start s.listen(port, host); - on stop s.close(); + on stop { + wss.close(); + s.close(); + } } diff --git a/packages/syntax-playground/src/server.js b/packages/syntax-playground/src/server.js index f5f3066..700671b 100644 --- a/packages/syntax-playground/src/server.js +++ b/packages/syntax-playground/src/server.js @@ -35,7 +35,12 @@ spawn named 'greetingServer' { } spawn named 'websocketEchoServer' { - // during Http.WebSocket($id, server, ['echo'], _) { - - // } + during Http.WebSocket($id, server, ['echo'], _) { + on message Http.RequestData(id, $message) { + console.log('got', id, message); + ^ Http.ResponseData(id, message); + } + + stop on message Http.RequestData(id, "quit"); + } }