Cannot read property 'socket's of undefined when exporting socket.io - node.js

I'm trying to modularize my application and would like to emit different event to client on different js file. Sample code below shows that an event 'onlinestatus' will be fired from led.js. However I keep on getting the message 'Type Error: Cannot read property 'sockets' of undefined' whenever I try to emit the event from led.js. I suspect something could be wrong when I"m trying to export the io from /bin/www.
/bin/www
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var connectedClientsNum = 0;
io.sockets.on('connection', function(socket) {
console.log("client connected!");
socket.on('disconnect', function() {
console.log("Client disconnected...");
console.log("Total Clients Connected: " + --connectedClientsNum);
})
});
...
module.exports = server;
module.exports.io = io;
led.js
var io = require('../bin/www').io;
...
function toggleLed(leds, err, callback) {
/* toggle the led value */
if (leds[0].value == 0) {
leds[0].value = 1;
leds[0].save(function(err) {
if (err) {
err("update led error");
}
else {
var person= {"status": "online"};
io.sockets.emit('onlinestatus', person);
callback("update led from 0 to 1 success");
}
});
}
else {
leds[0].value = 0;
leds[0].save(function(err) {
if (err) {
err("update led error");
}
else {
var person= {"status": "offline"};
io.sockets.emit('onlinestatus', person);
callback("update led from 1 to 0 success");
}
});
}
}

You should check the Docs at socket.io and check to see if there is actually still a socket.sockets.on() function still in the socket.io framework. I'm not sure if it is still there. If you must have it working, you could try changing versions of socket.io to 0.9, which would be where I think that would work.

Related

How to Emit data from function using Socket io

I am very beginner in NodeJS, I am taking data from S71200 PLC device using nodes7 library, I want to pass data using socket io emit but I can't pass data to socket io emit below my code
app.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var nodes7 = require('nodes7'); // This is the package name, if the repository is cloned you may need to require 'nodeS7' with uppercase S
var conn = new nodes7;
var doneReading = false;
var doneWriting = false;
var variables = {
TEST7: 'DB1,INT2.3',
TEST1: 'DB1,X0.0.3',
TEST2: 'DB1,INT2'
};
conn.initiateConnection({port: 102, host: '127.0.0.1', rack: 0, slot: 1}, connected);
function connected(err) {
if (typeof(err) !== "undefined") {
// We have an error. Maybe the PLC is not reachable.
console.log(err);
process.exit();
}
conn.setTranslationCB(function(tag) {return variables[tag];}); // This sets the "translation" to allow us to work with object names
conn.addItems(['TEST7','TEST1']);
//conn.writeItems('TEST2', 90, valuesWritten);
setInterval(function(){
conn.readAllItems(valuesReady);
},1000)
}
function valuesReady(anythingBad, values) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
console.log(values.TEST1[0],values.TEST1[1],values.TEST1[2],values.TEST7[0],values.TEST7[1],values.TEST7[2]);
//console.log( typeof(temp));
doneReading = true;
}
function valuesWritten(anythingBad) {
if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
console.log("Done writing.");
doneWriting = true;
}
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit("channelname", {
message: "Passing S71200 data"
});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
http.listen(3000,function(){
console.log('server listening on port 3000');
})
I am using interval function because every second data fetch from PLC device, I got all data from values.TEST1[0],values.TEST1[1],values.TEST1[2],values.TEST7[0],values.TEST7[1],values.TEST7[2] this data passing to
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit("channelname", {
message: "Passing S71200 data"
});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
Help me to solve this problem

NodeJS Net.createServer

