Can not read property '/' of undefined - javascript

I started studying node.js. I ask you questions while studying. when I run my code(server) and connect to localhost, It doesn't work properly.
This is error:
This is my code:
index.js
var server = require('./server');
var router = require('./router');
var requestHandlers = require('./requestHandlers');
var handle = {};
handle['/'] = requestHandlers.view;
handle['/view'] = requestHandlers.view;
handle['/create'] = requestHandlers.create;
server.start(router.route, requestHandlers.handle);
server.js
var http = require('http');
var url = require('url');
function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log('\nrequest for ' + pathname + ' received.');
response.writeHead(200, {'Content-Type' : 'text/plain'});
// route(handle, pathname); // injected function call
var content = route(handle, pathname);
response.write(content);
response.end();
}
http.createServer(onRequest).listen(8000);
console.log('server has started.');
}
exports.start = start;
router.js
function route(handle, pathname) {
console.log('about to route a request for ' + pathname);
if (typeof handle[pathname] === 'function') {
return handle[pathname]();
} else {
console.log('no request handler found for ' + pathname);
return "404 Not found";
}
}
exports.route = route;
requestHandlers.js
function view(response) {
console.log('request handler called --> view');
return "Hello View";
}
function create(response) {
console.log('request handler called --> create');
return "Hello Create";
}
exports.view = view;
exports.create = create;

In index.js, you're passing requestHandlers.handle, which doesn't exist, rather than the handle object that you've created.
var server = require('./server');
var router = require('./router');
var requestHandlers = require('./requestHandlers');
var handle = {};
handle['/'] = requestHandlers.view;
handle['/view'] = requestHandlers.view;
handle['/create'] = requestHandlers.create;
// server.start(router.route, requestHandlers.handle);
server.start(router.route, handle);

Related

Node.js shortened url

