Node.js TCP client behaving differently from Netcat/Telnet - sockets

I am issuing newline-separated text commands to a custom protocol TCP server. In the example below I issue 2 commands and receive a response written back. It works as expected in telnet and netcat:
$ nc localhost 1234
command1
command2
theresponse
The same workflow is not working when connecting with Node.js:
var net = require('net');
var client = net.connect(1234, 'localhost');
client.on('data', function(data) {
console.log('data:', data.toString());
});
client.on('error', function(err) {
console.log('error:', err.message);
});
client.write('command1\n');
client.write('command2\n');
I would expect that after running this program I would see "data: theresponse" written to the console, however, nothing is ever printed. I have also tried performing the writes inside of the "connect" callback, but I have the same results. The curious thing is that when I try this in the Node REPL...it works:
$ node
> var net = require('net')
undefined
> var client = net.connect(1234, 'localhost')
undefined
> client.on('data', function(data) { console.log('data:', data.toString()); })
{ ... }
> client.write('command1\n')
true
> client.write('command2\n')
true
> data: theresponse
Anyone have ideas about this bizarre behavior?
Thanks.
-Scott

Without testing the code, I'm presuming it's the asynchronous nature of Node.js that's biting you. In the REPL the connection happens before you can type in another command. In your code above you are writing before you are connecting.
Change the above code to this:
var net = require('net');
var client = net.connect(1234, function(){
client.on('data', function(data) {
console.log('data:', data.toString());
});
client.on('error', function(err) {
console.log('error:', err.message);
});
client.write('command1\n');
client.write('command2\n');
});

Related

iPhone doesn't connect to the web socket but the simulator does

Physical devices cannot connect to my web socket. I tried it with 3 different phone and with different networks. It works fine with my simulators though. I am not getting an error message apart from the standard "Cannot connect to the server" from socket.io on the client.
I don't know if this is a valid indicator but I also tried using https://www.websocket.org/ with the following parameter:
wss://converzone.htl-perg.ac.at:5134
I am getting a "ERROR: undefined DISCONNECTED" there.
I am using an ubuntu server which runs Ubuntu 16.04. The web socket is from socket.io and I am coding with Swift on the client and with Node.js on the server. This whole thing is running on my school's server.
// Here is an array of all connections to the server
var connections = {};
io.sockets.on('connection', newConnection);
function newConnection(socket) {
console.log(socket.id + " connected.");
socket.on('add-user', function(user) {
connections[user.id] = {
"socket": socket.id
};
});
socket.on('chat-message', function(message) {
console.log(message);
if (connections[message.receiver]) {
console.log("Send to: " + connections[message.receiver].socket);
//io.sockets.connected[connections[message.receiver].socket].emit("chat-message", message);
io.to(connections[message.receiver].socket).emit('chat-message', message);
} else {
console.log("Send push notification")
sendPushNotificationToIOS(message.senderName, message, message.deviceToken, message.sound)
}
});
//Removing the socket on disconnect
socket.on('disconnect', function() {
console.log("The client disconnected");
console.log("The new list of clients is: " + connections)
for (var id in connections) {
if (connections[id].socket === socket.id) {
delete connections[id];
break;
}
}
})
}
Please understand that this problem seems very weird to me. I have changed the AppTransferProtocol in my plist and changed the port from 3000 to 5134. Nothing changed. Tell me what code would seem relevant apart from the (minimal) server code.

gulp task with gulp-run-command doesn't work properly

I'm trying to run json-server in a gulp task and I'm checking if the server runs, with the function portInUse.
Like this:
var gulputil = require('gulp-util')
var run = require('gulp-run-command').default
var gulp = require('gulp')
const args = [
'json-server --watch .\\src\\main\\app\\reactjs\\api\\db.json --port 3005'
]
var net = require('net');
var portInUse = function(port, callback) {
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(port, '127.0.0.1');
server.on('error', function (e) {
callback(true);
});
server.on('listening', function (e) {
server.close();
callback(false);
});
};
gulp.task("initLocalJsonServer", function() {
portInUse(3005, function(returnValue) {
gulputil.log('1 ' + returnValue);
});
run(args);
portInUse(3005, function(returnValue) {
gulputil.log('2 ' + returnValue);
});
});
That command that is the value of args here, works as intended when I run it in command line, so there's nothing wrong with the command or json-server itself. If I run it, I get to see the json-server at localhost:3005
Now the output from the portInUse function indicates that the server starts, as the output is:
[10:33:56] 1 false
[10:33:56] 2 true
But if I go to localhost:3005 after the gulp tasks are done, I can't see any server running. What might be the reason?

How to use botkit with facebook and wit.ai