Hey uh I am having an issue and I think this is probably related to net.createserver.
The issue is that whenever the first client joins after that another second client joins, the first client can control the second client and then the first client disconnects because the socket(end) event gets triggered. Is it related to sockets or something or the server can't handle two connections? Please help
The code:
handleGame: function() {
console.log(log.success('The source is starting!'));
var server = net.createServer(function(socket) {
console.log('A client has connected' + "\r\n");
socket.setEncoding('utf8')
global.clientObjz = new client(socket);
game.addClient(clientObjz);
socket.on('data', function(data) {
data = data.toString().split('\0')[0];
console.log('Incoming data: ' + data + "\r\n")
if (data == "<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>" | data == "<msg t='sys'><body action='rndK' r='-1'></body></msg>" | data.startsWith("<msg t='sys'><body action='login' r='0'>")) {
parseXml(data, function(err, result) {
var type = result.msg['$'].t,
action = result.msg.body[0]['$'].action;
var method = Game.xmlHandlers[type][action];
if (typeof Game[method] == 'function') {
Game[method](data, client);
}
});
}
var dataType = data.charAt(0);
if (dataType == '%') {
game.handleraw(data, clientObjz);
}
});
socket.on('end', function() {
game.removeClient(socket);
console.log('A client has disconnected');
});
socket.on('error', function(err) {
console.log(err);
});
});
server.listen(Game1, "localhost", function() {
console.log('Server is listening on port 6113');
});
}
//this code is another file as i am calling it by game.clients.push
addClient: function(client) {
if (client) {
self.clients.push(client);
}
}
Yes, it's a clubpenguin emulator
full code: https://github.com/dev3211/bingojs
You need to implement socket channels if you are doing this only with NodeJS net.createServer. If you want it simple, you could look for something using express.js, something like this: https://medium.com/factory-mind/websocket-node-js-express-step-by-step-using-typescript-725114ad5fe4

NodeJS net module - don't try to create another instance of TCP server when called again

I'm totally new to the whole nodeJS asynchronous-y callback-y programming so I need more like a guidance to understanding what I'm even doing. With that said, I have two files main.js and server.js
My main file looks like this:
var server=require('./server.js');
server();
function WhenUserClicksButton(){
server();
}
and my server file looks like this:
var net = require('net');
function server(){
net.createServer(function (socket) {
socket.write('\x16'); //SYN character
socket.on('data', function (data) {
//handle data from client
});
}).listen(33333);
}
First call of server(); starts the TCP server. Then function WhenUserClicksButton is called when user clicks button (duhh) in a GUI. But it attempts to start the server again so I get
Error: listen EADDRINUSE :::33333
I got why this is happening but I can't think of a solution for it. What I really need is:
Start the server and listen on 33333
When nothing is happening server and client just exchanges SYN and ACK characters every few seconds (I already have this part done, I just removed it from this example for clarity because it's not really topic of this question)
When user click button change socket.write('\x16'); to socket.write('something');
Then wait for server and client to exchange data and after everything is done return results back to main.js
As I said, I'm new to this and I believe my problem lies in not understanding fully of what I'm doing. Any help and explanations are welcome!
I think you're very near where you need to be. I would do something like this:
server.js
var net = require('net');
var netServer = null;
var netSocket = null;
function sendData(data) {
if (netServer && netSocket) {
console.log('Send data: sending: ', data);
netSocket.write(data);
}
}
function startServer(){
netServer = net.createServer(function (socket) {
netSocket = socket;
socket.write('\x16'); //SYN character
socket.on('data', function (data) {
console.log('Server: data from client: ', data);
if (data.length === 1 && data[0] === 0x16) {
// log and ignore SYN chars..
console.log('SYN received from client');
} else if (newDataCallback) {
newDataCallback(data);
};
});
});
console.log('Server listening on 33333..');
netServer.listen(33333);
}
var newDataCallback = null;
function setNewDataCallback(callback) {
newDataCallback = callback;
}
module.exports = {
sendData: sendData,
startServer: startServer,
setNewDataCallback: setNewDataCallback
};
main.js
var server = require('./server');
function newDataCallback(data) {
console.log('newDataCallback: New data from server: ', data);
}
server.setNewDataCallback(newDataCallback);
server.startServer();
function wheneverUserClicksButton() {
server.sendData('something');
}
testClient.js
var clientSocket = net.createConnection(33333, "127.0.0.1");
clientSocket.on('data', (someData) => {
console.log('Data received', someData);
});
clientSocket.on('connect', () => {
console.log('Client Socket connected ');
clientSocket.write('Hello from client');
});

automatically pair up peer to peer connections using socket.io, socket.io-p2p, socket.io-p2p-server

I am attempting to hook up a small game with WebSockets. I am using socket.io, socket.io-p2p, and socket.io-p2p-server. I want users to be automatically paired up against any connected player who doesn't have a partner. I want users to only be connected in pairs.
So far simply following the docs I can only get clients to connect using just socket.io. When I attempt to use socket.io-p2p and socket.io-p2p-server I can sometimes get users to connect and other times I get error messages on the screen like
"Missing error handler on socket.
TypeError: Cannot read property 'emit' of undefined"
Someone opened an issue for this problem on the repo and didn't get a response and never got a response
https://github.com/tomcartwrightuk/socket.io-p2p-server/issues/5
I don't know if socket.io-p2p-server is broken or if I am just missing something. Further more socket.io-p2p-server has not been touched much since march.
So my main questions are:
Is socket.io-p2p-server still alive?
Is there a better implementation I can use for these abstractions?
Would writing my own logic instead of using socket.io-p2p-server be worth it?
client side code
import P2P from 'socket.io-p2p'
import io from 'socket.io-client'
const socket = io()
const p2pSocket = new P2P(socket, null, function () {
console.log("my id is: " + p2pSocket.peerId)
})
p2pSocket.on('peer-msg', function (data) {
console.log(data)
})
server side code
var http = require('http')
var httpServer = http.createServer(requestHandler)
var fs = require('fs')
var io = require('socket.io')(httpServer)
var p2pServerModule = require('socket.io-p2p-server')
var p2p = p2pServerModule.Server
var connectedUsers = p2pServerModule.clients
io.use(p2p)
httpServer.listen(8000, 'localhost');
function serveUpFile(req, res, path) {
fs.readFile(path.toString(), function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200)
res.end(data)
})
}
function requestHandler (req, res) {
if (req.url === '/static/bundle.js') {
serveUpFile(req, res, './static/bundle.js')
} else {
serveUpFile(req, res, './index.html')
}
}
io.on('connection', function (client) {
console.log('client connected to the server')
client.on('peer-msg', function (data) {
console.log('Message from peer %s', data)
})
client.on('disconnect', function () {
console.log('client disconnected from the server')
})
})
socket.io-p2p-server will not work with socket.io 1.x as expected.
Change socket.io-p2p-server/index.js:
This part:
if (typeof room === 'object') {
var connectedClients = socket.adapter.rooms[room.name]
} else {
var connectedClients = clients
}
To this:
if (typeof room === 'object' && ('name' in room) && (room.name in socket.adapter.rooms) ) {
var connectedClients = {}
for (var id in socket.adapter.rooms[room.name].sockets) {
connectedClients[id] = clients[id];
}
} else {
var connectedClients = clients;
}
This solution works for me.

