Does anyone have SSL working in a local dev environment in a way that supports both HTTPS and WS?
I’m trying to get HTTPS and WSS (for Apollo subscriptions) working in my local dev environment. Even though I have them on two different ports, something seems to be forcing or redirecting the WSS calls to the HTTPS port.
Here’s my current code. For SSL access I have installed Meteor package nourharidy/meteor-ssl
. I can use any comparable package or approach that people have found useful!
As required by nourharidy/meteor-ssl
, in server/main.js I have:
`SSL('/path/to/private/server.key','/path/to/private/server.crt', 3100);`
My ROOT_URL environment variable is:
https://10.0.1.10:3100 //I’m using my Mac’s ip address so that another Mac can access it
In imports/startup/server/index.js I have:
//SET UP APOLLO QUERY / MUTATIONS / PUBSUB
const USING_HTTPS = true;
const httpProtocol = USING_HTTPS ? "https" : "http";
const localHostString = '10.0.1.10' //I’m using my Mac’s ip address so that another Mac can access it
const METEOR_PORT = 3100;
const GRAPHQL_SUBSCRIPTION_PORT = 3200;
const subscriptionsEndpoint = `wss://${localHostString}:${GRAPHQL_SUBSCRIPTION_PORT}/subscriptions`;
const server = express();
server.use('*', cors({ origin: `${httpProtocol}://${localHostString}:${GRAPHQL_SUBSCRIPTION_PORT}` }));
server.use('/graphql', bodyParser.json(), graphqlExpress({
schema
}));
server.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
subscriptionsEndpoint: subscriptionsEndpoint
}));
// We wrap the express server so that we can attach the WebSocket for subscriptions
const ws = createServer(server);
ws.listen(GRAPHQL_SUBSCRIPTION_PORT, () => {
console.log(`GraphQL Server is now running on ${httpProtocol}://${localHostString}:${GRAPHQL_SUBSCRIPTION_PORT}`);
// Set up the WebSocket for handling GraphQL subscriptions
new SubscriptionServer({
execute,
subscribe,
schema
}, {
server: ws,
path: '/subscriptions',
});
});
Instead of being at https://10.0.1.10:3200/graphiql
where it’s supposed to be, graphIql is at https://10.0.1.10:3100/graphiql
!
In other words, graphIql loads up just fine on https://10.0.1.10:3100/graphiql
, but if you go to https://10.0.1.10:3200/graphiql
, you see 10.0.1.10 unexpectedly closed the connection
.
If I put both HTTPS and WSS on the same port, e.g. 3100, I get an listen EADDRINUSE :::31001
error.
What’s a good server-side setup to get HTTPS and WSS in Meteor/Apollo?
Thanks in advance to all for any info.
Solved it! It turns out my server setup was fine.
Server-side I was building the WSS url like so:
var websocketUri = Meteor.absoluteUrl('subscriptions').replace(/http/, 'ws').replace('3100', '3200');
The Meteor docs for absoluteUrl
say:
The server reads from the ROOT_URL environment variable to determine where it is running.
In Webstorm I have ROOT_URL set to https://10.0.nn.nn:3100
. But for some reason absoluteUrl was returning http://10.0.nn.nn:3000
. I.e. it had the wrong port.
After correcting the port-- it’s working!
UPDATE: I thought I had it solved when I posted a few days ago, but I was still missing something.
I’m now using ngrok to provide SSL to my dev system for use with HTTPS and WSS.
Here are a few details.
- I run Meteor on localhost:3000.
- I assign the value of “http://localhost:3000” to the ROOT_URL environment variable.
- I run two simultaneous ngrok connections, one for HTTPS and one for WSS:
./ngrok http 3000
./ngrok http 3200
- This gives me two ngrok urls, for example:
Forwarding https://9b785bd3.ngrok.io -> localhost:3000
Forwarding https://ec3d8027.ngrok.io -> localhost:3200
I access my app via the ngrok url, for example:
I build my HTTPS links and WSS links based on the ngrok addresses. For example:
const wssEndpoint = 'wss://ec3d8027.ngrok.io/subscriptions';
I hope this is helpful to others looking into this.