Parse-server: Parse Live Query not working with HTTPS server (TypeError: this._server.once is not a function)

Created on 2 Dec 2016  路  11Comments  路  Source: parse-community/parse-server

Make sure these boxes are checked before submitting your issue -- thanks for reporting issues back to Parse Server!

--

Issue Description

Parse Server would not start when using HTTPS and Live Query.

var app = express();

var api = new ParseServer({
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || 'myAppId',
masterKey: process.env.MASTER_KEY || '',
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',
verifyUserEmails: true,
publicServerURL: process.env.SERVER_EXTERNAL_URL || 'http://localhost:1337/parse',
appName: 'WhatTuDu',
emailAdapter: {
module: 'parse-server-simple-mailgun-adapter',
options: {
fromAddress: '[email protected]',
domain: 'mg.whattudu.com',
apiKey: 'key-xxxxxx',
}
},
push: {
ios: [
{
pfx: path.join(__dirname, '/dev.p12'), // Dev PFX or P12
bundleId: 'com.xxx.WhatTuDu',
production: false // Dev
},
{
pfx: path.join(__dirname, '/prod.p12'), // Prod PFX or P12
bundleId: 'com.xxx.WhatTuDu',
production: true // Prod
}
]
},
keyPairs: {
"restAPIKey": "",
"javascriptKey": "",
"clientKey": "",
"windowsKey": "",
"masterKey": ""
},
liveQuery: {
classNames: ["Event", "Votes", "Room", "Message", "User"]
},
websocketTimeout: 10 * 1000,
cacheTimeout: 60 * 600 * 1000
});

// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);

var port_ssl = process.env.PORT_SSL || 1338;
// Start https server
https.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
}, app).listen(port_ssl, function() {
console.log('parse-server running on SSL port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(https); //<- this line crashes

If you comment it you can start the server and access it in https. If you uncomment it then it crashes with the following errors:

WhatTuDu@ start /var/app/current
node server.js

/var/app/current/node_modules/parse-server/lib/ParseServer.js:430
throw err;
^

TypeError: this._server.once is not a function
at new WebSocketServer (/var/app/current/node_modules/ws/lib/WebSocketServer.js:78:18)
at new ParseWebSocketServer (/var/app/current/node_modules/parse-server/lib/LiveQuery/ParseWebSocketServer.js:26:13)
at new ParseLiveQueryServer (/var/app/current/node_modules/parse-server/lib/LiveQuery/ParseLiveQueryServer.js:103:33)
at Function.createLiveQueryServer (/var/app/current/node_modules/parse-server/lib/ParseServer.js:458:14)
at Object. (/var/app/current/server.js:195:13)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)

npm ERR! Linux 4.4.23-31.54.amzn1.x86_64
npm ERR! argv "/opt/elasticbeanstalk/node-install/node-v6.9.1-linux-x64/bin/node" "/opt/elasticbeanstalk/node-install/node-v6.9.1-linux-x64/bin/npm" "start"
npm ERR! node v6.9.1
npm ERR! npm v3.10.8
npm ERR! code ELIFECYCLE
npm ERR! WhatTuDu@ start: node server.js
npm ERR! Exit status 7
npm ERR!
npm ERR! Failed at the WhatTuDu@ start script 'node server.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the WhatTuDu package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node server.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs WhatTuDu
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls WhatTuDu
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /var/app/current/npm-debug.log

Steps to reproduce

Create a Parse Server using express and https (see code above) and enable Parse Live Query on the https server

Expected Results

Parse LiveQuery server should run on https server and no error should be happening

Actual Outcome

server doesn't start and crashes with errors as above.

Environment Setup

  • Server

    • parse-server version (Be specific! Don't say 'latest'.) : 2.2.25
    • Operating System: 64bit Amazon Linux 2016.09 v3.1.0 running Node.js 6.9.1
    • Hardware: amazon t2.micro
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): AWS
  • Database

    • MongoDB version: unknow, mLab managed
    • Storage engine: unknow, mLab managed
    • Hardware: unknow, mLab managed
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): mLab

Logs/Trace

WhatTuDu@ start /var/app/current
node server.js

/var/app/current/node_modules/parse-server/lib/ParseServer.js:430
throw err;
^

TypeError: this._server.once is not a function
at new WebSocketServer (/var/app/current/node_modules/ws/lib/WebSocketServer.js:78:18)
at new ParseWebSocketServer (/var/app/current/node_modules/parse-server/lib/LiveQuery/ParseWebSocketServer.js:26:13)
at new ParseLiveQueryServer (/var/app/current/node_modules/parse-server/lib/LiveQuery/ParseLiveQueryServer.js:103:33)
at Function.createLiveQueryServer (/var/app/current/node_modules/parse-server/lib/ParseServer.js:458:14)
at Object. (/var/app/current/server.js:195:13)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)

npm ERR! Linux 4.4.23-31.54.amzn1.x86_64
npm ERR! argv "/opt/elasticbeanstalk/node-install/node-v6.9.1-linux-x64/bin/node" "/opt/elasticbeanstalk/node-install/node-v6.9.1-linux-x64/bin/npm" "start"
npm ERR! node v6.9.1
npm ERR! npm v3.10.8
npm ERR! code ELIFECYCLE
npm ERR! WhatTuDu@ start: node server.js
npm ERR! Exit status 7
npm ERR!
npm ERR! Failed at the WhatTuDu@ start script 'node server.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the WhatTuDu package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node server.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs WhatTuDu
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls WhatTuDu
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /var/app/current/npm-debug.log

Most helpful comment

Alright, I believe I found something:

https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
  }, app).listen(port_ssl, function() {
  console.log('parse-server running on SSL port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(https);

This is broken because you're passing the https package and not the server itself

try:

var httpsServer = https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
  }, app).listen(port_ssl, function() {
  console.log('parse-server running on SSL port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpsServer);

All 11 comments

Thanks for reporting the issue. do you want to try to take a dent at it?

I wish i could... It's out of my depth though, I'm an iOS App developer and js is not where i'm at my best :(

That seems to be an issue with the ws module (https://npmjs.com/package/ws)

Well either ws or https... So either https need to be changed to add what ws needs or ws needs to be changed to work with https, no sure what the best course of action would be...

ws is calling 2 functions:

1) .once
2) .on

I logged the http and https objects from the call and here is what i got:

HTTP:

Server {
domain: null,
_events:
{ request:
{ [Function: app]
domain: undefined,
_events: [Object],
_maxListeners: undefined,
setMaxListeners: [Function: setMaxListeners],
getMaxListeners: [Function: getMaxListeners],
emit: [Function: emit],
addListener: [Function: addListener],
on: [Function: addListener],
prependListener: [Function: prependListener],
once: [Function: once],
prependOnceListener: [Function: prependOnceListener],
removeListener: [Function: removeListener],
removeAllListeners: [Function: removeAllListeners],
listeners: [Function: listeners],
listenerCount: [Function: listenerCount],
eventNames: [Function: eventNames],
init: [Function: init],
defaultConfiguration: [Function: defaultConfiguration],
lazyrouter: [Function: lazyrouter],
handle: [Function: handle],
use: [Function: use],
route: [Function: route],
engine: [Function: engine],
param: [Function: param],
set: [Function: set],
path: [Function: path],
enabled: [Function: enabled],
disabled: [Function: disabled],
enable: [Function: enable],
disable: [Function: disable],
acl: [Function],
bind: [Function],
checkout: [Function],
connect: [Function],
copy: [Function],
delete: [Function],
get: [Function],
head: [Function],
link: [Function],
lock: [Function],
'm-search': [Function],
merge: [Function],
mkactivity: [Function],
mkcalendar: [Function],
mkcol: [Function],
move: [Function],
notify: [Function],
options: [Function],
patch: [Function],
post: [Function],
propfind: [Function],
proppatch: [Function],
purge: [Function],
put: [Function],
rebind: [Function],
report: [Function],
search: [Function],
subscribe: [Function],
trace: [Function],
unbind: [Function],
unlink: [Function],
unlock: [Function],
unsubscribe: [Function],
all: [Function: all],
del: [Function],
render: [Function: render],
listen: [Function: listen],
request: [Object],
response: [Object],
cache: {},
engines: {},
settings: [Object],
_eventsCount: 1,
locals: [Object],
mountpath: '/',
_router: [Object] },
connection: [Function: connectionListener],
listening: { [Function: g] listener: [Function] } },
_eventsCount: 3,
_maxListeners: undefined,
_connections: 0,
_handle:
TCP {
bytesRead: 0,
_externalStream: {},
fd: 16,
reading: false,
owner: [Circular],
onread: null,
onconnection: [Function: onconnection],
writeQueueSize: 0 },
_usingSlaves: false,
_slaves: [],
_unref: false,
allowHalfOpen: true,
pauseOnConnect: false,
httpAllowHalfOpen: false,
timeout: 120000,
_pendingResponseData: 0,
_connectionKey: '6::::8080' }

HTTPS:

{ Server: { [Function: Server] super_: { [Function: Server] super_: [Object] } },
createServer: [Function],
globalAgent:
Agent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: { 'registry.npmjs.org:443::::::::': [Object] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
Agent:
{ [Function: Agent]
super_: { [Function: Agent] super_: [Object], defaultMaxSockets: Infinity } },
request: [Function],
get: [Function] }

Should i do an issue report on ws github page?

Yep that would be nice, I've checked their code, and their latest release is from April 2016 (the one we currently use), and the culprit code isn't there anymore.

What's odd is that the HTTPs Server inherits Server which should have once on it.

ok...

Well i checked in their current code (ws) and downloaded it and replaced the old ws/lib with the new one and the error just moves to a different module. Since the latest version of ws uses Ultron, the error ends up in Ultron:

/Users/ChD/Downloads/parse-server/node_modules/parse-server/lib/ParseServer.js:430
throw err;
^

TypeError: this.ee.on is not a function
at Ultron.on (/Users/ChD/Downloads/parse-server/node_modules/ultron/index.js:42:11)
at WebSocketServer (/Users/ChD/Downloads/parse-server/node_modules/ws/lib/WebSocketServer.js:80:20)
at new ParseWebSocketServer (/Users/ChD/Downloads/parse-server/node_modules/parse-server/lib/LiveQuery/ParseWebSocketServer.js:26:13)
at new ParseLiveQueryServer (/Users/ChD/Downloads/parse-server/node_modules/parse-server/lib/LiveQuery/ParseLiveQueryServer.js:103:33)
at Function.createLiveQueryServer (/Users/ChD/Downloads/parse-server/node_modules/parse-server/lib/ParseServer.js:458:14)
at Object. (/Users/ChD/Downloads/parse-server/server.js:212:13)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)

I can't find a source for HTTPS (any idea where to look for it?) but yeah my assumption would be that it should have it too which is why i mentioned the issue might be with HTTPS and not ws...

Alright, I believe I found something:

https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
  }, app).listen(port_ssl, function() {
  console.log('parse-server running on SSL port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(https);

This is broken because you're passing the https package and not the server itself

try:

var httpsServer = https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
  }, app).listen(port_ssl, function() {
  console.log('parse-server running on SSL port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpsServer);

Amazing! Thank you so much for that Florent! Works perfectly now! You made my day :D

No problemo! Good luck!

how about this, it had bugs, but I have no idea how to fix it.

anyone help?

var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var bodyParser = require('body-parser');
var SimpleMailgunAdapter = require('parse-server-simple-mailgun-adapter');
var stripe = require("stripe");
var https = require('https');
var http = require('http');
var fs = require('fs');


var options = {
    key: fs.readFileSync('/etc/letsencrypt/live/' + 'api.xxx.cloud/privkey.pem'),
    cert: fs.readFileSync('/etc/letsencrypt/live/' + 'api.xxx.cloud/fullchain.pem')
};

var api = new ParseServer({
    databaseURI: process.env.PARSE_SERVER_DATABASE_URI || 'mongodb://pAdmin:[email protected]:27017/parse?ssl=true',
    cloud: '/opt' + '/cloud/main.js',
    appId: process.env.PARSE_SERVER_APPLICATION_ID || 'cMxxxxxxxxxxxxxxxx1Y',
    masterKey: process.env.PARSE_SERVER_MASTER_KEY || 'yWxxxxxxxxxxxxxxxP8e',
    javascriptKey: process.env.PARSE_SERVER_MASTER_KEY || 'yxxxxxxxxxxxxxxxxxxx8e', 
    serverURL: process.env.PARSE_SERVER_URL || 'https://127.0.0.1:1337/parse',
    restAPIKey: process.env.PARSE_SERVER_MASTER_KEY || 'yxxxxxxxxxxxxxxxxxx8e',
    appName: 'parse',
    publicServerURL: 'https://api.xxx.cloud/parse',
    emailAdapter: SimpleMailgunAdapter({
        apiKey: 'key-2xxxxxxxxxxxxx0f0',
        fromAddress: '[email protected]',
    }),
    liveQuery: {
        classNames: ["UsPrIn", "Event", "Votes", "Room", "Message", "User"] // List of classes to support for query subscriptions
    }
});

var app = express();

// redirect all http requests to https
app.use(function (req, res, next) {
    if(!req.secure && (req.headers.host !== '127.0.0.1:1337')) {
        return res.redirect(301, ['https://api.xxx.cloud', req.url].join(''));
    }
    next();
});

// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));

// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);

app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, '/public/index.html'));
});

var port = process.env.PORT || 443;

var httpsServer = https.createServer(options, app).listen(port, function() {
    console.log('parse-server running on SSL port ' + port + '.');
});

var httpServer = http.createServer(app).listen(1337, function() {
    console.log('parse-server running on port 1337.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpsServer);
Was this page helpful?
0 / 5 - 0 ratings