netlify: WebSocket connection failed: Connection closed before receiving a handshake response - javascript

I have app on Netlify and I get some error:
server don't work: 9aeacd2….js:1 WebSocket connection to 'wss://xxxxxxxxxxxxx/:5000' failed: Connection closed before receiving a handshake response. Only start site is served.
Locally all works perfect and I wasn't getting any error. App builds on Netlify (gulp) and this is angular app.
Help me and thanks!
My server code:
"use strict";
process.title = 'node-chat';
var webSocketsServerPort = (process.env.PORT || 5000);
var webSocketServer = require('websocket').server;
var http = require('http');
var pref = '../';
var fs = require('fs');
var index = fs.readFileSync('src/index.html');
var clients = [];
var loggedUsers = [];
var tables = [];
var err;
/**
* HTTP server
*/
var server = http.createServer(function (req, res) {
var status;
var type;
var file = null;
switch (req.url) {
case "/":
case "/src/index.html":
file = index;
status = 200;
type = "text/html";
break;
default:
status = 404;
type = "text/plain";
}
res.writeHead(status, {'Content-Type': type});
if (file !== null) {
res.end(file);
} else {
res.end();
}
});
server.listen(webSocketsServerPort, function () {
console.log((new Date()) + " Server is listening on port " +
webSocketsServerPort);
});
/**
* WebSocket server
*/
var wsServer = new webSocketServer({
httpServer: server
});
wsServer.on('request', function (request) {
console.log((new Date()) + ' Connection from origin ' + request.origin +
'.' );
var connection = request.accept(null, request.origin);
var index = clients.push(connection) - 1;
connection.on('message', function (message) {
if (message.type === 'utf8') { // accept only text
var json = JSON.parse(message.utf8Data);
switch(json.type){
case 1:
break;
}
}
});
// user disconnected
connection.on('close', function (connection) {
console.log("DISCONNECTED");
});
});

Related

Why do I get a SyntaxError: Unexpected end of input?

Running a node server and I am getting the following error.
SyntaxError: Unexpected end of input
var http = require('http');
var socketio = require('socket.io');
if (typeof String.prototype.startsWith != 'function') {
String.prototype.startsWith = function (str){
return this.slice(0, str.length) == str;
};
}
function log_me(msg){
var ts = new Date(new Date().getTime() - (3600000*4));
var tss = ts.toString();
tss = tss.substring(0, tss.indexOf(' GMT'));
console.log(tss + ": " + msg);
}
var app = http.createServer(function(req, res) {
var postData = "";
req.on('data', function(chunk) {
postData += chunk; //Get the POST data
});
req.on('end', function() {
if (typeof(postData) !== "undefined") {
var message = JSON.parse(postData); <-- Here is the issue line 25
//Do something here
//Todo...
}
});
res.end();
}).listen(8080); //Use a non-standard port so it doesn't override your Apache
var io = socketio.listen(app);
//var io = require('socket.io').listen(8080,'0.0.0.0');
io.set('log level', 2);
// io.set('transports', ['flashsocket', 'polling', 'websocket']);
io.set('origins', '*:*');
You can use something like that:
JSON.safeParse = function(data) {
try {
return JSON.parse(data);
} catch (e) {
return false;
}
}
Change your JSON.parse call to JSON.safeParse, and then check if the result is valid:
var message = JSON.safeParse(postData);
if (message) {
// valid!
} else {
// invalid
}

How to set key on request header for authorization in nodejs?

