connection failed simple-peer after deployment - sockets

I am using simple-peer for video transmission. Its working fine in my local network so I add google's free stun server to connect with people not in my local network. But its throwing error connection failed if I try to connect to anyone outside of my local network and working fine at local network.
React part
const peer = new Peer({
initiator: true,
trickle: false,
stream,
config: {
iceServers: [
{urls: 'stun:stun.l.google.com:19302'},
{ urls: 'stun:global.stun.twilio.com:3478?transport=udp' }
]
}
});
peer.on("signal", signal => {
socketRef.current.emit("sendingSignal", { userIdToSendSignal: userIdToSendSignal, callerId: callerId, signal });
})
})
const peer = new Peer({
initiator: false,
trickle: false,
stream,
config: {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:global.stun.twilio.com:3478?transport=udp' }
]
},
});
//other peer give its signal in signal object and this peer returning its own signal
peer.on("signal", signal => {
socketRef.current.emit("returningSignal", { signal, callerId: callerId });
});
peer.signal(incomingSignal);
})
Nodejs part
const socket = require("socket.io");
const io = socket(server);
const usersInRoom = {}; //all user(socket id) connected to a chatroom
const socketToRoom = {}; //roomId in which a socket id is connected
//verifying token
io.use(async (socket, next) => {
try {
const token = socket.handshake.query.token;
const payload = await jwt.verify(token, process.env.SECRET);
socket.userId = payload;
const user = await User.findOne({ _id: socket.userId }).select('-password');
socket.username = user.username;
socket.name = user.name;
next();
} catch (error) {
console.log(error);
}
});
io.on('connection', socket => {
console.log('Some one joined socketId: ' + socket.id);
socket.on("joinRoom", roomId=> {
console.log('Joined roomId: ' + roomId + " socketId: " + socket.id + ' userId: ' + socket.userId);
if (usersInRoom[roomId]) {
const length = usersInRoom[roomId].length;
usersInRoom[roomId].push(socket.id);
} else {
usersInRoom[roomId] = [socket.id];
}
socketToRoom[socket.id] = roomId;
const usersInThisRoom = usersInRoom[roomId].filter(id => id !== socket.id);
socket.join(roomId); //for message
socket.emit("usersInRoom", usersInThisRoom); //send all socket id connected to this room
});
//client send this signal to sever and sever will send to other user of peerId(callerId is peer id)
socket.on("sendingSignal", payload => {
console.log(payload.callerId);
io.to(payload.userIdToSendSignal).emit('userJoined', { signal: payload.signal, callerId: payload.callerId });
});
//client site receive signal of other peer and it sending its own signal for other member
socket.on("returningSignal", payload => {
io.to(payload.callerId).emit('takingReturnedSignal', { signal: payload.signal, id: socket.id });
});
//from client send message to send all other connected user of same room
socket.on('sendMessage', payload => {
//sending message to all other connected user at same room
io.to(payload.roomId).emit('receiveMessage', { message: payload.message, name:socket.name, username: socket.username });
});
//someone left room
socket.on('disconnect', () => {
const roomId = socketToRoom[socket.id];
let socketsIdConnectedToRoom = usersInRoom[roomId];
if (socketsIdConnectedToRoom) {
socketsIdConnectedToRoom = socketsIdConnectedToRoom.filter(id => id !== socket.id);
usersInRoom[roomId] = socketsIdConnectedToRoom;
}
socket.leave(roomId); //for message group(socket)
socket.broadcast.emit("userLeft", socket.id); //sending socket id to all other connected user of same room without its own
});
});
Error

Related

Bot doesnt want to take id from db

