You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.5 KiB
110 lines
3.5 KiB
'use strict'; |
|
|
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
exports.default = expressWs; |
|
|
|
var _http = require('http'); |
|
|
|
var _http2 = _interopRequireDefault(_http); |
|
|
|
var _express = require('express'); |
|
|
|
var _express2 = _interopRequireDefault(_express); |
|
|
|
var _ws = require('ws'); |
|
|
|
var _ws2 = _interopRequireDefault(_ws); |
|
|
|
var _websocketUrl = require('./websocket-url'); |
|
|
|
var _websocketUrl2 = _interopRequireDefault(_websocketUrl); |
|
|
|
var _addWsMethod = require('./add-ws-method'); |
|
|
|
var _addWsMethod2 = _interopRequireDefault(_addWsMethod); |
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
|
|
|
function expressWs(app, httpServer) { |
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; |
|
|
|
var server = httpServer; |
|
|
|
if (server === null || server === undefined) { |
|
/* No HTTP server was explicitly provided, create one for our Express application. */ |
|
server = _http2.default.createServer(app); |
|
|
|
app.listen = function serverListen() { |
|
var _server; |
|
|
|
return (_server = server).listen.apply(_server, arguments); |
|
}; |
|
} |
|
|
|
/* Make our custom `.ws` method available directly on the Express application. You should |
|
* really be using Routers, though. */ |
|
(0, _addWsMethod2.default)(app); |
|
|
|
/* Monkeypatch our custom `.ws` method into Express' Router prototype. This makes it possible, |
|
* when using the standard Express Router, to use the `.ws` method without any further calls |
|
* to `makeRouter`. When using a custom router, the use of `makeRouter` may still be necessary. |
|
* |
|
* This approach works, because Express does a strange mixin hack - the Router factory |
|
* function is simultaneously the prototype that gets assigned to the resulting Router |
|
* object. */ |
|
if (!options.leaveRouterUntouched) { |
|
(0, _addWsMethod2.default)(_express2.default.Router); |
|
} |
|
|
|
// allow caller to pass in options to WebSocketServer constructor |
|
var wsOptions = options.wsOptions || {}; |
|
wsOptions.server = server; |
|
var wsServer = new _ws2.default.Server(wsOptions); |
|
|
|
wsServer.on('connection', function (socket, request) { |
|
if ('upgradeReq' in socket) { |
|
request = socket.upgradeReq; |
|
} |
|
|
|
request.ws = socket; |
|
request.wsHandled = false; |
|
|
|
/* By setting this fake `.url` on the request, we ensure that it will end up in the fake |
|
* `.get` handler that we defined above - where the wrapper will then unpack the `.ws` |
|
* property, indicate that the WebSocket has been handled, and call the actual handler. */ |
|
request.url = (0, _websocketUrl2.default)(request.url); |
|
|
|
var dummyResponse = new _http2.default.ServerResponse(request); |
|
|
|
dummyResponse.writeHead = function writeHead(statusCode) { |
|
if (statusCode > 200) { |
|
/* Something in the middleware chain signalled an error. */ |
|
dummyResponse._header = ''; |
|
socket.close(); |
|
} |
|
}; |
|
|
|
app.handle(request, dummyResponse, function () { |
|
if (!request.wsHandled) { |
|
/* There was no matching WebSocket-specific route for this request. We'll close |
|
* the connection, as no endpoint was able to handle the request anyway... */ |
|
socket.close(); |
|
} |
|
}); |
|
}); |
|
|
|
return { |
|
app: app, |
|
getWss: function getWss() { |
|
return wsServer; |
|
}, |
|
applyTo: function applyTo(router) { |
|
(0, _addWsMethod2.default)(router); |
|
} |
|
}; |
|
} /* This module does a lot of monkeypatching, but unfortunately that appears to be the only way to |
|
* accomplish this kind of stuff in Express. |
|
* |
|
* Here be dragons. */ |