synchronizing http response with socket connection - javascript

I am using a http server with a socket connection , when http request hits, socket connection sends message to different client which performs a http request after this http response the client replies to the message and and response of initial http request is send.
My problem is first http request sometimes get response successfuly and sometimes not, I think there is a sync problem, how to solve it.
code for creating socket and httpserver -
const app = require('express')()
bodyParser = require('body-parser')
app.use(bodyParser.json())
const net = require('net');
var client;
var res1,currentReq;
//----------------------------------------------------------------------------
// http requests listener
//----------------------------------------------------------------------------
app.listen(8001, () => console.log('Http server listening on port 8001'));
//----------------------------------------------------------------------------
// http requests handling
//----------------------------------------------------------------------------
app.post('/makeCall', (req, res) => {
console.log('sd' + req.body)
res1 = res;
currentReq='makeCall';
console.log('{"route":"/api/makeCall","data":{"product_id":"' + req.body.product_id + '","destination":"' + req.body.destination + '"}}');
client.write('{"route":"/api/makeCall","data":{"product_id":"' + req.body.product_id + '","destination":"' + req.body.destination + '"}}');
});
//----------------------------------------------------------------------------
// Establishing tcp connection for incoming requests
//----------------------------------------------------------------------------
var server = net.createServer(function(connection) {
console.log ('client has connected successfully!');
client = connection;
client.on('data',function(data){
switch(currentReq)
{
case 'makeCall' :
console.log('send make call response');
res1.end(data);
break;
}
console.log(data.toString());
//res1.end(data);
});
connection.pipe(connection);
});
//----------------------------------------------------------------------------
// listener for tcp connections
//----------------------------------------------------------------------------
server.listen(8000, function() {
console.log('server for localhost is listening on port 8000');
console.log('server bound address is: ' + server.address ());
});
code for client to which socket connects -
tcpClient.on('connect',function(){
logger.info("[%s] , Connected to the server at %s:%s",__file,CONFIG.tcp_server_host,CONFIG.tcp_server_port);
logger.info("[%s] , TCP client info %s",__file,tcpClient.address().address);
});
// Handle data event
tcpClient.on('data',function(data){
logger.info('[%s] , Data recevied',__file);
// Convert the Buffer to JSON object
var reqInfo;
reqInfo = JSON.parse(data.toString());
if(reqInfo!=null){
switch(reqInfo.route){
case '/api/makeCall':;
var product_id = reqInfo.data.product_id;
var destination = reqInfo.data.destination;
var test = {};
var source;
var myJSONObject = {'product_id':product_id};
MongoClient.connect(url, function(err, db) {
var dbo = db.db("mapping");
dbo.collection("mapping").findOne({"id":product_id},function(err,result)
{
if(err)
{
throw err;
}
JSON.stringify(result);
sourceDB = result.source;
// Set the options for HTTPS request
options.method = "POST";
options.url = "url";
options.json = true;
options.auth = {
user: '123',
password: '123'
};
options.body = {"Source": sourceDB,"Destination": destination} ;
logger.info('[%s] , HTTPS request options : %o',__file,options);
request(options,function(error,res1,body){
tcpClient.write('Sending data to Falcon');
});
});
});

Related

OpenShift Node.js WebSocket server connection issues

I am trying to connect to my server running on OpenShift using WebSockets, but no matter how I configure it, nothing seems to go through. I've tried connecting ports 8000, 8080, and 80 with binding to 8000 and 8080, but nothing gets through.
My client attempts to connect:
var connection = new WebSocket('ws://trserve-trserver.1d35.starter-us-east-1.openshiftapps.com:8000');
connection.onopen = function() {
window.alert("Connected!");
};
But "Connected" never pops up in an alert window. On the server side:
var webSocketsServerPort = process.env.PORT ||
process.env.OPENSHIFT_NODEJS_PORT || 8080;
var webSocketIP = process.env.IP || process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0';
var server = http.createServer(function(request, response) {});
server.listen(webSocketsServerPort, webSocketIP, function() {
console.log((new Date()) + " Server is listening on port " +
webSocketsServerPort);
});
var wsServer = new webSocketServer({
httpServer: server
});
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
The server prints:
"The server is listening on port 8080"
but never list anything with Connection from the origin.
Client side:
Example 1: Using the W3C WebSocket API.
var W3CWebSocket = require('websocket').w3cwebsocket;
var client = new W3CWebSocket('ws://localhost:8080/', 'echo-protocol');
client.onerror = function() {
console.log('Connection Error');
};
client.onopen = function() {
console.log('WebSocket Client Connected');
};
Example 2:
var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();
client.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
});
client.connect('ws://localhost:8080/', 'echo-protocol');
Server side:
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
function originIsAllowed(origin) {
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
request.reject();
}
return;
}
var connection = request.accept('echo-protocol', request.origin);
});
Source: WebSocket
Hope, this may help you. You just need to go step by step. Most important is to allow origin from backend from where client request is coming.

