Why does this loop break my code? - javascript

Fair warning, I am a novice with javascript and ool. I am trying to put together a simple script to parse data out to a web socket. The script should be able to handle an infinite number of payloads.
This code works, although can only handle on payload at a time:
#!/usr/bin/env node
var io = require('socket.io-client');
var i=1
socket = io.connect('http://10.0.9.1:80');
var data = JSON.parse(process.argv[2]);
socket.on('connect', function(){
console.log('Emitting');
socket.emit('widget', data);
process.exit(0);
});
Wrapping the code in a loop with a logic test breaks it. No syntax errors, but it does not seem to call the emit method.
#!/usr/bin/env node
var io = require('socket.io-client');
var i=1
var data
while (true) {
i++
if ( process.argv[i] ) {
socket = io.connect('http://10.0.9.1:80');
data = JSON.parse(process.argv[2]);
socket.on('connect', function(){
console.log('Emitting');
socket.emit('widget', data);
});
} else {
process.exit(0);
};
};

The sockets you are creating are async, so you end up creating a bunch of sockets and then call process.exit(0) before there's time to establish the connection

There were many mistakes in my first attempt. Clues from ControlAltDel and mrid made me realize my loop structure was all wrong. The loop should have been placed within the on('connect') like so:
#!/usr/bin/env node
var io = require('socket.io-client');
var i=1
var data
socket = io.connect('http://10.0.9.1:80');
socket.on('connect', function(){
while (true) {
i++;
if ( process.argv[i] ) {
data = JSON.parse(process.argv[i]);
console.log('Emitting ');
socket.emit('widget', data);
} else {
process.exit(0);
};
}
});

Related

NodeJS - where to place functions for eval()

I have a NodeJS-Server which communicated with the fronend via Websocket-Connection.
When the Server gets a on('message'), it should run a function which name is given the message via eval().
it workes fine, unless I completely don't know where to put the funcions to be called.
var http = require('http');
var ws = require('ws');
function render(vars) {
var server = http.createServer(function(req, res) {
.....
});
/* WEBSOCKET */
var wsServer = new ws.Server({server});
wsServer.on('connection', socket => {
socket.on('message', message => {
console.log('WS from template <-- ', message);
var wsIn = JSON.parse(message);
eval(wsIn.action);
});
});
}
when a message is incoming, eval(wsIn.action) should run a function called.. .lets assume runme.. so where would I now need to declare this function ? I try everything but whatever I do, i get
ReferenceError:: runme is not defined
edit:
I found out something interesting:
when i call a function normal like runme(); in my onMessage.. everything is cool.. but with eval(runme); nothing happens.. no error, no output, nothing..

Send a message in socket.io-client

I have a direct question: can use in socket.io-client a method like in socket.io io.sockets.emit() to broadcast messages?
Here is my code and what a want to do:
var ioc = require('socket.io-client');
var s = ioc.connect("http://localhost:8000/", {reconnection: true});
s.on('connect', function () {
//...
}
//I want here out side of the <connect event> to send a message with socket.io-client
So thanks guys, the problem on from anothor place, I fixed it on my own like a man.
var ioc = require('socket.io-client');
var s = ioc.connect("http://localhost:8000/", {reconnection: true});
s.on('connect', function () {
...........
}
s.emit('msg','message')

node: custom emitter backing up when socket.io connection is established

I have a spawn function that is continuously outputting new information. I'm monitoring the output of that spawn via the 'data' event and emitted a custom emitter that I call 'updated' that emits whenever new data is received from the spawn. After each 'data' event occurs the data stored in partialData is emitted with the 'updated' emitter and then cleared.
This seems to work fine but when socket.io is implemented, the 'data' event seems to be ran but the results in partialData don't get processed, pile up on each other, and then several occurrences of the 'data' event get emitted at once. Why is this occuring and how do I resolve this issue? In the real application I'm using this in JSON strings are being handled and the pileup is causing node to crash.
This example is a simplified version of a larger application but the symptoms are the same. The following example consists of a bash script to emit a timestamp every 1/5th of second which should be ran from the same directory as the node code. After you launch the node command the terminal will output the timestamp and length of partialData. You will notice a change in the length of partialData whenever you browse to 127.0.0.1:3000. This is the issue.
emitter.sh:
#!/bin/bash
while [[ 1 ]]; do
echo `date +%s`
usleep 20000
done
emitter.js:
var express = require('/usr/local/lib/node_modules/express');
var http = require('http');
var spawn = require('child_process').spawn;
var events = require('events');
var util = require('util');
var app = express();
var server = http.createServer(app);
var io = require('/usr/local/lib/node_modules/socket.io').listen(server);
runCommand = function (arg1) {
var self = this;
var partialData = '';
var cmd = spawn(arg1);
cmd.stdout.setEncoding('utf8');
cmd.stdout.on('data', function(data) {
partialData += data.substr(0,data.length-1);
console.log('data: '+partialData.trim());
console.log('length: '+partialData.length);
partialData = '';
self.emit('updated', data);
});
}
util.inherits(runCommand, events.EventEmitter);
var result = new runCommand('./emitter.sh');
app.get('/', function(req, res){
res.send(
"<script src='/socket.io/socket.io.js'></script>\n"+
"<script>\n"+
"var socket=io.connect('http://127.0.0.1:3000');\n"+
"</script>\n"
);
});
server.listen(3000);
io.sockets.on('connection', function(webSocket) {
console.log('socket established');
});
There's no guarantee that the data event will be triggered every time your shell script has outputted a line; when other I/O takes place (like your socket.io example), the output is allowed to be buffered.
If you want line-support, you can use the readline module:
var cmd = spawn(arg1);
cmd.stdout.setEncoding('utf8');
var linereader = require('readline').createInterface(cmd.stdout, cmd.stdin);
linereader.on('line', function(line) {
...
});

calling a socket inside another socket using node.js and socket.io

I am a trying to use socket.io and node.js like this :
The browser sends an event to socket.io, in the data event I call another server to get some data, and I would like to send back a message to the browser using a socket.emit.
This looks like that :
socket.on('ask:refresh', function (socket) {
const net = require("net");
var response = new net.Socket();
response.setTimeout(1000);
response.get_response = function (command, port, host) {
this.connect(port, host, function () {
console.log("Client: Connected to server");
});
this.write(JSON.stringify({ "command": command }))
console.log("Data to server: %s", command);
};
response.on("data", function (data) {
var ret = data.toString();
var tmp_data = JSON.parse(ret.substring(0, ret.length - 1).toString());
var data = new Object();
var date = new Date(tmp_data.STATUS[0].When * 1000 );
data.date = date.toString();
socket.emit('send:refresh', JSON.stringify(data) );
});
response.get_response("version", port, host);
});
};
The thing is that I cannot access "socket.emit" inside response.on.
Could you please explain me how I can put a hand on this ?
Thanks a lot
You appear to be overwriting the actual socket with the one of the callback parameters:
socket.on('ask:refresh', function(socket) {
// socket is different
});
Change the name of your callback variable, and you won't have this problem.

Node.js module level variables are undefined

I'm having an issue accessing the scope of a module level variable from within a function inside of said module. See below...
var socketio = require('socket.io');
var socket = socketio.listen();
var myCustomModule = require('./lib/mycustommodule')('http://mysite:8080');
socket.on('connection', function connection(socket) {
socket.emit('message', {data:"test1"}); <====THIS WORKS
socket.on('init', function init(data) {
socket.emit('message', {data:"test1"}); <====THIS WORKS
refreshMyCustomModule();
});
});
var refreshMyCustomModule = function() {
socket.emit('message', {data:"test1"}); <=====THIS DOESN'T WORK
myCustomModule.beginSomeAsyncTask(function(data) { <======THIS DOESN'T WORK
socket.emit('message', {data:"test2"}); <========THIS DOESN'T WORK
});
};
Looking at the sample above. When I call my refreshMyCustomModule function suddenly socket and myCustomModule become undefined. I've also tried using this as well as setting up a var self = this.
I've written a bunch in javascript on the client but when coding in node.js it seems like scoping is different and I just can't crack this nut.
Note that the socket at the global level of your script and socket within your function connection are two different variables. The one inside your function connection is the argument that was passed into that function from the connection event. The one you're using in refreshMyCustomModule is the global one, the one on which you called listen.
This is clearer if we change their names, since they're different variables:
var socketio = require('socket.io');
var socketUsedForListen = socketio.listen();
var myCustomModule = require('./lib/mycustommodule')('http://mysite:8080');
socketUsedForListen.on('connection', function connection(socketFromConnection) {
socketFromConnection.emit('message', {data:"test1"});
socketFromConnection.on('init', function init(data) {
socketFromConnection.emit('message', {data:"test1"});
refreshMyCustomModule();
});
});
var refreshMyCustomModule = function() {
socketUsedForListen.emit('message', {data:"test1"});
myCustomModule.beginSomeAsyncTask(function(data) {
socketUsedForListen.emit('message', {data:"test2"});
});
};
I'm reasonably certain you meant to use socketFromConnection in refreshMyCustomModule, not socketUsedForListen. If so, either move the refreshMyCustomModule into your connection callback, or pass the socket into it as an argument.
It's because you're using an async event in socket.on('init') that leads to the scope issue. I believe if you pass in the parameters you want to use from the parent it will work. e.g.:
var socketio = require('socket.io');
var socket = socketio.listen();
var myCustomModule = require('./lib/mycustommodule')('http://mysite:8080');
socket.on('connection', function connection(socket) {
socket.emit('message', {data:"test1"}); <====THIS WORKS
socket.on('init', function init(data) {
socket.emit('message', {data:"test1"}); <====THIS WORKS
refreshMyCustomModule(socket, myCustomModule);
});
});
var refreshMyCustomModule = function(socket, module) {
socket.emit('message', {data:"test1"}); <=====THIS DOESN'T WORK
module.beginSomeAsyncTask(function(data) { <======THIS DOESN'T WORK
socket.emit('message', {data:"test2"}); <========THIS DOESN'T WORK
});
};

Categories