nodejs serialport write issues?

I am using the nodejs serialport module (https://npmjs.org/package/serialport) and I am having issues when I write to the serial port.
If I simply write to the port as shown below, the serial device never gets the command.
var serialport = require("serialport");
var sp = new serialport.SerialPort(serialPortPath);
sp.write("SYST:ADDR?\n");
However, if I use a setTimeout as shown below, then it seems to work?
var serialport = require("serialport");
var sp = new serialport.SerialPort(serialPortPath);
setTimeout(function(){sp.write("SYST:ADDR?\n")},1000);
FYI, the "serialPortPath" is set elsewhere in the code.
I am not sure what is going on... any ideas?
I think I got it figured out from the github (https://github.com/voodootikigod/node-serialport page... basically it looks like I was missing the "open" event as shown below:
serialPort.on("open", function () {
console.log("open");
serialPort.on("data", function(data) {
console.log("data received: " + data);
});
serialPort.write("SYST:ADDR?\n", function(err, results) {
console.log("err: " + err);
console.log("results: " + results);
});
});
Here is another approach which works very well and allows for dynamic addressing of a specific serial device. In my case I am only interested in connecting to the Numato device connected to our integrated system which is why I have the conditional logic in the list callback.
exports.testSerial = function(data) {
serialPort.list(function(err, ports) {
var port = {};
for(var i = 0; i < ports.length; i++) {
try {
if(typeof ports[i].manufacturer != 'undefined' && ports[i].manufacturer.includes("Numato")) {
port = ports[i];
}
} catch(err) {
console.dir(err);
}
}
// the port will be opened via the constructor of this call
var numato = new serial(port.comName, {baudrate : 19200}, function(err) {
if(err) {
return console.dir(err);
}
// by having the write call within the callback you can access it directly w/o using .on()
numato.write('relay ' + data.state + ' ' + data.channel + '\r', function(err) {
if(err) {
console.dir('error writing');
console.dir(err);
}
console.dir('serial message written');
numato.close();
});
});
return true;
});
}
Hope this helps someone in the future! For reference this is with library version 4.0.7.

Resources