Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

heroku WSS #1627

Closed
bryku opened this issue Sep 9, 2019 · 3 comments
Closed

heroku WSS #1627

bryku opened this issue Sep 9, 2019 · 3 comments

Comments

@bryku
Copy link

bryku commented Sep 9, 2019

So i am trying to use websocket with heroku, but it is forcing me to use wss:// instead of ws://.

After diving into this I have found... well a hole lot of nothing that explains how to change from one to the other. Has anyone got this working?

After messing with this, I could just use the http:// version of the website and use the ws:// version of the websocket. Works exactly how it is meant to, but this isn't exactly idea. While there isn't much for personal information they still have to login this way.

@lpinca
Copy link
Member

lpinca commented Sep 9, 2019

See https://github.com/websockets/ws#external-https-server. If Heroku can be used as a SSL-terminating load balancer you do not have to change anything.

Please use another channel for general support questions. This issue tracker is only for bugs.

@lpinca lpinca closed this as completed Sep 10, 2019
@bryku
Copy link
Author

bryku commented Sep 16, 2019

Sorry, I'm using a new terminal program and it shows this as "questions". I'm guessing from your response, it is actually "issues". Sorry for the confusion.

I did find a solution, which was similar to the link you provided.
If you are using express, you can just pass express in instead of {port: 8000}.
Express will automatically handle the keys and http / https depending on the situation.
While it is very similar to the described example, you don't have to mess with the keys, when switching between evn like localhost to production. So it makes it a bit smoother. Although, it would be pretty easy to make a function that handles that, for prototyping using express is easier even though I tend not to like it as much.

Thanks for the help either way, ws has been pretty smooth, but some more example would be helpful. Nodejs ws examples almost all go to socket.io... which is questionable itself.

@andrevenancio
Copy link

andrevenancio commented Feb 28, 2020

Can you provide the solution you found in a bit more detail? I'm at the same cross road as you. my application uses a hapi server, and I've build a custom hapi plugin that internally uses the ws module.

It works perfectly fine over http, but if the users open https and I use wss:// then i get the following error:

WebSocket connection to 'wss://XXXXXXXX.herokuapp.com:80/' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR

What I found is that if I use @hapi/nes as a websocket server, it works cross ws and wss in heroku.
So I'm not sure this is about a paid service from Heroku, but more about how the websocket is implemented.

In the case of @hapi/nes they still use ws behind the scenes. But I'm failing to figure out why the one they have works, and a custom server doesnt'.

Roughly my code is the following:
server.js

import Hapi from '@hapi/hapi';
import Inert from '@hapi/inert';
import path from 'path';
import routes from './routes';
import { SocketStateHapi } from './socket-state-plugin';

export const init = async () => {
    const port = process.env.PORT || 3000;
    const relativeTo = path.join(process.cwd(), 'build');

    const server = Hapi.server({
        port,
        host: '0.0.0.0',
        routes: {
            cors: true,
            files: {
                relativeTo,
            },
        },
    });

    await server.register(Inert);
    await server.register(SocketStateHapi);
  

    server.route(routes);

    await server.start();
    console.log(`🚀  Server running on ${server.info.uri}`);
};

SocketStateHapi.js (just how hapi handles plugins

export const SocketStateHapi = {
    name: 'socket-state-plugin',
    version: '1.0.0',

    register: server => {
        const ss = new Socket({
            server: server.listener,
        });
        ss.connect();
    },
};

And finally the ws server itself:

import WebSocket from 'ws';
import { v4 } from 'uuid';
import { Room } from './room';

export class Socket {
    constructor(options) {
        this.options = options;
    }

    connect() {
        const server = new WebSocket.Server(this.options, {
            rejectUnauthorized: false,
        });
        server.on('connection', (socket, req) => {
            console.log('socket connected');
            socket.on('close', () => {
                console.log('socket disconnected');
            });
        });
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants