Sunday, July 07, 2013

Node.js and Internet space debris

I've been having a little trouble with certain parts of Node.js. Part of the problem is my lack of familiarity async programming (my kingdom for a horse!), my lack of practical experience with OOP, Node.js's weak module documentation and finally the shared information that has become the Internet space debris (the cloud ;-) ). I ran into a problem with socket.io where I couldn't get client disconnects detected. I ran into one short stub after another. Some mixed in with other modules (such as Express) others just plain wrong (did these things every work?). Now I'm not saying that the Internet is a bad thing. I just wish there were better tools for the average user to filter the data. When I am familiar with the subject, my brain is the best tool. When I am not familiar with the subject, I need to learn and I tend to learn by trial and error (a lot of errors). A prime example, Node.js, socket.io and dealing with clients disconnecting from the server. I couldn't figure out how to get the server to tell me when a user disconnected (or when it received a message, a related problem).

Here's an example of bad information (which I found a lot of):

 # Bad code
io = require('socket.io').listen(app);

// define interactions with client
io.sockets.on('connection', function(socket){
var address = socket.handshake.address;
++userCount;

consolelog("Connect from " + address.address);

socket.emit('message', { 'message' : 'Ready' });
});

io.sockets.on('disconnect', function(){
//var address = socket.handshake.address;
--userCount;

consolelog("Disconnect user");

if(userCount < 0) {
userCount = 0;
}
});

io.sockets.on('message', function(data){
console.log("socket.on Message = " +
data.message + " [" + JSON.stringify(data) + "]");
});

io.sockets.on('disconnect', function(){
//var address = socket.handshake.address;
--userCount;

consolelog("Disconnect user");

if(userCount < 0) {
userCount = 0;
}
});

That's an example of what I pulled together from the debris I found on the Internet. So is it my fault or is that too much junk? It's probably both.

Note the io.sockets.on for disconnect and message. They are outside the io.sockets.on connection (I understand that connect would work too). I finally found an example with both disconnect and message inside the connection function. When I moved them inside I got the expected results.

Here's an example that I found that works (for me, a dangerous statement):

 # Working code (I hesitate to say good code)
io = require('socket.io').listen(app);

// define interactions with client
io.sockets.on('connection', function(socket){
var address = socket.handshake.address;
++userCount;

consolelog("Connect from " + address.address );
socket.emit('message', { 'message' : 'Ready' });

socket.on('disconnect', function(){
//var address = socket.handshake.address;
--userCount;
consolelog("Disconnect from " + address.address);

if(userCount < 0) {
userCount = 0;
}
});

socket.on('message', function(data){
console.log("socket.on Message = " + data.message +
" [" + JSON.stringify(data) + "]");
});
});

So despite sifting through the debris I have been able to pull together a bunch of things I needed, such as sending data from the client to the server from javascript when css makes changes. Also finally figuring out how to fix the disconnect and message issues. I'm still working getting a grip on async programming. In the meantime the Irrigation control system is moving along nicely.

Thursday, July 04, 2013

Node.js, Raspberry Pi and irrigation control, Part 2

In my previous blog entry I created a node.js server that accepts a crontab like configuration to turn on and off the virtual irrigation LEDs in a browser. These virtual LEDs are currently hard coded (part of the user configuration that I still need to work on). I've now added the external interface to digital IO in the form of an Elexol Ethernet/UDP IO24 board (an older revision). I think I've standardized on the device interface. I'll need to create a nice Node.js module for the device interface (something new to learn). I hope to create other interfaces to an Elexol USB interface and some Pi direct IO interfaces.

I'm still not completely happy with my Javascript and the code as it relates to node.js. I do have it under git control so I'm working to get it tagged so I can have one for each device interface. I'll need to get it up on IXR's external git repository.so others can play but that's a bit further down the line at the moment.