I am beginner in nodejs. I am building a simple server that writes json data to csv file. The question is:
For authorization, the “appKey” parameter needs to be set in the request header:
appKey: 9a3ab6d8-9ffe-49a5-8194-bc7d61123f4a
I could not understand what I am going to do.
This is what I have so far:
var fs = require('fs');
var express = require('express');
var app = express();
var inFilename = 'power_plants.json',
outFilename = 'powerplants.csv';
app.get('/', function (req, res) {
writeToCsv();
res.send('Successfully Created!');
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
function writeToCsv(){
var inJSON = fs.readFileSync(inFilename);
inJSON = JSON.parse(inJSON);
var outCSV = inJSON.rows;
var csv = [];
for(var k in outCSV) {
var items = [[outCSV[k].PowerPlant , outCSV[k].meter]];
for (index = 0; index < items.length; ++index) {
csv.push(items[index].join(', ') + '\n');
}
}
fs.writeFile(outFilename, csv, function (err) {
if (err) {
return console.log(err);
}
console.log('FILE SUCCESSFULLY WRITTEN!\n');
});
}
To extract the value of the header appKey you have to get it with this:
var appKey = req.headers.appKey;

How do I send a message ONLY to a specific socket.id?

I'm slowly setting up the structure a project and while I can ping an alert to every other user besides the ping source, I still need to be able to ping an alert to a specific user. I assume the best way to do this is to ping to a certain socket.id. Any ideas how to do this? socket.broadcast.to(socket.id) doesn't seem to work in my setup as I keep getting an error (Cannot read property 'to' of undefined).
client.js
// BROWSERIFY
//DEPENDENCIES
var P2P = require("socket.io-p2p");
var io = require("socket.io-client");
var ss = require("socket.io-stream");
var socket = io();
var opts = { autoUpgrade: true, peerOpts: { numClients: 10 } };
var p2p = new P2P(socket, opts);
var $ = require("jquery");
//Handler for the ping button
var pingRoom = function () {
socket.emit('pingAlert');
};
window.pingRoom = pingRoom;
var pingTwo = function () {
socket.emit('pingAlertTwo');
};
window.pingTwo = pingTwo;
////////////////////////////////////////////////////////
//Intercepts the pingBack event from the server side
socket.on('pingBack', function (data) {
alert("ALERT");
});
socket.on('pingBackTwo', function (data) {
socket.broadcast.to(socketid).emit('message', 'for your eyes only');
});
////////////////////////////////////////////////////////
//Peer number counter (incomplete functionality)
p2p.on("peer-num", function (num) {
console.log("You are peer number " + num);
$(".peerNum").html("You are connected to " + num + " peers.");
});
////////////////////////////////////////////////////////
//Appends stream to element
p2p.on("file", function (stream) {
//console.log(stream);
var img = document.createElement("img");
img.src = (window.URL || window.webkitURL).createObjectURL(new Blob(stream));
document.getElementById("receivedImages").appendChild(img);
});
////////////////////////////////////////////////////////
//Converts file to binary stream and logs progress in the console
$(function () {
$("#file").change(function (e) {
ss.forceBase64 = true;
var file = e.target.files[0];
var stream = ss.createStream();
ss(socket).emit("file", stream, { size: file.size, name: file.name });
var blobStream = ss.createBlobReadStream(file);
var size = 0;
blobStream.on("data", function (chunk) {
size += chunk.length;
console.log(Math.floor(size / file.size * 100) + "%");
});
blobStream.pipe(stream);
});
});
////////////////////////////////////////////////////////
//Logs users in the user log
socket.on('users_log', function (data) {
$('#log').append(data + "<br>");
console.log(data);
});
////////////////////////////////////////////////////////
server.js
//DEPENDENCIES
var app = require("express")();
var express = require("express");
var server = require("http").Server(app);
var p2pserver = require("socket.io-p2p-server").Server;
var io = require("socket.io")(server);
var ss = require("socket.io-stream");
var path = require("path");
//Added configuration
app.use(express.static(__dirname));
app.use(express.static("server_scripts"));
app.use(express.static("client_scripts"));
io.use(p2pserver);
//Peer number
var peerNum = 0;
////////////////////////////////////////////////////////
//Connections and disconnections
io.on("connection", function (socket) {
//Increments the peer number for connected peers
console.log("Peer " + peerNum + " connected");
io.emit("peer-num", peerNum);
peerNum++;
////////////////////////////////////////////////////////
//Streamer
ss(socket).on("file", function (stream, data) {
var filename = path.basename(data.name);
var parts = [];
stream.on("data", function (data) {
parts.push(data);
});
stream.on("end", function () {
socket.broadcast.emit("file", parts);
});
});
////////////////////////////////////////////////////////
//Holds the socket.id of connections
ID = socket.id;
////////////////////////////////////////////////////////
//Emits connection status to user end (User ID log)
io.sockets.emit('users_log', "client id - " + ID + " connected");
io.sockets.emit('users_online', ID);
////////////////////////////////////////////////////////
//Server side logging of connections
console.log('client id - ' + ID + ' connected.');
////////////////////////////////////////////////////////
//Alert listener and response
socket.on('pingAlert', function () {
console.log('Ping');
io.sockets.emit('pingBack');
});
socket.on('pingAlertTwo', function () {
console.log('PingTwo');
io.sockets.emit('pingBackTwo');
});
////////////////////////////////////////////////////////
//Handles disconnections
socket.on('disconnect', function () {
//Emits disconnection to user end (User ID log)
io.sockets.emit('users_log', "client id - " + ID + " disconnected");
//Decreases peer counter on disconnect
peerNum--;
////////////////////////////////////////////////////////
//Server side logging of disconnections
console.log('client id - ' + ID + ' disconnected.')
io.sockets.emit('users_offline', ID);
//NOTE: Features need to be added here
////////////////////////////////////////////////////////
})
});
//Listen on
server.listen(8000, function () {
console.log("Listening on 8000")
});
io.sockets.connected[ID].emit('ping',data);
ID is socketId, data is payload you want send with event.
when you write io.function() The Event is emitted for all users, but if you write socket.function(), the event is emitted for that particular socket.
If you wish to emit some message to a particular user, use socket.emit() function.

When using the expressjs in Nodejs, the server keeps close_wait status after a few thousands of requests

I put the code below onto my server:
var express = require('express');
var app = express();
var mysql = require('mysql');
var db = mysql.createPool({host:'192.168.1.234', user:'root', password:'123456', database:'db_xuyou_test', port:3306});
app.post('/query', function (req, res){
s = {};
platform = Number(req.query['platform']) * 100000000;
platform_upper = platform + 99999999;
appv = Number(req.query['appv']) * 10000;
resource = Number(req.query['res']) * 1;
id = platform + appv + resource;
resource_upper = platform + appv + 9999;
sql = 'select appv from (select min(id) as min_id from download where id >= ? and id <= ?) as a inner join download on a.min_id = download.id';
db.query(sql, [platform, platform_upper], function(err, row) {
if (err) {
console.error(err);
res.end();
return;
}
if (row.length <= 0) {
s['code'] = 2;
s['message'] = 'update!';
res.send(s);
console.log(s);
return;
}
if (Number(row[0]['appv']) > appv) {
s['code'] = 2;
s['message'] = 'update!';
res.send(s);
console.log(s);
return;
}
sql = 'select res as version, versionName, ip, port, filename from download where id > ? and id <= ? order by id';
db.query(sql, [id, resource_upper], function(err2, resRow) {
if (err2) {
console.error(err2);
res.end();
return;
}
if (resRow.length <= 0) {
s['code'] = 0;
s['message'] = '';
res.send(s);
console.log(s);
return;
}
s['code'] = 1;
s['message'] = '';
s['versionData'] = resRow;
console.log(s);
res.send(s);
});
});
});
app.listen(3000, '0.0.0.0');
And I wrote a test which sends thousands of requests to the server. But very weirdly, the the server suddenly ran into close_wait status after processing a few thousands of requests.
As the code describes, it processes the request by selecting the data from the database and send the result back to the clients and the procedure will end.
Why it turns out to be close_wait?? How to solve it?
Thanks in advance.

Can't send fetched data to my socket.io stream?

I'm trying to switch from single mysql-queries to mysql-pool connection, so users can share one mysql-connection, but I'm not familiar with this at all (also new to nodejs/socket.io).
The following code is what I've done so far to send data every second to the socket in an array:
var
port = process.env.OPENSHIFT_NODEJS_PORT || 8000,
ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1',
app = require('http').createServer(handler),
fs = require('fs'),
request = require('request'),
mysql = require('mysql'),
moment = require('moment'),
tz = require('moment-timezone'),
pool = mysql.createPool({
connectionLimit: 100,
host: 'xxx',
user: 'xxx',
password: 'xxx',
database: 'xxx',
debug: false,
port: 3306}),
socketArray = [],
POLLING_INTERVAL = 1000,
pollingTimer;
moment.tz.setDefault("Europe/Berlin");
var io = require('socket.io').listen(app);
io.set('origins', '*:*');
function time()
{
output = new Date();
output = moment().format('(H:mm:ss.SS) ');
return output;
}
function handler(req,res)
{
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.statusCode = 200;
res.connection.setTimeout(0);
res.end();
}
app.listen(port,ip);
function pollingLoop () {
if (socketArray.length === 0) {
// no connections, wait and try again
setTimeout(pollingLoop, POLLING_INTERVAL);
return; // continue without sending mysql query
}
pool.getConnection(function(err,connection){
if (err) { console.log({"code" : 100, "status" : "connection-db error"}); return; }
console.log('connected as id ' + connection.threadId);
console.log('socketArray length: ' + socketArray.length);
var selection =
"SELECT\
a.`id`,a.`product_id` AS pid,a.`random` AS nr,a.`price`,a.`price_end` AS pe,\
TIMESTAMPDIFF(SECOND,NOW(),a.`datetime`) AS duration,\
ABS(TIMESTAMPDIFF(SECOND,NOW(),b.`date`)) AS hb\
FROM `auctions` AS a\
LEFT JOIN `auctions_bids` AS b ON b.`auction_id` = a.`id`\
WHERE TIMESTAMPDIFF(SECOND,NOW(),a.`datetime`) > '-1'\
GROUP BY a.`id`\
ORDER BY `duration` DESC,`id` DESC LIMIT 15";
var streamArray = [], lg = '';
var query = connection.query(selection, function(err, results, rows){
lg += ('id: '+results[0].id+' ('+results[0].duration+') ');
if
(
((results[0].duration < 2 || results[0].duration <= results[0].nr) && (results[0].price <= results[0].pe))
||
((results[0].duration < 2 || results[0].duration <= results[0].nr) && (results[0].hb > 0 && results[0].hb < 30))
)
{
min = 3;
max = 5;
rand = Math.floor(Math.random()*(max-min+1)+min);
price = results[0].price+0.01;
price = price.toFixed(2);
pool.query('UPDATE `auctions` SET `random` = ?,`price` = ?, `datetime` = DATE_ADD(`datetime`,INTERVAL(17-TIMESTAMPDIFF(SECOND,NOW(),`datetime`))SECOND) WHERE `id` = ?',[rand, price, results[0].id]);
console.log(time()+'UPDATED id '+results[0].id+': random ('+rand+') price ('+price+'€)');
}
streamArray.push(results[0]);
updateSockets({ streamArray: streamArray });
console.log("auctions pushed: " + streamArray);
connection.release();
setTimeout(pollingLoop, POLLING_INTERVAL);
});
console.log(time()+lg+' C: '+socketArray.length);
});
}
pollingLoop();
io.sockets.on('connection', function(socket) {
socket.on('disconnect', function() {
clearTimeout(pollingTimer);
var socketIndex = socketArray.indexOf(socket);
console.log(time()+'SOCKET-ID = %s DISCONNECTED', socketIndex);
if (~socketIndex) { socketArray.splice(socketIndex, 1); }
});
console.log(time()+'NEW SOCKET CONNECTED!');
socketArray.push(socket);
});
var updateSockets = function(data) {
socketArray.forEach(function(tmpSocket) { tmpSocket.volatile.emit('stream', data); });
};
console.log(time()+'server.js executed\n');
But this doesn't send me any data to the WebSocket. Is this approach (code-structure) even correct? Previously I used query.on('results') to get data like this:
var selection = "SELECT * FROM auctions";
var query = mysql.query(selection), auctions = [];
query.on('result', function(auction) {
console.log('id: '+auction.id+' ('+auction.duration+') ');
});
This worked fine showing data with auction.row but how to do this in my mysql pool connection?
Also after some seconds I'm getting an error that release() isn't even defined, but it's listed in the mysql-module documentation... so I think my whole logical process is somehow incorrect.
Should I use connection.end() and .release() at all? Because the
connection should never end.
Should I still use setInterval(function () { mysql.query('SELECT
1'); }, 5000); as answered in another StackOverflow question to keep
the connection alive here? (nodejs mysql Error: Connection lost The server closed the connection)
(Appreciate any tips or answers to even some of my questions! Better some answers than none, because I experienced that this topic isn't answered much at all.)
EDIT:
Updated my whole code (see above). Output looks like this now: http://s21.postimg.org/avsxa87rb/output.jpg
So the stream gets the data, but in the console.log is nothing and there's this javascript error?
You should be creating a pool, and using getConnection on that pool. Then, when you're done with the connection, release it. Additionally, you do not need to stop the pollingLoop or start it for each connection, one loop is enough.
I didn't understand the if statement with conditions, so i omitted it. It likely needs to go somewhere else.
var socketArr = [];
function handler(req, res) {
res.statusCode = 200;
res.connection.setTimeout(0);
res.end();
}
app.listen(port, ip);
var pool = mysql.createPool({
host : 'example.org',
user : 'bob',
password : 'secret'
});
function pollingLoop () {
if (socketArr.length === 0) {
// no connections, wait and try again
setTimeout(pollingLoop, 1000);
return; // continue without sending mysql query
}
pool.getConnection(function (err, connection) {
if (err) {
console.log({
"code": 100,
"status": "Error in connection database"
});
return;
}
console.log('connected as id ' + connection.threadId);
var selection = "SELECT * FROM auctions";
var streamArray = [],
lg = '';
var query = connection.query(selection, function (err, results, fields, rows) {
lg += ('id: ' + results[0].id + ' (' + results[0].duration + ') ');
/*if (conditions) {
var query_update = connection.query('UPDATE `auctions` SET `price` = ? WHERE `id` = ?', [price, auction.id]);
console.log(time() + 'UPDATED id ' + auction.id + ': price (' + price + '€)');
}*/
streamArray.push(results);
updateSockets({
streamArray: streamArray
});
console.log("auctions pushed: " + streamArray);
connection.release();
setTimeout(pollingLoop, 1000);
});
console.log(time() + lg + ' C: ' + socketArr.length);
});
}
// start loop
pollingLoop();
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
var socketIndex = socketArr.indexOf(socket);
console.log(time() + 'SOCKET-ID = %s DISCONNECTED', socketIndex);
if (~socketIndex) {
socketArr.splice(socketIndex, 1);
}
});
console.log(time() + 'NEW SOCKET CONNECTED!');
socketArr.push(socket);
});
var updateSockets = function (data) {
socketArr.forEach(function (tmpSocket) {
tmpSocket.volatile.emit('stream', data);
});
};

Categories

Resources