RangeError: Invalid status code: 0, NodeJS ZeroMQ

I am developing a simple node api/server, that uses websockets, specifically ZeroMQ. However when sending/requesting data, I receive the following error:
RangeError: Invalid status code: 0 at ServerResponse.writeHead (_http_server.js:192:11)
var express = require('express');
var app = express();
var bodyParser = require("body-parser");
var server_port = "3000";
/** app settings **/
var zeromq = require("zeromq");
var socket = zeromq.socket("req");/* sends request */
var protocol = "tcp://";
var ip = "192.000.0.000"; //server
var socket_port = "9998";
var url = protocol + ip + ":" + socket_port;
app.use(bodyParser());
/** paths **/
app.post('/request', function (request, response) {
var command = request.body;
//connect to port
socket.connect(url, function (error) {
if (error) {
console.log("connection error : ", error);
process.exit(0);
}
});
//response to front end
socket.send(JSON.stringify(command));
//recieve request
socket.on('message', function (message) {
//output message to console
console.log("Recieved message # : " + (new Date().toDateString()) + " : " + message.toString());
//send response
response.setHeader('Content-Type', 'text/plain');
response.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
response.status(200).send(message);
});
});
/** start app **/
app.listen(server_port);
console.log("Server started on port: " + server_port);
CODE UPDATED:
Now I am getting:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
I'm guessing that you are sending the status 0. Try using
res.status(200).send(<body>);

cannot read property '<fieldname>' of null after some time running

I have an angularjs website with NodeJS socket methods as a client, and a NodeJS application as a server.
Data is being passed from the server to the client through socket events. The problem is that after working fine for about 5 minutes, intermittently data that is successfully being sent from the NodeJS server is being received as 'null' in the website, thus giving me the following error:
angular.js:11598 TypeError: Cannot read property '<fieldName>' of null
at ecabsAngular.js:42
at angular.js:12149
at angular.js:12137
at angular.js:12137
at Object.<anonymous> (angular.js:12837)
at l.$digest (angular.js:14222)
at l.$apply (angular.js:14493)
at Socket.<anonymous> (ecabsAngular.js:275)
at Socket.Emitter.emit (socket.io-1.2.0.js:1)
at Socket.onevent (socket.io-1.2.0.js:1)
Do you have any idea what is causing this and how this can be solved?
Thanks in advance!
Edit:
This is the code that is crashing on the client side (on the website)
(function(){
var app = angular.module('Module', []);
app.controller('MainCtrl', ['$scope', '$window', function($scope, $window){
$scope.bookings = [];
socket.on('updateBooking', function(booking){
$scope.loadAllocations();
for (var i=0; i<$scope.bookings.length; i++) {
if ($scope.bookings[i].CRMBookingID == booking.CRMBookingID) {
$scope.$apply(function(){
$scope.bookings[i] = booking;
});
}
}
});
}
]);
})();
This is the code from the NodeJS (server):
var app = require('express')();
var http = require('http');
http.globalAgent.maxSockets = 200;
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var sql = require('mssql');
server.listen(3000);
app.post('/updatebooking', function(request, response) // receive web service request
{
response.writeHeader(200, {"Content-Type": "text/plain"}); // build response header
response.end(); // end the response
request.on('data', function(changes)
{
try{
var c = JSON.parse(changes.toString()); // parse data received
var connection = new sql.Connection(config); // create DB connection
connection.connect(function (err) // connect to the database
{
if (err!=null) { logger.error('Update booking connection error: ' + c + ' ' + err); }
var request = new sql.Request(connection); // create SQL request
request.stream = true;
try{
var sqlquery = <sqlquery>; // build SQL query
logger.trace("Executing SP in DB: " + sqlquery);
request.query(sqlquery); // execute SP
request.on('row', function (row) // once committed send to the client (website)
{
logger.trace("Updated booking with Reference ID " + row.Ref + " " + sqlquery);
io.emit('updateBooking', row); // sending data
})
request.on('error', function(err) {
logger.error('Update booking SP request error: ' + sqlquery + err);
});
}catch( e){
logger.error('Update booking request error' + sqlquery + ' ' + e);
}
});
} catch(e)
{
var c = JSON.parse(changes.toString());
logger.error('Update booking error for: ' + c + ' ' +e);
}
connection.on('error', function(err) {
logger.error('Update error connection: ' + err);
});
});
});

Websocket server with ssl support (using websocket.io)