I'm making a command where u can setup a bot status channel. Everything so far worked fine, db even writes down id of guild and channel but when I want to use it in ready.js is says its not defined.
Little help would be handy and grateful
Code:
https://pastebin.com/GnxtxFwG - main command
https://pastebin.com/hhy90czw - schema
https://pastebin.com/jVDGu43T - error
Error file:
const { EmbedBuilder } = require('discord.js');
const { channelId } = require('../../schemas/status');
module.exports = {
name: "ready",
once: "true",
async execute(client) {
console.log(channelId)
console.log('Bot is up and ready to work!')
const uptime = new EmbedBuilder()
.setColor('ffd9c0')
.addFields(
{ name: 'Capy is back and online!', value: 'Bot was probably offline due to a bug or maintenance.'},
{ name: '\u200b', value: 'If Capy isnt working how is he supposed to be contact on of our Developers or contact <#574849327650963469> directly.'},
)
const channel = await client.channels.cache.get(channelId);
channel.send({ embeds: [uptime] });
setInterval(client.pickPresence, 10 * 1000);
},
};
Client on function
const { EmbedBuilder } = require('discord.js');
const { Statuses } = require('../../schemas/status');
const uptime = require('../../commands/tools/status')
module.exports = {
name: "ready",
once: "true",
async execute(client) {
console.log(Statuses.channelId)
console.log('Bot is up and ready to work!')
const uptimeEmbed = new EmbedBuilder()
.setColor('ffd9c0')
.addFields(
{ name: 'Capy is back and online!', value: 'Bot was probably offline due to a bug or maintenance.'},
{ name: '\u200b', value: 'If Capy isnt working how is he supposed to be contact on of our Developers or contact <#574849327650963469> directly.'},
)
const channel = await client.channels.cache.get(Statuses.channelId);
Statuses.findById({ channelId: message.guild.id }, async (err, data) => {
if (data) {
channel.send({ embeds: [uptimeEmbed] });
} else {
new Statuses ({
guildId: interaction.guild.id,
chnanelId: uptime ? uptime : "None"
}).save()
console.log("Status channel wasnt set on this server yet!")
}
});
setInterval(client.pickPresence, 10 * 1000);
},
};
Schema
const { Schema, model } = require('mongoose');
const statusSchema = new Schema({
guildId: String,
channelId: String,
});
module.exports = model("Status", statusSchema, "Statuses");
Main command
const {
SlashCommandBuilder,
ChatInputCommandInteraction,
EmbedBuilder,
} = require("discord.js");
const Statuses = require('../../schemas/status');
module.exports = {
data: new SlashCommandBuilder()
.setName("status")
.setDescription("Select the language of the bot")
.addChannelOption(uptime => {
return uptime
.setName("channel")
.setDescription("Channel you want to send the FAQ embed in")
.setRequired(true)
}),
/**
*
* #param {ChatInputCommandInteraction} interaction
* #param {Client} client
*/
async execute(interaction, client) {
const { options } = interaction;
const uptime = options.getChannel("channel");
const user = interaction.user;
const status = new EmbedBuilder()
.setColor("#bb6464")
.setDescription(`Status message was set to ${uptime}!`)
.setFooter({ text: `Request from ${interaction.user.username}`, iconURL: user.displayAvatarURL()})
.setTimestamp();
const status2 = new EmbedBuilder()
.setColor("#bb6464")
.setDescription(`Status message was changed to ${uptime}!`)
.setFooter({ text: `Request from ${interaction.user.username}`, iconURL: user.displayAvatarURL()})
.setTimestamp();
let statusProfile = await Statuses.findOne({ channelId: interaction.guild.id });
if (!statusProfile) {
statusProfile = await new Statuses({
guildId: interaction.guild.id,
channelId: uptime,
});
await statusProfile.save().catch(console.error);
interaction.reply({ embeds: [status] })
console.log(statusProfile);
} else {
await interaction.reply({ embeds: [status2] });
console.log(statusProfile);
}
}
}

Socket.io, Mongodb returning undefined to frontend

