When my node application restarted from command line or restarted by forever.js (if changes detected), then socket.io 'disconnect' event not fired.
My code is as follows :
io.sockets.on('connection', function(socket) {
var session = socket.handshake.session;
socket.join('room');
socket.on('disconnect', function() {
var clients = io.sockets.clients('room');
if (!clients || (clients && clients.length === 0)) {
//remove from online list
}
});
socket.on('error', function(err) {
if(err === 'handshake error') { console.log('handshake error', err); }
else { console.log('io error', err); }
});
socket.on('message', function(data) {
//console.log('messege received on server is "' + data + '"');
});
});
Here my socket.on('disconnect') not firing when node.js application is started.
Any guess, why it is not happening/firing?
Related
I'm attempting to connect to an Active Directory domain controller to make some basic LDAP queries using JavaScript. I'm using the LDAPJS library and the built-in node tls module. I'm getting an error when attempting to run client.bind
The TLS connection seems to be working fine (it's coming back as authorized===true, though on the secureConnect event, I'm getting undefined.
The related code and output is below:
var tlsOptions = {
host: "my.domain.controller.net",
port: portNumber,
ca: fs.readFileSync("C:\\myCA.pem"),
};
var server = tls.connect(tlsOptions, function () {
console.log(
"Server connected",
server.authorized ? "and authorized" : "but UNAUTHORIZED"
);
if (server.authorized) {
var client = ldap.createClient({
url: "ldaps://domiancontroler",
tlsOptions: tlsOptions,
});
console.log("Client created!")
client.bind(userDN, userPW, function (err) {
console.log("Client binding error:", err)
process.exit()
});
}
});
server.setEncoding("utf8");
server.on("data", function (data) {
console.log("server data callback: ", data);
});
server.on("secureConnect", function (data) {
console.log("server secureConnect callback: ", data);
});
server.on("error", function (error) {
console.log("server error callback", error);
});
Produces the following output:
> Server connected and authorized
> Client created!
> server secureConnect callback: undefined
> Client binding error: null
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');
});
when users online and don't close our clients such as browser tab or android application, i can send message to each specific user by
socket.broadcast.to(socketId)
.emit('new message', {
username: data.fromUsername,
money : 'Hurrraaa'
});
when users close clients as mobile application this event don't trigger but i can send any message to broadcast as:
socket.broadcast.emit('new message', "hooooorrrrraaaaa");
my users don't use client application any time, but i need to send message to some specific user and notify user until opening application and see message, users should be on'time in my application to get every message which i want to send from server like with Chat messengers which don't need users currently are using application such as WhatsApp, how can i resolve this problem?
then problem is send message to some specific users when they are istalled application and logged ti sever, but not using now and application waiting to receive message such as broadcast or special message to himself
this code is my simplified server:
var socket = require('socket.io'),
express = require('express'),
app = express(),
server = require('http').createServer(app),
io = socket.listen(server),
port = process.env.PORT || 3000,
mysql = require('mysql'),
uuid = require('node-uuid'),
datetime = require('node-datetime'),
moment = require('moment'),
bcrypt = require('bcrypt'),
async = require('async'),
request = require('request'),
redis = require("redis"),
redisClient = redis.createClient(),
forever = require('forever'),
log = require('log4node');
var io_redis = require('socket.io-redis');
io.adapter(io_redis({host: 'localhost', port: 6379}));
require('sticky-socket-cluster/replace-console')();
var options = {
workers : require('os').cpus().length,
first_port : 8000,
proxy_port : 3000,
session_hash: function (req, res) {
return req.connection.remoteAddress;
},
no_sockets: false
};
require('sticky-socket-cluster')(options, start);
function start(port) {
io.sockets.on('connection', function (socket) {
socket.on('new message', function (data) {
socket.broadcast.emit('new message', "hooooorrrrraaaaa");
});
socket.on('login', function (data) {
log.info(JSON.stringify(data))
login(data.username, data.password, function (success, value) {
if (success) {
redisClient.exists(data.username, function (err, doesExist) {
if (err) return;
if (!doesExist) {
redisClient.set(data.username, socket.id, function (err, res) {
redisClient.set(data.username, socket.id);
});
}
else {
redisClient.del(data.username);
redisClient.set(data.username, socket.id, function (err, res) {
redisClient.set(data.username, socket.id);
});
}
});
socket.emit('login', {
result : true,
id : value.id,
registeredMobileNumber: value.registeredMobileNumber
});
} else {
socket.emit('login', {result: false});
}
});
});
socket.on('userConnected', function (username) {
redisClient.exists(username, function (err, doesExist) {
if (err) return;
if (!doesExist) {
redisClient.set(username, socket.id, function (err, res) {
redisClient.set(username, socket.id);
});
}
else {
redisClient.del(username);
redisClient.set(username, socket.id, function (err, res) {
redisClient.set(username, socket.id);
});
}
});
});
socket.on('disconnectUser', function (data) {
redisClient.exists(data.username, function (err, doesExist) {
if (err) return;
if (doesExist) {
redisClient.del(data.username);
}
});
});
server.listen(port, function () {
console.log('Express and socket.io listening on port ' + port);
});
}
You can use socket.on('disconnect', function() {});
When a User disconnects , save the users user_id.
Subsequent message on the user_id would be saved in the server.
When the client reconnects again get the time of the latest message and then push the message after that time (saved in the server) to the client.
How to send the response properly. I like to move to another page after FTP and Telnet sessions.
Even tried using res.redirect function too. While using res.redirect, i commented window.location= "SaveRedirect"; line, in javascript of html page. Even then, I get the same error.
Here presenting the code snippet,
the javascript code in html
IPData ={
"DeviceIpAddr": "192.168.1.2"
};
function processSave() {
$.post("PostSave", IPData, function(data) {
window.location= "SaveRedirect";
});
return true;
}
node js code snippet
app.get('/SaveRedirect', function (req, res) {
res.sendFile( __dirname + "/" + "Page2.htm" );
})
var bodyParser = require('body-parser');
var testJsonEncoder = bodyParser.json();
urlEncoded = bodyParser.urlencoded({ extended: true });
app.post('/PostSave', testJsonEncoder,urlEncoded, function(request, response){
var LoginData = JSON.stringify(request.body, null, 4);
console.log(LoginData);
FormDataObj = JSON.parse(LoginData);
gDeviceIpAddress = FormDataObj.DeviceIpAddr;
console.log("IP Address" + gDeviceIpAddress);
console.log("FTP to linux box...");
ftpFile(gDeviceIpAddress, "PUT", "temp_data.json", response);
console.log("FTP temp_data file to linux box... Done!");
TelnetLinux(gDeviceIpAddress);
console.log("Telnet to linux box... Done!");
response.send("just to send response");
//response.json(LoginData);
});
function ftpFile(ftpIPAddr, operation, filename, resp) {
console.log("ftpIPAddr = " + ftpIPAddr);
ftpConfig.host = ftpIPAddr;
// Handle error
ftpClient.on("error", function (err) {
console.log(" - ERROR HANDLE - \n");
console.log(err);
resp.send("FAIL: " + err.message);
ftpClient.end();
});
// Handle error
ftpClient.on("ready", function () {
console.log("Connected....\n");
if(operation == "GET") {
console.log("filename : " + filename);
ftpClient.get(filename, function(err, stream) {
if (err)
{
resp.send("FAIL: " + err.message + " - " + filename);
ftpClient.end();
//throw err;
}
else {
stream.once('close', function() { ftpClient.end(); });
stream.pipe(fs.createWriteStream('test_data.json'));
resp.send("SUCCESS: file received");
ftpClient.end();
}
});
}
if(operation == "PUT") {
ftpClient.put(filename, filename, function(err) {
if (err) {
resp.send("FAIL: " + err.message + " - " + filename);
ftpclient.end();
throw err;
}
else {
resp.send("SUCCESS: file sent");
ftpClient.end();
}
});
}
});
ftpClient.connect(ftpConfig);
}
function TelnetLinux(deviceIPAddr) {
var telnetParams = {
host: deviceIPAddr,
port: 23,
username: "webtest",
password: "test123",
shellPrompt: '$',
timeout: 1500,
// removeEcho: 4
};
cmd = "ls";
console.log("Telnet Address : " + deviceIPAddr);
telnetClient.on('ready', function(prompt) {
telnetClient.exec(cmd, function(err, response) {
//console.log(response);
console.log("Cmd executed !");
});
});
telnetClient.on('timeout', function() {
console.log('telnet socket timeout!')
telnetClient.end();
});
telnetClient.on('close', function() {
console.log('telnet connection closed');
});
telnetClient.connect(telnetParams);
}
Error :
c:\WebTest>node webapp.js
Example app listening at http://:::8081
IP Address192.168.1.2
FTP to linux box...
ftpIPAddr = 192.168.1.2
FTP temp_data file to linux box... Done!
Telnet Address : 192.168.1.2
Telnet to linux box... Done!
Cmd executed !
telnet socket timeout!
telnet connection closed
Connected....
_http_outgoing.js:346
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (c:\WebTest\node_modules\express\lib\response.js:719:10)
at ServerResponse.send (c:\WebTest\node_modules\express\lib\response.js:164:12)
at c:\WebTest\webapp.js:222:11
at Object.cb (c:\WebTest\node_modules\ftp\lib\connection.js:1017:13)
at Parser.<anonymous> (c:\WebTest\node_modules\ftp\lib\connection.js:117:20)
at emitTwo (events.js:100:13)
at Parser.emit (events.js:185:7)
at Parser._write (c:\WebTest\node_modules\ftp\lib\parser.js:59:10)
at doWrite (_stream_writable.js:301:12)
at writeOrBuffer (_stream_writable.js:287:5)
at Parser.Writable.write (_stream_writable.js:215:11)
at Socket.ondata (c:\WebTest\node_modules\ftp\lib\connection.js:273:20)
at emitOne (events.js:90:13)
at Socket.emit (events.js:182:7)
at readableAddChunk (_stream_readable.js:153:18)
This happens when you try to do res.send (or response.send) multiple times in the same call. I believe it has to do with this bit of code:
app.post('/PostSave', testJsonEncoder, urlEncoded, function(request, response) {
var LoginData = JSON.stringify(request.body, null, 4);
console.log(LoginData);
FormDataObj = JSON.parse(LoginData);
gDeviceIpAddress = FormDataObj.DeviceIpAddr;
console.log("IP Address" + gDeviceIpAddress);
console.log("FTP to linux box...");
ftpFile(gDeviceIpAddress, "PUT", "temp_data.json", response);
console.log("FTP temp_data file to linux box... Done!");
TelnetLinux(gDeviceIpAddress);
console.log("Telnet to linux box... Done!");
response.send("just to send response");
//response.json(LoginData);
});
You're doing a response.send at the end of this function, and again in ftpFile()
Since you are sending response multiple times in app.post("/Postsave" and function ftpFile for the same request, you get this error.
To resolve this, I would suggest you to send the result(or error) from the ftpfile back to the app.post(i.e., through callback) and then based on the result or error send the response from the app.post function.
I want to write a simple chat for practical experience.
All right, but I can't get a socket.nickname for notice a join/leave from the room. (when I tried pass its, he always sad a 'undefined').
Now all right, tried to create list of rooms
UPDATE CODE:
client.js:
$('#roomForm').submit(function() {
socket.emit('createRoom', $('#roomName').val());
$('#roomForm').hide();
$('#chatForm').show();
return false;
});
socket.on('message', function(data) {
newMessage(data);
});
socket.on('showRooms', function(rooms) {
console.log(rooms);
for(var i = 0; i < rooms.length; i++) {
$('#rooms').append($('<li>')
.append($('<form id="freeRoom">')
.append($('<span id="room">').text(rooms[i] + ' ///'))
.append($('<button>').text('connect'))));
};
});
$('#freeRoom').submit(function() {
socket.emit('connectToRoom', $('#room').text());
return false;
});
server.js:
io.on('connection', function(socket) {
socket.on('sendNickname', function(username) {
socket.username = username;
users.push(socket.username);
socket.emit('showRooms', rooms);
});
socket.on('disconnect', function() {
socket.broadcast.to(socket.room).emit('notice', socket.username + ' has left the room');
users.splice(users.indexOf(socket.username), 1);
socket.emit('showRooms', rooms);
});
socket.on('message', function(data) {
socket.broadcast.to(socket.room).emit('message', data);
});
socket.on('createRoom', function(room) {
socket.leave(socket.room);
socket.room = room;
rooms.push(socket.room);
socket.join(socket.room);
socket.emit('showRooms', rooms);
console.log('Rooms: ' + rooms);
socket.broadcast.to(socket.room).emit('notice', socket.username + ' has joined to room');
});
socket.on('connectToRoom', function(room) {
console.log('Will connect to that room: ' + room);
socket.join(room);
});
});
**UPD 2: **
Tried to connect free created room:
$('#freeRoom').submit(function() {
socket.emit('connectToRoom', $('#room').text());
return false;
});
P.S. And... Sorry for my english >.<
The event name that you emit, that is 'connect' is reserved in Socket.io along with 'message' and 'disconnect':
http://socket.io/docs/#sending-and-receiving-events
Socket.IO allows you to emit and receive custom events. Besides
connect, message and disconnect, you can emit custom events:
...
Change it to something else, e.g:
Server.js:
io.on('connection', function(socket) {
socket.on('send-nickname', function(nickname) {
socket.nickname = nickname;
users.push(socket.nickname);
console.log(users);
});
...
Client.js
socket.emit('send-nickname', nickname);