I have just started learning to code about 5 days ago and what I'm struggling to achieve, is to have an rssfeed-to-twitter script that posts a shortened url instead of a full website/article feed url. I found a node.js module called TinyURL that could do that but i struggle to get it to work. Here's the full script:
var simpleTwitter = require('simple-twitter');
var fs = require('fs');
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type' : 'text/plain'});
res.end('RSS Twitter Bot\n');
}).listen(5693);
var timeInterval = 300000; // run every 30m
var timerVar = setInterval (function () {runBot()}, timeInterval);
function runBot(){
var lastCompleted = Date.parse(new Date(0));
console.log(lastCompleted);
try {
var lastcompletedData = fs.readFileSync('./lastCompleted.json', 'utf8');
var timeData = JSON.parse(lastcompletedData);
var lastCompletedFromFile = Date.parse(new Date(timeData.lastCompleted));
if ( isNaN(lastCompletedFromFile) == false ) {
lastCompleted = lastCompletedFromFile;
}
} catch (e) {
console.log(e);
}
fs.readFile('./config.json', 'utf8', function (err, data) {
if (err) console.log(err); // we'll not consider error handling for now
var configData = JSON.parse(data);
console.log(configData);
var twitter = new simpleTwitter( configData.consumerKey //consumer key from twitter api
, configData.consumerSecret //consumer secret key from twitter api
, configData.accessToken //access token from twitter api
, configData.accessTokenSecret //access token secret from twitter api
, 3600);
var dateNow = Date.parse(new Date());
var FeedParser = require('feedparser');
var request = require('request');
var req = request(configData.feedUrl);
var feedparser = new FeedParser();
req.on('error', function (error) {
console.log(error);
});
req.on('response', function (res){
var stream = this;
if (res.statusCode != 200 ) return this.emit('error', new Error('Bad status code'));
stream.pipe(feedparser);
});
feedparser.on('error', function(error) {
console.log(error);
});
feedparser.on('readable', function() {
var stream = this;
var meta = this.meta;
var item;
while (item = stream.read()) {
var itemDate = Date.parse(item.date);
//check to not publish older articles
if (itemDate > lastCompleted){
var titleLength = item.title.length;
var itemTitle = item.title;
var itemLink = item.link;
if (titleLength > 100) {
itemTitle = itemTitle.substring(0, 100);
}
twitter.post('statuses/update'
, {'status' : itemTitle + ' ' + itemLink + " " + configData.tags}
, function (error, data) {
console.dir(data);
});
console.log(itemTitle + ' ' + item.link + configData.tags);
}
}
//TO KNOW WHEN FROM TO START POSTING
var dateCompleted = new Date();
console.log('loop completed at ' + dateCompleted);
var outputData = {
lastCompleted : dateCompleted
}
var outputFilename = './lastCompleted.json';
fs.writeFile(outputFilename, JSON.stringify(outputData, null, 4), function(err) {
if(err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
});
});
}
And this is the TinyURL node.js module
var TinyURL = require('tinyurl');
TinyURL.shorten('http://google.com', function(res) {
console.log(res); //Returns a tinyurl
});
Changing the 'http://google.com' string to itemLink var works just fine and prints it in the terminal as expected.
TinyURL.shorten(itemLink, function(res) {
console.log(res); //Returns a tinyurl
});
What i'm trying to achieve is:
twitter.post('statuses/update', {'status' : itemTitle + ' ' + tinyurlLink + " " + configData.tags}
How can i get the response turned into a e.g var tinyurlLink to replace the itemLink var? Any help would be much appreciated!
As suggested by #zerkms sending a tweet from inside the TinyURL.shorten worked!

How to access/save the session data on the authorization event in Socket.io/express-sessions?

I setup a websocket using Socket.io and express 4 framework on node.js server.
I am trying to implement authorization step for my users when using my websocket.
When a user connects, a token is passed as a query value to the server. At the server level, I query a database for a session that match the passed token. If a session is found, I do few other check to ensure that the token is not hijacked.
Problem
The session data seems to be cleared on every page reload. Or the server is failing to link the sessionId to the user who created it so everytime it generates a new session.
I am puzzled on how to access the session variables "if they are set."
My Code's Problem
When a user reload his/her page/client, the session data will become undefined on the new request. The session is good until the page is refreshed which is my problem. I need to be able to keep the session active even after the user refresh their page.
Questions
How can ensure that the session data are not cleared on every page refresh?
Here is my authorization code
io.set('authorization', function (handshakeData, accept) {
var session = handshakeData.session || {};
//This is always undefined!
console.log('Session Data:' + session.icwsSessionId);
//var cookies = handshakeData.headers.cookie;
var token = handshakeData._query.tokenId || '';
//console.log('Token: ' + token);
if(!token){
console.log('Log: token was not found');
return accept('Token was found.', false);
}
//allow any user that is authorized
if(session && session.autherized && token == session.token){
console.log('Log: you are good to go');
return accept('You are good to go', true);
}
//if the client changed their token "client logged out"
//terminate the open session before opening a new one
if (session.autherized && token != session.token){
var icwsConnection = new icwsConn(icwsRequest);
icwsRequest.setConnection(session.icwsServer, session.icwsPort);
icwsRequest.setIcwsHeaders(session.icwsSessionId, session.icwsToken);
icwsConnection.logout();
session.autherized = false;
session.token = null;
session.icwsServer = null;
session.icwsPort = null;
session.icwsSessionId = null;
session.icwsToken = null;
icwsConnection = null;
}
Here is my entire code if needed
var env = require('./modules/config'),
app = require('express')(),
https = require('https'),
fs = require('fs'),
session = require('express-session'),
redisStore = require("connect-redis")(session),
sharedsession = require("express-socket.io-session"),
base64url = require('base64url');
const server = https.createServer(
{
key: fs.readFileSync('certs/key.pem'),
cert: fs.readFileSync('certs/cert.pem')
}, function (req, res){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
}
).listen(env.socket.port, env.socket.host, function () {
console.log('\033[2J');
console.log('Websocket is running at https://%s:%s', server.address().address, server.address().port);
});
var io = require('socket.io')(server);
const sessionMiddleware = session({
store: new redisStore({
host: env.redis.host,
port: env.redis.port
}),
secret: env.session.secret,
name: env.session.name,
rolling: false,
resave: true,
saveUninitialized: true
});
app.use(sessionMiddleware);
// Use shared session middleware for socket.io
// setting autoSave:true
io.use(sharedsession(sessionMiddleware, {
autoSave: true
}));
var icwsReq = require('./modules/icws/request.js'),
icwsConn = require('./modules/icws/connection.js'),
icwsInter = require('./modules/icws/interactions.js'),
sessionValidator = require('./modules/validator.js');
var clients = {};
var icwsRequest = new icwsReq();
var sessionChecker = new sessionValidator();
app.get('/', function (req, res) {
res.send('welcome');
});
io.set('authorization', function (handshakeData, accept) {
var session = handshakeData.session || {};
//This is always undefined!
console.log('Session Data:' + session.icwsSessionId);
//var cookies = handshakeData.headers.cookie;
var token = handshakeData._query.tokenId || '';
//console.log('Token: ' + token);
if(!token){
console.log('Log: token was not found');
return accept('Token was found.', false);
}
//allow any user that is authorized
if(session && session.autherized && token == session.token){
console.log('Log: you are good to go');
return accept('You are good to go', true);
}
/*
if (!originIsAllowed(origin)) {
// Make sure we only accept requests from an allowed origin
socket.destroy();
console.log((new Date()) + ' Connection from origin ' + origin + ' rejected.');
return false;
}
*/
//if the client changed their token "client logged out"
//terminate the open session before opening a new one
if (session.autherized && token != session.token){
var icwsConnection = new icwsConn(icwsRequest);
icwsRequest.setConnection(session.icwsServer, session.icwsPort);
icwsRequest.setIcwsHeaders(session.icwsSessionId, session.icwsToken);
icwsConnection.logout();
session.autherized = false;
session.token = null;
session.icwsServer = null;
session.icwsPort = null;
session.icwsSessionId = null;
session.icwsToken = null;
icwsConnection = null;
}
var myIP = '10.0.4.195';
var decodedToken = base64url.decode(token);
sessionChecker.validateData(decodedToken, myIP, env.session.duration, function(isValid, icws){
if(isValid){
session.authorized = true;
session.icwsServer = icws.host;
session.icwsPort = icws.port;
session.token = token;
session.icwsSessionId = null;
session.icwsToken = null;
icwsRequest.setConnection(icws.host, icws.port);
var icwsConnection = new icwsConn(icwsRequest);
icwsConnection.login(icws.username, icws.password, function(isLogged, icwsSession, headers){
if(isLogged && icwsSession.sessionId && icwsSession.csrfToken){
//icwsConnection.setWorkstation(icws.workstaton);
session.icwsSessionId = icwsSession.sessionId;
session.icwsToken = icwsSession.csrfToken;
icwsRequest.setIcwsHeaders(session.icwsSessionId, session.icwsToken);
console.log('Log: new connection to ICWS! ' + session.icwsSessionId );
}
});
console.log('Log: new connection to websocket!')
return accept('New connection to websocket!', true);
} else {
console.log('Log: token could not be validated!');
return accept('Token could not be validated!', false);
}
});
});
io.on('connection', function (socket) {
console.log('Authorized Session! Websocket id ready for action!');
//var origin = socket.request.headers.origin || '';
//var myIP = socket.request.socket.remoteAddress || '';
if(!socket.request.sessionID){
console.log('Missing Session ID');
return false;
}
var socketId = socket.id;
var sessionID = socket.request.sessionID;
//Add this socket to the user's connection
if(userCons.indexOf(socketId) == -1){
userCons.push(socketId);
}
clients[sessionID] = userCons;
console.log(clients); //display all connected clients
socket.on('placeCall', function(msg){
icwsInter.call(method, uri, params, header, true);
});
socket.on('chat', function(msg){
console.log('Chat Message: ' + msg);
socket.emit('chat', { message: msg });
});
socket.on('disconnect', function(msg){
console.log('Closing sessionID: ' + sessionID);
var userCons = clients[sessionID] || [];
var index = userCons.indexOf(socketId);
if(index > -1){
userCons.splice(index, 1);
console.log('Removed Disconnect Message: ' + msg);
} else {
console.log('Disconnect Message: ' + msg);
}
});
socket.on('error', function(msg){
console.log('Error Message: ' + msg);
});
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
var allowed = env.session.allowedOrigins || []
if(allowed.indexOf(origin) >= 0){
return true;
}
return false;
}
Edited
The io cookie changes on every request. When a io cookie is created it will have a last accessed values of 12/31/1969 4:00:00 PM
Also, this cookie changes on every page reload.
After #Osk suggestion below Here is my new code which is still isn't saving my session data on page reload.
var env = require('./modules/config'),
app = require('express')(),
https = require('https'),
fs = require('fs'),
session = require('express-session'),
redisStore = require("connect-redis")(session),
sharedsession = require("express-socket.io-session"),
base64url = require('base64url'),
cookieParser = require("cookie-parser");
const server = https.createServer(
{
key: fs.readFileSync('certs/key.pem'),
cert: fs.readFileSync('certs/cert.pem')
}, function (req, res){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
}
).listen(env.socket.port, env.socket.host, function () {
console.log('\033[2J');
console.log('Websocket is running at https://%s:%s', server.address().address, server.address().port);
});
var io = require('socket.io')(server);
var sessionStore = new redisStore({
host: env.redis.host,
port: env.redis.port
});
const sessionMiddleware = session({
store: sessionStore,
secret: env.session.secret,
name: env.session.name,
rolling: true,
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60 * 60 * 1000
}
});
app.use(sessionMiddleware);
// Use shared session middleware for socket.io
// setting autoSave:true
io.use(sharedsession(sessionMiddleware, {
autoSave: false
}));
var icwsReq = require('./modules/icws/request.js'),
icwsConn = require('./modules/icws/connection.js'),
icwsInter = require('./modules/icws/interactions.js'),
sessionValidator = require('./modules/validator.js');
var clients = {};
var icwsRequest = new icwsReq();
var sessionChecker = new sessionValidator();
app.get('/', function (req, res) {
res.send('welcome');
});
//Middleware for authorizing a user before establishing a connection
io.use(function(socket, next) {
var origin = socket.request.headers.origin || '';
if (!originIsAllowed(origin)) {
// Make sure we only accept requests from an allowed origin
socket.destroy();
console.log((new Date()) + ' Connection from origin ' + origin + ' rejected.');
return false;
}
var myIP = socket.request.socket.remoteAddress || '';
var token = socket.handshake.query.tokenId || '';
var session = socket.handshake.session || {};
//This should be defined on a reload
console.log('IP Address: ' + myIP + ' SessionID: ' + socket.handshake.sessionID);
if(!token){
console.log('Log: token was not found');
return next(new Error('Token not found'));
}
//allow any user that is authorized
if(session && session.autherized && token == session.token){
console.log('Log: you are good to go');
return next(new Error('You are good to go'));
}
//if the client changed their token "client logged out"
//terminate the open session before opening a new one
if (session.autherized && token != session.token){
var icwsConnection = new icwsConn(icwsRequest);
icwsRequest.setConnection(session.icwsServer, session.icwsPort);
icwsRequest.setIcwsHeaders(session.icwsSessionId, session.icwsToken);
icwsConnection.logout();
session.autherized = false;
session.token = null;
session.icwsServer = null;
session.icwsPort = null;
session.icwsSessionId = null;
session.icwsToken = null;
icwsConnection = null;
session.save();
}
var decodedToken = base64url.decode(token);
sessionChecker.validateData(decodedToken, myIP, env.session.duration, function(isValid, icws){
if(isValid){
session.authorized = true;
session.icwsServer = icws.host;
session.icwsPort = icws.port;
session.token = token;
session.icwsSessionId = null;
session.icwsToken = null;
icwsRequest.setConnection(icws.host, icws.port);
var icwsConnection = new icwsConn(icwsRequest);
/*
icwsConnection.login(icws.username, icws.password, function(isLogged, icwsSession, headers){
if(isLogged && icwsSession.sessionId && icwsSession.csrfToken){
//icwsConnection.setWorkstation(icws.workstaton);
session.icwsSessionId = icwsSession.sessionId;
session.icwsToken = icwsSession.csrfToken;
icwsRequest.setIcwsHeaders(session.icwsSessionId, session.icwsToken);
console.log('Log: new connection to ICWS! ' + session.icwsSessionId );
}
});
*/
session.save(function(){
console.log('Log: new connection to websocket!');
});
return next();
} else {
console.log('Log: token could not be validated!');
return next(new Error('Token could not be validated!'));
}
});
});
io.on('connection', function (socket) {
console.log('Connection is validated and ready for action!');
var socketId = socket.id;
if(!socket.handshake.sessionID){
console.log('sessionId was not found');
return false;
}
var sessionID = socket.handshake.sessionID;
var userCons = clients[sessionID] || [];
//Add this socket to the user's connection
if(userCons.indexOf(socketId) == -1){
userCons.push(socketId);
}
clients[sessionID] = userCons;
//console.log(clients);
socket.on('placeCall', function(msg){
icws.call(method, uri, params, header, true);
});
socket.on('chat', function(msg){
console.log('Chat Message: ' + msg);
socket.emit('chat', { message: msg });
});
socket.on('disconnect', function(msg){
console.log('Closing sessionID: ' + sessionID);
var userCons = clients[sessionID] || [];
var index = userCons.indexOf(socketId);
if(index > -1){
userCons.splice(index, 1);
console.log('Removed Disconnect Message: ' + msg);
} else {
console.log('Disconnect Message: ' + msg);
}
});
socket.on('error', function(msg){
console.log('Error Message: ' + msg);
});
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
var allowed = env.session.allowedOrigins || []
if(allowed.indexOf(origin) >= 0){
return true;
}
return false;
}
Which version of socket.io are you using?
express-socket.io-session works with socket.io 1.x
I see you're calling io.set() which is deprecated on socket.io 1.x
For more on this, take a look at http://socket.io/docs/migrating-from-0-9/ under the title Authentication differences.
There, it's stated that
The old io.set() and io.get() methods are deprecated and only
supported for backwards compatibility."
Could this be related to your issue ?
When you install the express-socket.io-session package, there's an example directory inside the package. It may come in handy to test against a working example for this module.
Here is a working example of how you can share sessions between express and socket.io, even when they are not on the same domain.
(You can find a slightly different git repository with a running example here https://github.com/dievardump/express-socket-auth )
I simply use express-session, I don't see why using another middleware, since it works perfectly with socket.io
Since I do not have redis accessible, I used require('session-file-store') for the shared sessions.
Problem
Problem comes from the cross-domain policy which won't let you share the connect.sid Cookie value.
A workaround is :
serve non-httpOnly session cookies from the host (here for me server.dev). [express.js line 16]
read via JavaScript and send the connect.sid value as a sessionId parameter when connection to socket.io [client.js line 26:30]
when handshaking adding the value of connect.sid=socket.handshake.query.sessionId to the socket.handshake.headers.cookie before reading the handshake with the session middleware [socket.js line 32:37]
Architecture
Here followed :
server.js which require
express.js : Create express server accessed on my computer via http://server.dev:3000
serve HTML
create Sessions when loading page
socket.js : Create Socket.io server accessed on my computer via http://socket.dev:8000
client.js
served on http://server.dev:3000
connect to socket server on http://socket.dev:8000
Tests
Steps to test I used here :
Client open the page
If the cookie key connect.sid is not set
Client tries to connect to Socket.io : Connection error : [Not authenticated]
Client calls /authenticate
session is generated
Client tries to connect to Socket.io with value of connect.sid as sessionId parameter : Connection sucessfull
If cookie connect.sid is set
Client tries to connect to Socket.io with value of connect.sid as sessionId parameter : Connection sucessfull
Files
server.js
require('./express');
require('./socket');
express.js
var express = require('express');
var app = express();
var http = require('http');
var io = require('socket.io');
var bodyParser = require('body-parser');
var sessionExpress = require('express-session');
var FileStore = require('session-file-store')(sessionExpress);
var secret = 'keyboard cat';
var session = sessionExpress({
secret: secret,
store: new FileStore(),
resave: true,
saveUninitialized: true,
cookie: {
httpOnly: false, // important to allow client to read session cookie with JavaScript
maxAge: 60 * 60 * 1000
}
});
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static(__dirname));
app.use('/authenticate', session);
app.get('/authenticate', function(req, res) {
var session = req.session;
session.userdata = session.userdata || {};
session.userdata.connected = true;
session.save(function(err) {
if (err) {
connectionError(res, session);
} else {
res.status(200);
res.send();
}
});
});
// routes
app.get('/', function(req, res) {
res.send('welcome');
});
// setup servers
var server = http.createServer(app);
server.listen(3000);
socket.js
var express = require('express');
var app = express();
var http = require('http');
var io = require('socket.io');
var sessionExpress = require('express-session');
var FileStore = require('session-file-store')(sessionExpress);
var secret = 'keyboard cat';
var sessionIdKey = 'connect.sid';
var session = sessionExpress({
secret: secret,
store: new FileStore(),
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 60 * 60 * 1000
}
});
// setup servers
var server = http.createServer(app, function (req, res){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
});
server.listen(8000);
var sio = io(server);
sio.use(function(socket, accept) {
// writing sessionId, sent as parameter, on the socket.handshake cookies
if (socket.handshake.query.sessionId) {
var cookies = (socket.handshake.headers.cookie || '').split(';');
cookies.push(sessionIdKey + '=' + socket.handshake.query.sessionId);
socket.handshake.headers.cookie = cookies.join(';');
}
session(socket.handshake, {}, function(err) {
if (err) return accept(err);
console.log('User trying to connect to Socket.io');
var session = socket.handshake.session,
userData = session.userdata || {};
// is connected and good
if (!userData || !userData.connected) {
console.log('----- User has no active session, error');
accept(new Error('Not authenticated'));
} else {
console.log('----- Socket.io connection attempt successful');
accept(null, session.userid !== null);
}
});
});
sio.on('connection', function (socket) {
console.log('Connection');
});
client.js
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return decodeURIComponent(parts.pop().split(";").shift());
}
function fetch(url, data, callback) {
try {
var x = new XMLHttpRequest();
x.open(data ? 'POST' : 'GET', url, 1);
x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.onreadystatechange = function () {
x.readyState > 3 && callback && callback(x.responseText, x);
};
x.send(data || null);
} catch (e) {
window.console && console.log(e);
}
};
function connectServer(cb) {
var sessionId = getCookie('connect.sid');
var data = { forceNew: true, query : { } };
if (sessionId) {
data.query.sessionId = sessionId
}
console.log('Trying to connect to Socket.io server');
var server = io('http://socket.dev:8000', data);
server.on('error', function (err) {
console.log('----- Connection error : [%s]', err);
setTimeout(function () {
cb();
}, 200);
});
server.on('connect', function (data) {
console.log('----- Connection successful with sessionId [%s]', sessionId);
setTimeout(function () {
cb();
}, 200);
});
}
if (getCookie('connect.sid')) {
console.log('Session cookie Detected');
connectServer(function () { });
} else {
connectServer(function () {
console.log('Call ./authenticate to create session server side');
fetch('./authenticate', null, function () {
console.log('Session created')
connectServer(function () {});
});
});
}
Execution
First Page loading Results
Client :
Trying to connect to Socket.io server
----- Connection error : [Not authenticated]
Call ./authenticate to create session server side
Session created
Trying to connect to Socket.io server
----- Connection successful with sessionId [s:Ir9dVPi8wzplPCoeNXAsDlOkhL8AW0gx.wwzUQ2jftntWEc6lRdYqGxRBoszjPtjT4dBW/KjFIXQ]
Server :
User trying to connect to Socket.io
----- User has no active session, error
User trying to connect to Socket.io
----- Socket.io connection attempt successful
Connection
Reload page
Client :
Session cookie Detected
Trying to connect to Socket.io server
----- Connection successful with sessionId [s:Ir9dVPi8wzplPCoeNXAsDlOkhL8AW0gx.wwzUQ2jftntWEc6lRdYqGxRBoszjPtjT4dBW/KjFIXQ]
Server :
User trying to connect to Socket.io
----- Socket.io connection attempt successful
Connection

NodeJS and SocketIO on Server

I have a problem with my NodeJS and SocketIO setup on my server,
I want to access the HTTP Port by doing
var socket = io.connect("http://domain.com:8070");
Sadly this returns ERR_CONNECTION_TIMED_OUT
Here is my Server:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app, { log: false })
, fs = require('fs');
var mysocket = 0;
var socket = 0;
app.listen(8070);
function handler (req, res) {
fs.readFile(__dirname + '/app/tpl/skins/habbo/client.php',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
console.log('Client successfully connected');
mysocket = socket;
});
//udp server on 41181
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("Packet recieved from server: " + msg);
if (mysocket != 0) {
mysocket.emit('field', "" + msg);
mysocket.broadcast.emit('field', "" + msg);
}
});
server.on("listening", function () {
var address = server.address();
console.log("udp server listening " + address.address + ":" + address.port);
});
server.bind(41181);
and my Client:
<script src="http://domain.com:8070/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect(http://domain.com:8070);
socket.on("hello", function(l){
var k = l.split(/,/);
switch(k){
case "testing":
{
window.alert('lol');
return;
}
}
});
</script>
Any ideas on how I can get it to work on http://domain.com:8070? Thanks.
It looks like your socket is not listening on port 8070.
Untested, but worth a try :
var io = require('socket.io').listen(app.listen(8070), {log: false});
You can also remove the URL from your client (although it shoudn't change anything) :
var socket = io.connect();
Edit :
You should also wrap the address in quotes :
var socket = io.connect("http://domain.com:8070");

connect mongo to node error

Im tring to connect node server to mongo and there is my code :
var http = require("http");
var url = require("url");
var Router = require('node-simple-router');
var router = Router();
var qs = require('querystring');
var mongoose = require('mongoose');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
// mongo connection and use
mongoose.connect('mongodb://localhost/jobs');
var db = mongoose.connection;
db.on('error', function() {console.log("error")});
db.once('open', function () {
console.log("connected!");
// init the schema
var jobSchema = mongoose.Schema({ bName: String , phone :Number ,location:[{longitude:Number,latitude:Number}],Email:String,field:String,exp:String});
jobSchema.methods.printDetails = function() {
var str = "id=" + this.id + " name="+this.name;
console.log(str);
};
var job = mongoose.model('jobs',jobSchema);
//adding a jobs for testing :
var testJob = new job ({bName: 'Microsoft' , phone :'035588319' ,location:[{longitude:'7.8',latitude:'7.8'}],Email:'microsoft#gmail.com' ,field:'QA',exp:'0-2'});
testJob.save(function(error,prod) {
if(error) {
console.log(error);
}
else {
console.log("a job was saved to mongodb");
//testJob.printDetails();
}
)};
function start(route) {
function onRequest(request, response) {
var path = url.parse(request.url).pathname;
console.log("Request for " +path+ "received.");
route(path);
if(request.method==='GET')
{
response.writeHead(200, {"Content-Type": "text/plain","access-control-allow-origin":"*"});
console.log(request.body);
response.end("res");
}
else if(request.method === 'POST')
{
response.writeHead(200, {"Content-Type": "text/plain","access-control-allow-origin":"*"});
//var userString = JSON.stringify(body);
response.end("POST REQUEST");
}
else if (request.method==='PUT')
{
response.writeHead(200, {"Content-Type": "text/plain","access-control-allow-origin":"*"});
response.end("put request");
}
else if(request.method==='DELETE')
{
response.writeHead(200, {"Content-Type": "text/plain","access-control-allow-origin":"*"});
response.end("delete request");
}
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
i dont start my server because of syntax error on line 79 , but i only have 78 lines .
syntax error unexpected end of input : }); , and can anyone tell me if this is the right way to connect between the mongo and the node web server .
When you call db.once("open", function () { you never close that paren and brace.
I think you want a }); after the testJob declaration. That should also be }) and not )}.

How can I get node.js to return data once all operations are complete

I am just learning server-side JavaScript so please bear with any glaring mistakes I've made.
I am trying to write a file parser that operates on HTML files in a directory and returns a JSON string once all files have been parsed. I started it with a single file and it works fine. it loads the resource from Apache running on the same machine, injects jquery, does the parsing and returns my JSON.
var request = require('request'),
jsdom = require('jsdom'),
sys = require('sys'),
http = require('http');
http.createServer(function (req, res) {
request({uri:'http://localhost/tfrohe/Car3E.html'}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var window = jsdom.jsdom(body).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
// jQuery is now loaded on the jsdom window created from 'body'
var emps = {};
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step++;
var name = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = name.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2];
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
emps = JSON.stringify(emps);
//console.log(emps);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(emps);
});
} else {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("empty");
//console.log(response.statusCode);
}
});
}).listen(8124);
Now I am trying to extend this to using the regular file system (fs) and get all HTML files in the directory and parse them the same way and return a single combined JSON object once all files have been parsed. Here is what I have so far but it does not work.
var sys = require("sys"),
fs = require("fs"),
jsdom = require("jsdom"),
emps = {};
//path = '/home/inet/www/media/employees/';
readDirectory = function(path) {
fs.readdir(path, function(err, files) {
var htmlfiles = [];
files.forEach(function(name) {
if(name.substr(-4) === "html") {
htmlfiles.push(name);
}
});
var count = htmlfiles.length;
htmlfiles.forEach(function(filename) {
fs.readFile(path + filename, "binary", function(err, data) {
if(err) throw err;
window = jsdom.jsdom(data).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step++;
var empname = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = empname.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2]
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
});
});
});
});
}
readDirectory('/home/inet/www/media/employees/', function() {
console.log(emps);
});
In this particular case, there are 2 html files in the directory. If i console.log(emps) during the htmlfiles.forEach() it shows me the results from the first file then the results for both files together the way I expect. how do I get emps to be returned to readDirectory so i can output it as desired?
Completed Script
After the answers below, here is the completed script with a httpServer to serve up the detail.
var sys = require('sys'),
fs = require("fs"),
http = require('http'),
jsdom = require('jsdom'),
emps = {};
var timed = setInterval(function() {
emps = {};
readDirectory('/home/inet/www/media/employees/', function(emps) {
});
}, 3600000);
readDirectory = function(path, callback) {
fs.readdir(path, function(err, files) {
var htmlfiles = [];
files.forEach(function(name) {
if(name.substr(-4) === "html") {
htmlfiles.push(name);
}
});
var count = htmlfiles.length;
htmlfiles.forEach(function(filename) {
fs.readFile(path + filename, "binary", function(err, data) {
if(err) throw err;
window = jsdom.jsdom(data).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
var imagecount = jquery("tr td img").length;
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step += 1;
var empname = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = empname.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2]
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
count -= 1;
if (count <= 0) {
callback(JSON.stringify(emps));
}
});
});
});
});
}
var init = readDirectory('/home/inet/www/media/employees/', function(emps) {
});
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(emps));
}).listen(8124);
That sure is a lot of code a couple of mistakes.
You're never calling the callback function you supply to readDirectory
You need to keep track of the files you have parsed, when you parsed all of them, call the callback and supply the emps
This should work:
var sys = require("sys"),
fs = require("fs"),
jsdom = require("jsdom"),
//path = '/home/inet/www/media/employees/';
// This is a nicer way
function readDirectory(path, callback) {
fs.readdir(path, function(err, files) {
// make this local
var emps = {};
var htmlfiles = [];
files.forEach(function(name) {
if(name.substr(-4) === "html") {
htmlfiles.push(name);
}
});
// Keep track of the number of files we have parsed
var count = htmlfiles.length;
var done = 0;
htmlfiles.forEach(function(filename) {
fs.readFile(path + filename, "binary", function(err, data) {
if(err) throw err;
window = jsdom.jsdom(data).createWindow();
jsdom.jQueryify(window, 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', function (window, jquery) {
jquery("tr td img").parent().parent().each(function(){
var step = 0;
jquery(this).children().each(function(index){
if (jquery(this).children('img').attr('src') !== undefined) {
step++;
var empname = jquery(this).parent().next().next().children('td:nth-child('+step+')').children().children().text();
var name_parts = empname.split(",");
var last = name_parts[0];
var name_parts = name_parts[1].split(/\u00a0/g);
var first = name_parts[2]
emps[last + ",_" + first] = jquery(this).children('img').attr('src');
}
});
});
// As soon as all have finished call the callback and supply emps
done++;
if (done === count) {
callback(emps);
}
});
});
});
});
}
readDirectory('/home/inet/www/media/employees/', function(emps) {
console.log(emps);
});
You seem to be doing this a tad wrong
readDirectory('/home/inet/www/media/employees/', function() {
console.log(emps);
});
But you've defined your function as:
readDirectory = function(path) {
Where is the callback argument? Try this:
readDirectory = function(path, callback) {
then under emps[last + ",_" + first] = jquery(this).children('img').attr('src'); put
callback.call(null, emps);
Your callback function will be called however many times your loop goes on for. If you want it to return all of them at once, you'll need to get a count of how many times the loop is going to run for, count up until that number then call your callback when the emps array is full of the data you need.

Categories