I want to use socekt.io for a new project I am building. I am using socket.io for a login component and will be using socket.io in the future to update pages like a chat app. I am also using mongoose to handle my mongodb connection. I am taking in a username, and returning a password to my front end to be bcryptjs compareSync hashed. The problem I am having is that whatever is returned to the front end is undefined. When I print out what is returned to the front end, it prints out the value I am looking for though. Something is going on between the backend emitting something, and the frontend receiving something but I don't know what is it exactly. Here is my code for the back end:
const express = require('express')
const socket = require('socket.io');
const http = require('http');
const router = require('./router');
const mongoose = require('mongoose');
let Player = require('../models/player.model');
require('dotenv').config();
const PORT = process.env.PORT || 5000;
const app = express();
const server = http.createServer(app);
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, {useNewUrlParser: true, useCreateIndex: true,
useUnifiedTopology: true });
const connection = mongoose.connection;
connection.once('open',() => {
console.log('MongoDB database connection established successfully')
});
const io = socket(server);
io.on('connection', (socket) => {
console.log('We have a new connection');
socket.on('login', ({ username }, callback) => {
console.log(username);
Player.find({"username": username}, function (err, player) {
if(err) {
console.log("there has been an error"), {player: null}
}
socket.emit('id', { password: player[0]['password'].toString(), id : player[0]['_id']})
}) })})
app.use(router);
server.listen(PORT, () => console.log('Server is working'))
Here is my code for the front end:
const ENDPOINT = 'localhost:5000';
async function submitAccount (e) {
e.preventDefault();
socket.emit('login', { username });
socket.on("id", (response) => {
setPassword2(String(response['password']));
id = response['id']; console.log(id);
console.log(password2)
});
try {
if (bcrypt.compareSync(password, password2) == true) {
props.setCookie("id", id);
setAccess(true);
access2 = true;
console.log(access2)
console.log('works')
}
else {
setErrorType('Invalid Password')
setErrorMsg('There is an issue with your password. Please try again')
setOpenModal(true)
console.log(password);
console.log(password2);
}
}
catch {
setErrorType('Invalid Username')
setErrorMsg('This username does not exist. Please try another')
setOpenModal(true)
}
Thanks for the help!
When you do the socket.on, it should include the whole statement you are looking to change with the socket.io output. See below:
async function submitAccount (e) {
e.preventDefault();
socket.emit('login', { username });
socket.on("id", (response) => {
setPassword2(String(response['password']));
id = response['id']; console.log(id);
console.log(password2)
if (password2 != undefined) {
try {
if (bcrypt.compareSync(password, password2) == true) {
props.setCookie("id", id);
setAccess(true);
access2 = true;
console.log(access2)
console.log('works')
}
}

How to get connected clients and client certificate in node-opcua server

I have a node-opcua server setup with 2 clients connected to it with Security Mode set to SignAndEncrypt. Now, I have 2 questions:
Is there a way for the server to find out how many clients are connected to it?
The server application will like to know the identity of a connected client, is there an API to get the client certificate obtained during OpenSecureChannel?
OPCUA Server can expose such information under the RootFolder.Server.ServerDiagnostics node, and the information you need shall be accessible through OPCUA.
This little node-opcua client program will show you how to do.
note:
that certain data such as security diagnostics requires a secure connection and a non-anonymous user
client_extract_server_diagnostic.ts
// this script is typescript and can be run this way
// $ npx ts-node client_extract_server_diagnostic.ts
import {
AttributeIds,
OPCUAClient,
ClientSession,
StatusCodes,
MessageSecurityMode,
SecurityPolicy,
UserIdentityInfoUserName,
UserTokenType
} from "node-opcua";
// the opcua server to connect to
const endpointUrl = "opc.tcp://localhost:48010";
// the credential
const userIdentityToken: UserIdentityInfoUserName = {
password: "secret",
userName: "root",
type: UserTokenType.UserName
};
async function extractServerStatistics(session: ClientSession) {
const nodesToRead = [
{
attributeIds: AttributeIds.Value, nodeId:"Server_ServerDiagnostics_EnabledFlag"
},
{
attributeIds: AttributeIds.Value, nodeId:"Server_ServerDiagnostics_ServerDiagnosticsSummary_CurrentSessionCount" //i=2277
},
{
attributeIds: AttributeIds.Value, nodeId:"Server_ServerDiagnostics_ServerDiagnosticsSummary_CurrentSubscriptionCount" // i=2285
},
{
attributeIds: AttributeIds.Value, nodeId: "Server_ServerDiagnostics_ServerDiagnosticsSummary_CumulatedSessionCount" // i=2278
},
{
attributeIds: AttributeIds.Value, nodeId: "Server_ServerDiagnostics_ServerDiagnosticsSummary_CumulatedSubscriptionCount" // i=2278
},
{
attributeIds: AttributeIds.Value, nodeId: "Server_ServerDiagnostics_SessionsDiagnosticsSummary_SessionSecurityDiagnosticsArray" // i=3708
}
];
const dataValues = await session.read(nodesToRead);
console.log("Diagnostic enabled ? = ", dataValues[0].value.value);
console.log("Current Session Count = ", dataValues[1].value.value);
console.log("Current Subscription Count = ", dataValues[2].value.value);
console.log("Cumulated Session Count = ", dataValues[3].value.value);
console.log("Cumulated Subscription Count = ", dataValues[4].value.value);
// note reading SessionSecurityDiagnotiscArray may requires authenticated session to succeed
console.log("SessionSecurityDiagnotiscArray = ");
if (dataValues[5].statusCode === StatusCodes.Good) {
const sessionSecurityDiagnosticArray = dataValues[5].value.value;
// console.log(dataValues[5].value.value.toString());
for (const sessionSecurityDiagnostic of sessionSecurityDiagnosticArray) {
console.log(" session client certificate ", sessionSecurityDiagnostic.clientCertificate.toString("base64"));
console.log();
}
} else {
console.log(dataValues[5].toString());
}
}
( async () => {
try {
const client = OPCUAClient.create({
endpoint_must_exist: false,
securityMode: MessageSecurityMode.SignAndEncrypt,
securityPolicy: SecurityPolicy.Basic256Sha256,
});
client.on("backoff",() => console.log("still trying to connec to ", endpointUrl));
await client.connect(endpointUrl);
const session = await client.createSession(userIdentityToken);
await extractServerStatistics(session);
await session.close();
await client.disconnect();
console.log("done");
} catch(err) {
console.log("Err" , err.message);
process.exit(1);
}
})();

NodeMailer queuing outgoing email, but email never sends

I'm trying to send an email from my own domain without using an external SMTP server. I'm using NodeMailer's SMTP connection:
let options = {
secure: true,
port: consts.portOut,//465
host: consts.host, //mydomain.com
transactionLog: true,
debug: true,
requireTLS: true,
authMethod: 'PLAIN',
};
let connection = new SMTPConnection(options);
connection.connect(function() {
let auth = {
user: 'abc',
pass: 'def'
};
connection.login(auth, function(err) {
if (err) {
console.log("Authentication failed!", err);
}
console.log("Authentication to SMTP server successful.");
let envelope = {
from: 'fee#mydomain.com',
to: 'myemail#gmail.com'
};
let message = 'message hello world';
connection.send(envelope, message, function(err, info) {
if (err) {
console.log("err:::", err);
} else {
console.log('info?', info);
//connection.quit();
}
});
connection.quit();
});
});
connection.on("error", function(err) {
console.log(err);
});
My server code using NodeMailer's SMTP Server:
const options = {
secure: true,
size: 25000000, //25MB
authMethods: ['PLAIN'],
key: hskey,
cert: hscert,
ca: [hschain],
onAuth(auth, session, callback) {
if(auth.username !== 'abc' || auth.password !== 'def') {
return callback(new Error('Invalid username or password'));
}
callback(null, {user: 123}); // where 123 is the user id or similar property
},
onConnect(session, callback) {
console.log("the address is:", session.remoteAddress)
if (session.remoteAddress === consts.ip) {
return callback(); // Accept the address
} else {
return callback(new Error('Only connections from %s allowed', consts.ip));
}
},
onData(stream, session, callback) {
simpleParser(stream, (err, parsed) => {
if(err) {
console.error(err);
} else {
console.log(parsed);
}
});
stream.on('end', function () {
let err;
if(stream.sizeExceeded){
err = new Error('Message exceeds fixed maximum message size');
err.responseCode = 552;
return callback(err);
}
callback(null, 'Message queued as abcdef');
});
}
};
const emailServer = new SMTPServer(options);
emailServer.listen(consts.portOut, function () {
processSMTPConnection(consts, hskey);
});
emailServer.on("error", function (err) {
console.error("Error %s", err.message);
});
So after my client connects to my local SMTP server, the last message I get is 'Message queued as abcdef' and nothing ever sends (nothing ever arrives in my gmail inbox or any other email testing services)...
No incorrect ports are blocked, so I must be missing something(?).
Is this not how to correctly use NodeMailer?
Should I be able to send emails from my local domain using NodeMailer?
Documentation here has a note that states:
This module does not make any email deliveries by itself. smtp-server
allows you to listen on ports 25/24/465/587 etc. using SMTP or LMTP
protocol and that’s it. Your own application is responsible of
accepting and delivering the message to destination.
(emphasis mine)
Your server seems to accept the email (that's why it's showing that the message has been queued) but it doesn't delivers to destination.
To expand a little bit on how to send the message once it arrives to your SMTP server. If the TO address is local, just put the message in their mailbox. But if you want to "remail" the message, you need to contact the TO mail exchange with the message.
Something like:
const toExchange = getMX(parsed.to);
const outMessage = createMessageFromParsed(parsed);
const transporter = createTransport({
port: 25,
host: toExchange,
name: os.hostname(),
});
transporter.sendMail(outMessage);

node.js socket exception read ETIMEDOUT - how do I catch it properly? what about write timeouts?

I have a proxy server that manages a bunch of clients and also talks with another http server. Messages get posted back and forth and directed to clients. Clients can and do timeout, and the server has a heartbeat function (that repeats every n seconds) that sends a heartbeat to all clients that are in a map of clientId to socket connection.
I get a 'read ETIMEDOUT' exception when the heartbeat tries to talk to a client that is no longer connected but who's socket is still active. I tried temporarily setting the timeout of the socket connection to 2000ms with the theory that my socket event handler for timeout would catch this (the event handler is in the tcp server portion), but this didn't happen. It takes several heartbeats to die.
Part of the problem is definitely my lack of understanding of how to structure node.js code, so if you have any suggestions, I'd very much appreciate them.
Another question is whether it is possible to handle read and write timeouts separately, or at least break them out. What I'd really like to do is have my heartbeat function be part of the tcp server and only send a heartbeat if it hasn't heard from the client in say n seconds, and only send this heartbeat once. If we get a timeout, then we kill the socket, otherwise we wait again.
Thanks!
>>$ node --harmony-weakmaps server.js
Heartbeat: Sat Feb 18 2012 08:34:40 GMT+0000 (UTC)
{
sending keep_alive to id:00:00:00:00:00:10 socket:[object Object]
}
socket:received data: {"id":"00:00:00:00:00:10","m":"keep_alive","success":"true"}
Heartbeat: Sat Feb 18 2012 08:35:40 GMT+0000 (UTC)
{
sending keep_alive to id:00:00:00:00:00:10 socket:[object Object]
}
socket:received data: {"id":"00:00:00:00:00:10","m":"keep_alive","success":"true"}
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: read ETIMEDOUT
at errnoException (net.js:642:11)
at TCP.onread (net.js:375:20)
Heartbeat function that triggers the timeout:
console.log("Starting heartbeat");
var beat_period = 60;
setInterval(function() {
if(Object.keys(id2socket).length != 0){
console.log("Heartbeat: " + new Date());
//for (var key in id2socket) {
// console.log("\t"+key+"->"+id2socket[key]);
//}
console.log("{");
for(var id in id2socket) {
var socket = id2socket[id];
// don't want sockets to time out
socket.setTimeout(2000); // for heartbeat, set the timeout
try {
console.log("\tsending keep_alive to id:"+id+" socket:"+id2socket[id]);
socket.write('{"m":"keep_alive"}\r\n');
} catch(Error) {
console.log("Heartbeat:Cannot find id:"+id);
removeSocketFromMap(id,socket);
// TODO: send message to API
}
socket.setTimeout(0); // no timeout
}
console.log("}");
}
}, beat_period * 1000);
server.js:
// Launch Instructions
// node --harmony-weakmaps server.js
var net = require('net'); // tcp-server
var http = require("http"); // http-server
var querystring = require('querystring');
// Map of sockets to clients
var id2socket = new Object;
var socket2id = new WeakMap; // allows us to use object as key to hash
// Test for client:
// {"id":"123","m":"add"} // establishes connection and puts client into id2socket map
// {"id":"123","m":"test"} // sends a message through to API
// HTTP:POST outbound function
// http://www.theroamingcoder.com/node/111
function postOut(dataToPost){
try{
console.log("postOut msg:"+JSON.stringify(dataToPost));
} catch (Error) {
console.log("postOut error:"+Error);
}
var post_domain = '127.0.0.1';
var post_port = 80;
var post_path = '/cgi-bin/index3.py';
var post_data = querystring.stringify({
'act' : 'testjson',
'json' : JSON.stringify(dataToPost)
});
console.log("post_data:"+post_data);
var post_options = {
host: post_domain,
port: post_port,
path: post_path,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
var post_req = http.request(post_options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('Response:data: ' + chunk);
});
});
// Handle various issues
post_req.on('error', function(error) {
console.log('ERROR' + error.message);
// If you need to go on even if there is an error add below line
//getSomething(i + 1);
});
post_req.on("response", function (response) {
console.log("Response:response:"+response);
});
// write parameters to post body
post_req.write(post_data);
post_req.end();
}
function removeSocketFromMap(id,socket){
console.log("removeSocketFromMap socket:"+socket+" id:"+id);
delete id2socket[id];
socket2id.delete(socket);
//TODO: print map???
console.log("socketmap {");
for (var key in id2socket) {
console.log("\t"+key+"->"+id2socket[key]);
}
console.log("}");
}
// Setup a tcp server
var server_plug = net.createServer(
function(socket) {
// Event handlers
socket.addListener("connect", function(conn) {
console.log("socket:connection from: " + socket.remoteAddress + ":" + socket.remotePort + " id:"+socket.id );
});
socket.addListener("data", function(data) {
console.log("socket:received data: " + data);
var request = null;
try {
request = JSON.parse(data);
} catch (SyntaxError) {
console.log('Invalid JSON:' + data);
socket.write('{"success":"false","response":"invalid JSON"}\r\n');
}
if(request!=null){
response = request; // set up the response we send back to the client
if(request.m=="keep_alive"){ // HACK for keep alive
// Do nothing
} else if(request.m !== undefined && request['id'] !== undefined){ // hack on 'id', id is js obj property
if(request.m == 'connect_device' || request.m == 'add'){
console.log("associating uid " + request['id'] + " with socket " + socket);
id2socket[request['id']] = socket;
socket2id.set(socket, request['id']);
}
postOut(request);
socket.write(JSON.stringify(response)+"\r\n");
} else if(request['id'] !== undefined){
postOut(request);
socket.write(JSON.stringify(response)+"\r\n");
} else {
response['content'] = "JSON doesn't contain m or id params";
socket.write(JSON.stringify(response)+"\r\n");
}
} else {
console.log("null request");
}
});
socket.on('end', function() {
id = socket2id.get(socket);
console.log("socket:disconnect by id " + id);
removeSocketFromMap(id,socket);
socket.destroy();
});
socket.on('timeout', function() {
id = socket2id.get(socket);
console.log('socket:timeout by id ' + id);
removeSocketFromMap(id,socket);
socket.destroy();
});
// handle uncaught exceptions
socket.on('uncaughtException', function(err) {
id = socket2id.get(socket);
console.log('socket:uncaughtException by id ' + id);
removeSocketFromMap(id,socket);
socket.destroy();
});
}
);
server_plug.on('error', function (error) {
console.log('server_plug:Error: ' + error);
});
// Setup http server
var server_http = http.createServer(
// Function to handle http:post requests, need two parts to it
// http://jnjnjn.com/113/node-js-for-noobs-grabbing-post-content/
function onRequest(request, response) {
request.setEncoding("utf8");
request.content = '';
request.on('error', function(err){
console.log("server_http:error: "+err);
})
request.addListener("data", function(chunk) {
request.content += chunk;
});
request.addListener("end", function() {
console.log("server_http:request_received");
try {
var json = querystring.parse(request.content);
console.log("server_http:received_post {");
for(var foo in json){
console.log("\t"+foo+"->"+json[foo]);
}
console.log("}");
// Send json message content to socket
if(json['json']!=null && json['id']!=null){
id = json['id'];
try {
var socket = id2socket[id];
socket.write(json['json']+"\r\n");
} catch (Error) {
console.log("Cannot find socket with id "+id);
} finally {
// respond to the incoming http request
response.end();
// TODO: This should really be in socket.read!
}
}
} catch(Error) {
console.log("JSON parse error: "+Error)
}
});
request.on('end', function () {
console.log("http_request:end");
});
request.on('close', function () {
console.log("http_request:close");
});
}
);
server_http.on('error', function (error) {
console.log('server_http:Error: ' + error);
});
// Heartbeat function
console.log("Starting heartbeat");
var beat_period = 60;
setInterval(function() {
if(Object.keys(id2socket).length != 0){
console.log("Heartbeat: " + new Date());
//for (var key in id2socket) {
// console.log("\t"+key+"->"+id2socket[key]);
//}
console.log("{");
for(var id in id2socket) {
var socket = id2socket[id];
// don't want sockets to time out
socket.setTimeout(2000); // for heartbeat, set the timeout
try {
console.log("\tsending keep_alive to id:"+id+" socket:"+id2socket[id]);
socket.write('{"m":"keep_alive"}\r\n');
} catch(Error) {
console.log("Heartbeat:Cannot find id:"+id);
removeSocketFromMap(id,socket);
// TODO: send message to API
}
socket.setTimeout(0); // no timeout
}
console.log("}");
}
}, beat_period * 1000);
// Fire up the servers
//var HOST = '127.0.0.1'; // just local incoming connections
var HOST = '0.0.0.0'; // allows access to all external IPs
var PORT = 5280;
var PORT2 = 9001;
// accept tcp-ip connections
server_plug.listen(PORT, HOST);
console.log("TCP server listening on "+HOST+":"+PORT);
// accept posts
server_http.listen(PORT2);
console.log("HTTP server listening on "+HOST+":"+PORT2);
EDIT:
Should I be using .on(event,callback) vs .onlistener(event,callback)?
UPDATE:
That didn't work, I changed the stuff in tcp_server to all add_listener in the heartbeat as .on. Still didn't catch the errors and blew up and said I added too many listeners.
First, its a bit hard to say if your structure is right without some more understanding of the context of your code...
Try adding
socket.on('error', function() {
id = socket2id.get(socket);
console.log('socket:timeout by id ' + id);
removeSocketFromMap(id,socket);
socket.destroy();
}
to the anonymous function in net.CreateServer. ETIMEDOUT is a system call error, and node.js is just reporting it. It may not be caused by just a typical 'timeout'. You say its being caused by the Hearbeat write, but it looks like TCP.read is the origination. It may be a half-closed socket.
For the ETIMEDOUT exception issue, did you try listening for an uncaughtException on the process itself?
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
See the documentation here : http://nodejs.org/docs/latest/api/process.html#event_uncaughtException_