I am having this issue were if I am not able to connect to a host, Nodejs stalls. The weird part is I had this working with async.eachSeries when it was a array and the port was static. Does anyone know why?
client = new net.Socket;
hosts = {'google.com': '443', 'yahoo.com': '80','msn.com': '444'};
client.setTimeout(1000, function () {
console.log("Timeout has occurred")
});
async.eachOfSeries(hosts, function(port,host,callback) {
client.connect(port, host, function() {
console.log('Connected to ' + host + " on port " + port);
client.destroy();
callback();
});
});
client.on('timeout', function() {
console.log('client has timed out');
client.destroy(); // kill client after server's response
});
Thank you,
John
msn.com connection on port 444 fails and and the last 'callback' (after successful connect) is never called- which is why node stalls.
Check the following code which solves this (notice msn call is now the first one and just times out- I feel it's better for understating the flow).
var async = require('async');
var net = require('net');
hosts = { 'msn.com': '444', 'google.com': '443', 'yahoo.com': '80' };
async.eachOfSeries(hosts, function (port, host, callback) {
client = new net.Socket;
client.setTimeout(1000, function () {
console.log("Timeout has occurred")
});
client.connect(port, host, function () {
console.log('Connected to ' + host + " on port " + port);
client.destroy();
callback();
}).on('timeout', function () {
console.log('client has timed out');
client.destroy();
callback();
});
});
Related
I'm integrating websockets with express on the backend and using browser's native websocket api on the client side. I have so far been able to send and receive message from the client to server and server back to client. But all this happens with a page refresh only. Isn't websocket supposed to be real time? Lets say I make a change in the message on server file, then it has to immediately reflect in my browser's console. and lets say I make a change in the message in the script file on the client side, then it has to immediately show the changes on server's console.(Also I'm using nodemon to run the server so changes has to reflect pretty quickly). But right now, I see myself making a request to / via page refresh and then server upgrading and then responding back with the message.
Please tell me if I'm missing something in the code or otherwise in the concept?
app.js
const express = require('express')
const app = express()
const path = require('path')
const WebSocketServer = require('websocket').server;
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname, '/public')))
const port = 8080
app.get('/', (req, res) => {
res.render('index')
})
const server = app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
wsServer = new WebSocketServer({
httpServer: server
});
function originIsAllowed(origin) {
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept(null, request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF("server says hi");
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
client.js:
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello to Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
I am not sure if I understand the question, but if you want the client to send message to server, you have do it the same way as it is done in open listener:
socket.send('MESSAGE FOR SERVER') or, if server should send something to client, then just
connection.send('MESSAGE FOR CLIENT').
Realtime communication with WebSocket means, the connection is created only once and the protocol is kept opened (Unlike REST API, where the connection is created with every request.)
The message must be sent actively either from server or client, there is nothing observing some message state and updating it on the other side.
I have created one socket server in node js where I can send some data and receive from the server, but the problem is every time connection is closing and creating new PID for another request. here my requirement is once my IOT device connects to the server then the connection should stay there and I want to send, receive data any time.
Can anyone help me out?
I am posting my code below
Server code
var net = require('net');
// Create Server instance
var server = net.createServer(main);
server.listen(9010, function() {
console.log('server listening on %j', server.address());
});
function main(sock) {
sock.setEncoding("utf8");
sock.on('data', function(data) {
var data = data;
console.log('Request data is ', data);
console.log('Says:', data);
sock.write("responding to client");
sock.write(' exit');
});
sock.on('close', function () {
console.log('connection closed');
});
sock.on('error', function (err) {
console.log('Connection error: %s', err.message);
});
};
Client code
var net = require('net');
//params
var HOST = 'myhost';
var PORT = 9010;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('Hello socket server');
});
client.on('data', function(data) {
console.log('Recieved data: ' + data);
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
My Code Looks Like this
var Client = require('ssh2').Client;
var fs=require('fs');
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.shell('xtail', function(err, stream) {
stream.write('xtail\n\r');
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
// stream.stdin.write('?');
console.log('hey');
console.log('STDOUT: ' + data);
fs.appendFile('D:\\Breme\\As1.txt',data,function(err){
if(err)
{
console.log(err);
}
//console.log('file saving..')
});
// setTimeout(function(){
// process.exit(1);
// }, 20000);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
conn.destroy();
});
});
}).connect({
host: '10.214.14.15',
port: 22,
username: 'bwadn',
password: 'bwain'
});
after connecting to server I am downloading the file but I want to send 'Ctrl+C' command from client, so that it stops receiving data
Can anyone please help me in solving this, As i am new to NodeJS I need your support in solving this...thanks
Most reliable way in this particular case, since you are using a variant of tail in your shell, is to use
stream.write('\x03'); //send ctrl+c
you would need to send it when you know you don't need xtail output anymore. It is beyond the scope of this question to discuss the means, but setTimeout is definitely not a good idea.
Alternative (preferred) method:
stream.signal('INT')
and for other uses see Ssh2 Channel API
Testing node httpServer and webSocketServer(ws)
Trying to implement a http-ws server that will close after a client is connected as illustrated below:
var HTTPserver =
httpServer(require('path')
.join(__dirname, 'www'));
HTTPserver
.on('listening', function()
{
console.log('HTTP listening:');
//---------------
var WebSocket = require('ws');
var webSocketServer =
new WebSocket.Server(
{
server: HTTPserver
});
webSocketServer
.on('connection',
function(ws)
{
console.log('client connected');
setTimeout(function()
{
console.log('trying to close webSocketserver');
webSocketServer.close();
setTimeout(function()
{
console.log('trying to close HTTPserver');
HTTPserver.close();
}, 1000);
}, 1000);
});
})
.on('close', function()
{
console.log('server closed'); // never happens
})
.on('error', function()
{
console.log('server error');
})
.listen(8000);
// this works when no Client Connection
/*
setTimeout(function()
{
HTTPserver.close();
}, 3000);
*/
I uploaded the full test project.
https://github.com/kenokabe/http-ws-test
HTTPserver.close(); works just as expected without ws client connections.
HTTPserver.close(); does not work (fails to close) with ws client connections.
Any idea what is going on and how to fix this issue? Thanks.
**PS. Please note that what I need to close is
NOT only ws connections but also httpServer.
I need to open and close whole frequently.
The reason to close httpServer is that the project is for plugin, and need to shut down httpServer in a specific case.**
UPDATE
I modified the code to close webSocketServer before httpServer, but still httpServer is alive.
I updated my gitHub
https://github.com/kenokabe/http-ws-test
Finding
How do I shutdown a Node.js http(s) server immediately?
Force close all connections in a node.js http server
connection->socket needs to be destroyed for each.
For my sample code, I use ES6 observe method.
http://wiki.ecmascript.org/doku.php?id=harmony:observe#object.observe
http://wiki.ecmascript.org/doku.php?id=harmony:observe_api_usage
https://github.com/jdarling/Object.observe
var IO = {
terminate:
{
val: false
}
};
var trigger = function(obj)
{
obj.val = !obj.val;
};
var HTTPserver =
httpServer(require('path')
.join(__dirname, 'www'));
var webSocketServer;
HTTPserver
.on('listening', function()
{
console.log('HTTP listening:');
//---------------
var WebSocket = require('ws');
webSocketServer =
new WebSocket.Server(
{
server: HTTPserver
})
.on('connection',
function(ws)
{
console.log('client connected');
});
})
.on('close', function()
{
console.log('server closed'); // never happens
})
.on('error', function()
{
console.log('server error');
})
.on('connection', function(socket)
{
console.log('connection');
Object.observe(IO.terminate, function(changes)
{
console.log('now!2');
socket.destroy();
});
})
.listen(8000);
setTimeout(function()
{
console.log('now');
HTTPserver.close();
webSocketServer.close();
trigger(IO.terminate);
}, 15000);
I'm planning to use nodeJS as my comet server and I wrote some code for testing, but there is an issue that when client connected to the server for the first time, it couldn't get response from server.
Here is the server-side code (server.js):
var util = require('util');
var redis = require('redis').createClient(6379, '192.168.1.254');
var http = require('http');
redis.on("error", function (err) {
console.log("Error " + err);
});
var server = http.createServer(requestListener);
server.listen(9898, '192.168.1.254');
function requestListener(req, res) {
util.log('Connected.');
redis.brpoplpush('msg:q:1', 'msg:s:1', 20, function(err, reply) {
if (err) {
util.log('ERROR: ' + err);
}
var length = reply ? reply.length : 0;
res.writeHead(200, {
'Content-Type':'text/plain',
'Content-Length':length
});
if (length) {
res.end(reply);
util.log('Sent: ' + reply);
} else {
res.end('');
}
});
}
And the client code (client.sh):
#!/bin/bash
while [ 1 ]
do
curl -i http://192.168.1.254:9898
done
I tested it following steps:
node server.js
./client.sh
In redis, LPUSH('msg:q:1', 'blablah')
Now, "Sent: blablah" printed on console, res.end(reply) excuted, but client receives nothing. I repeat step 3 for many times, then it works as expect. If I restart the client, the first few responses can't be received again.
How can I resolve this?
I think what might happening here is you've aborted curl while it was waiting for the response from redis. After the HTTP client is aborted, the redis command still stays active. You then push another element onto the queue, the redis command returns, but has no HTTP response to write it to. When you start the curl loop again, you find the queue empty.
Here's a modified version of your program that streams the response and detects a client abort. It doesn't put the element back on the queue, but you could certainly do that as well.
var util = require('util');
var redis = require('redis').createClient();
var http = require('http');
redis.on("error", function (err) {
console.log("Redis error " + err);
});
redis.on("ready", function () {
console.log("Redis client ready");
});
var server = http.createServer(requestListener);
server.listen(9898);
function requestListener(req, res) {
var aborted = false;
res.writeHead(200, {
"Content-Type": "text/plain"
});
res.write("Checking redis...\n");
redis.brpoplpush('q', 's', 20, function (err, reply) {
if (aborted) {
return console.log("Client aborted before redis reply came back.");
}
if (err) {
return res.end("Redis error");
}
res.end("Redis reply: " + reply);
});
req.on("aborted", function () {
console.log("HTTP client aborted.");
aborted = true;
});
}