I have a simple Websocket server using node.js and websocket.io
var ws = require('websocket.io')
, server = ws.listen(8000);
server.on('connection', function (socket) {
console.log("connected");
socket.on('message', function (message) {
on_message_callback(socket, message);
});
socket.on('close', function () {
on_close_callback(socket);
});
});
And this is a major part of client:
const HOST = "wss://127.0.0.1:8000/";
var websocket = new WebSocket(HOST);
websocket.onopen = function(evt) { ... };
websocket.onclose = function(evt) { ... },
websocket.onerror = function(evt) { ... };
websocket.onmessage = function(evt) { ... };
(I've tested it with wss://echo.websocket.org:443 and works as desired)
Works for HTTP pages as desired. Problem is that I need to work under HTTPS pages, too. I not able to "upgrade" my code to make it work. Can anyone help me? I haven't found any tutorial for websocket.io (I want to keep using the same technologies).
I'm also not sure how to handle certificates. I can only generate self-signed. What for this case? When I create them, I have to import them manually to each browser, so they'll allow this communication?
Thank you.
Finally figured out solution (using Worlize/websocket-node)
const PORT = 8000;
const SUBPROTOCOL = 'sub-protocol';
var WebSocketServer = require('websocket').server;
var https = require('https');
var fs = require('fs');
// Private key and certification (self-signed for now)
var options = {
key: fs.readFileSync('cert/server.key'),
cert: fs.readFileSync('cert/server.crt')
};
// callback function is called only when localhost:8000 is accessed via https protocol
var server = https.createServer(options, function(request, response) {
// it sends 404 response so browser stops loading, otherwise it keeps loading
console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
response.writeHead(404);
response.end();
});
// bind server object to listen to PORT number
server.listen(PORT, function() {
console.log((new Date()) + ' Server is listening on port ' + PORT);
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
// If autoAcceptConnections is set to false, a request event will be emitted
// by the server whenever a new WebSocket request is made
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
// accepts connection and return socket for this connection
var connection = request.accept(SUB_PROTOCOL, request.origin);
console.log((new Date()) + ' Connection accepted.');
// when message is received
connection.on('message', function(message) {
// echo
connection.send(connection, message.utf8Data);
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});

Two way communication between server and client on socket.io node.js

I am trying to write code for server in node.js in which, client running on browser will send some data to server when some ".on" event will occur. Now at server side the task is to receive data coming from client and send that data back to client.
I am using socket.io.
Write now I am doing this as,
Client side:
<p id="ValSlider1"> Curr Val </p>
<input class = "mySlider1" type="range" name="slider" id="slider-0" value="0" min="0" max="100" />
<script>
var socket = io.connect('http://localhost');
$(".mySlider1").change(function() {
var sVal = $(this).val();
socket.emit('ValSlider1', sVal);
console.log('ValSlider1: ' + sVal );
});
socket.on('packet', function (data) {
var valFromServer = data.split('-');
document.getElementById("ValSlider1").innerHTML = valFromServer[0];
document.getElementById("ValSlider2").innerHTML = valFromServer[1];
document.getElementById("ValSlider3").innerHTML = valFromServer[2];
document.getElementById("ValSlider4").innerHTML = valFromServer[3];
$('#container1').html(data);
});
and on server side:
var qs = require('querystring'),
fs = require('fs'),
parser = new require('xml2json'),
urr = require('url'),
app= require('http').createServer(handler).listen(3000),
io = require('socket.io').listen(app);
function handler (req, res) {
var reqObj = urr.parse(req.url, true);
var reqPath = reqObj.pathname;
if ('/' == reqPath ) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile(__dirname + '/client.html', function(err, data) {if (err) {res.writeHead(500);
return res.end('Errorloadingclient.html');
}
res.end(data);
});
}
};
var slider1, slider2, slider3, slider4 ;
io.sockets.on('connection', function(socket) {
socket.on('ValSlider1', function(data){
slider1 = data ;
socket.emit('packet', data);
console.log("Slider 1 Value: " + data);
});
});
setInterval(function () {
var data = slider1 + "-" + slider2 + "-" + slider3 + "-" + slider4;
socket.emit('packet', data);
console.log(data);
},1000);
});
app.maxConnections = 1;
Now, when communication starts initially two-three slider change values are received by server and printed on console but then the values not get updated, server sends previous values only to client.
Also, if I use socket.emit('ValSlider1', sVal); twice at client side it works better, but why it require emit twice am unable to find, any help will appreciated.
Thanks.
I finally managed to do it in this way:
On server side:
var app = require('http').createServer(handler).listen(3000),
var io = require('socket.io').listen(3001);
var publisher = require('socket.io').listen(app);
On client side:
var socket = io.connect('http://localhost:3001');
var socket2 = io.connect('http://localhost');
The client will send data to server on 'socket'. In response, the server will also send some data on the same port. The server will continuously push data on port 3001 at every second which is received in the client with the ".on('data')" event of server1.

Categories