kudos/koa-websocket

How to create https server and support websocket or wss use koa2?

Closed this issue · 4 comments

Create https server:

const Koa = require('koa');
const app = new Koa();
const options = {
    key: fs.readFileSync('./ssl/private.pem', 'utf8'),
    cert: fs.readFileSync('./ssl/20180303.crt', 'utf8')
};
https.createServer(options, app.callback()).listen(443);

Then how to make ws or wss work with https? Please @kudos

I ran into a similar issue myself a few days ago. While not ideal, I do have a solution:

From the source of koa-websocket (index.js, lines 43-53):

module.exports = function (app) {
  const oldListen = app.listen;
  app.listen = function () {
    debug('Attaching server...');
    app.server = oldListen.apply(app, arguments);
    app.ws.listen(app.server);
    return app.server;
  };
  app.ws = new KoaWebSocketServer(app);
  return app;
};

koa-websocket attaches a .ws object to app, which in turn has .listen method. That's exactly the method we need to kind of monkey-patch to hack https into this. So, instead of using listen directly (which makes websockets work on top of koa), can use a workaround:

app.listen = () => {
  const server = http.createServer(app.callback()).listen(host.port);
  app.ws.listen(server);
  if (process.env.NODE_ENV === 'production') {
    const sslServer = https.createServer(SSL, app.callback()).listen(443);
    app.ws.listen(sslServer);
  }
};

app.listen();

EDIT: Forgot to mention here: host.port is just a plain string read from a config file. SSL is the ssl config object with a key / cert pair.

Haven't tested this on a server yet, but it works locally.

EDIT 2: It looks like this can be considered the same issue as #28 - passing options to the ws instance itself should take care of this.

@DBozhinovski Thank you very very much, great answer. I know how to do it now.

Just ran into the same issue and found out that the solution in #29 (comment) does not work for koa-websocket@4.0.0, I guess because PR #28 got merged.

Here is the updated version which works for me:

const Koa        = require('koa'),
      http       = require('http'),
      webSockify = require('koa-websocket'),
      app        = new Koa();
...
webSockify(app);
...
const server = http.createServer(app.callback());
...
// attach WebSockets to same server
app.ws.listen({
    server: server,
});

// start server
server.listen(port);

Just ran into the same issue and found out that the solution in #29 (comment) does not work for koa-websocket@4.0.0, I guess because PR #28 got merged.

Here is the updated version which works for me:

const Koa        = require('koa'),
      http       = require('http'),
      webSockify = require('koa-websocket'),
      app        = new Koa();
...
webSockify(app);
...
const server = http.createServer(app.callback());
...
// attach WebSockets to same server
app.ws.listen({
    server: server,
});

// start server
server.listen(port);

2021.11.13 Still work :)