I am a novice in chatbot development and I would like some help.
While it seems quite simple to connect botkit with facebook messenger and wit.ai in orger to use NLP. I haven't managed to do so. My initial goal is to have a simple conversation like hello-hello but using wit.ai as middleware.
Below I attach the code. What it should do is receive a "hello" message, pass it to wit.ai and then respond "I heard hello!" as a reply (without using wit at this stage). Instead I just receive
debug: RECEIVED MESSAGE
debug: CUSTOM FIND CONVO XXXXXXXXXXXXXX XXXXXXXXXXXXXX
debug: No handler for message_received
after every message I send to facebook messenger bot. In wit it seems like I am getting the messages since I receive messages in my inbox to update the intents.
If there is any code much simpler than the one below I would be very happy to have it so that I can start with something much simpler :).
Thanks
<pre><code>
if (!process.env.page_token) {
console.log('Error: Specify page_token in environment');
process.exit(1);
}
if (!process.env.page_token) {
console.log('Error: Specify page_token in environment');
process.exit(1);
}
if (!process.env.verify_token) {
console.log('Error: Specify verify_token in environment');
process.exit(1);
}
if (!process.env.app_secret) {
console.log('Error: Specify app_secret in environment');
process.exit(1);
}
var Botkit = require('./lib/Botkit.js');
var wit = require('./node_modules/botkit-middleware-witai')({
token: process.env.wit,
minConfidence: 0.6,
logLevel: 'debug'
});
var os = require('os');
var commandLineArgs = require('command-line-args');
var localtunnel = require('localtunnel');
const ops = commandLineArgs([
{name: 'lt', alias: 'l', args: 1, description: 'Use localtunnel.me to make your bot available on the web.',
type: Boolean, defaultValue: false},
{name: 'ltsubdomain', alias: 's', args: 1,
description: 'Custom subdomain for the localtunnel.me URL. This option can only be used together with --lt.',
type: String, defaultValue: null},
]);
if(ops.lt === false && ops.ltsubdomain !== null) {
console.log("error: --ltsubdomain can only be used together with --lt.");
process.exit();
}
var controller = Botkit.facebookbot({
debug: true,
log: true,
access_token: process.env.page_token,
verify_token: process.env.verify_token,
app_secret: process.env.app_secret,
validate_requests: true, // Refuse any requests that don't come from FB on your receive webhook, must provide FB_APP_SECRET in environment variables
});
var bot = controller.spawn({
});
controller.setupWebserver(process.env.port || 3000, function(err, webserver) {
controller.createWebhookEndpoints(webserver, bot, function() {
console.log('ONLINE!');
if(ops.lt) {
var tunnel = localtunnel(process.env.port || 3000, {subdomain: ops.ltsubdomain}, function(err, tunnel) {
if (err) {
console.log(err);
process.exit();
}
console.log("Your bot is available on the web at the following URL: " + tunnel.url + '/facebook/receive');
});
tunnel.on('close', function() {
console.log("Your bot is no longer available on the web at the localtunnnel.me URL.");
process.exit();
});
}
});
});
controller.middleware.receive.use(wit.receive);
controller.hears(['hello'], 'direct_message', wit.hears, function(bot, message) {
bot.reply(message, 'I heard hello!');
});
function formatUptime(uptime) {
var unit = 'second';
if (uptime > 60) {
uptime = uptime / 60;
unit = 'minute';
}
if (uptime > 60) {
uptime = uptime / 60;
unit = 'hour';
}
if (uptime != 1) {
unit = unit + 's';
}
uptime = uptime + ' ' + unit;
return uptime;
}
Make sure you have a few conversations in Wit.ai beforehand so for example hello there and highlight the hello in that statement as something like, greetings.
Now i'm not sure what your intents are called in wit.ai but in your statement controller.hears(['hello'] you're actually listening to the wit.ai intents. So in the example i mentioned above, we'd be using hears(['greetings']) since that's the intent in wit.ai.
Also, instead of using direct_message use message_received this is what it should look like:
controller.hears(['hello'], 'message_received', wit.hears, function(bot, message) {
bot.reply(message, 'I heard hello!');
});
If you're struggling tracking down the problem you can stick a console statement in your controller so something like console.log("Wit.ai detected entities", message.entities); and see what you get back from that.
Let me know if you're still having any issues :)

How to know my socket connect is success or not?

I want to do something when the nodejs server is started or I will do something else not related to the server.
But how could I know that. There is no property that shows the status of the connection, and because the socket is asynchronous that I can't get the err by try..catch...
The following is my clinet code.
var socket = io.connect('http://localhost:3000/monitor');
socket.on('message', function (data) {
console.log(data);
});
Anyone can tell me how to if(is connected).. else.. in this place?
Try listening to the following events:
socket.on( 'connect', function() {
});
socket.on( 'disconnect', function() {
});
socket.on( 'connect_failed', function() {
});
socket.on( 'error', function() {
});
Socket.io has some bugs in firing some events so it's better to listen to all of those that might mean a connection failed.

Net Module Nodester not Listening to Port

I have a basic node.js app that is designed to open up a connection between two clients and echo the input of one to the other.
var net = require("net");
console.log("Relay Started");
var id = 0;
var Socket = [];
relay = net.createServer(function(socket) {
socket.on('connect', function() {
console.log('Connected');
if(socket.id==null) {
socket.id = id;
Socket[id]=socket;
id++;
}
});
socket.on('data', function(data) {
data = data.toString()
if (socket.id==0) {
Socket[1].write(data);
} else if (socket.id==1) {
Socket[0].write(data);
}
console.log(socket);
console.log(data.toString());
});
})
relay.listen(process.env['app_port']||8080);
It works fine when run locally, however when I put it onto a Nodester development server, I am unable to connect by using telnet zapcs.nodester.com 18007 (it is hosted under the name zapcs, and the given port is 18007). The Relay Started is logged, but nothing after that, and no connection. Any ideas on why this would be?
~
you can not telnet zapcs.nodester.com 18007, you only can connect to zapcs.nodester.com:80 by http or websock, nodester will route your request to your app actual port (18007) on the host.
And check this: http://www.slideshare.net/cmatthieu/nodester-architecture-overview-roadmap-9382423