Node.js variable getting reset - undefined - javascript

I have a global variable (openTokSessionID) that is set by a function. When the function is run again, it should check to see if openTokSessionID is set. If it is, it should use the current value. Instead, however, it complains that openTokSessionID is undefined. My server code is below. Thanks for your help.
var http = require('http').createServer(handler),
io = require('socket.io').listen(http).set('log level', 1),
opentok = require('opentok'),
key = '', // Replace with your API key
secret = ''; // Replace with your API secret
var ot = new opentok.OpenTokSDK(key,secret);
ot.setEnvironment("staging.tokbox.com");
//ot.setEnvironment("api.opentok.com"); //only for production
http.listen(8080);
console.log('Chatserver listening on port 8080');
var nicknames = {};
var log = {};
var connectedUsersObject={};
var privateSessionObject={};
var data;
var openTokSessionID='';
function handler(req, res) {
res.writeHead(200);
res.end();
}
////////////////////////////////////////////SOCKET.IO FUNCTIONS///////////////////////////////////////////////////////
io.sockets.on('connection', function (socket) {
socket.on('private message', function(data) {
console.log('OpenTok Session ID is: ....' + openTokSessionID);
if(data.messageType=='openTokDemoRequest'){ //if new session, create unique session ID, add to current chat object
console.log(data.messageType + ' sender: ' + data.from);
var location = '127.0.0.1'; // use an IP or 'localhost'
console.log('message type is: "openTokDemoRequest". openTokSessionID is: ' + openTokSessionID);
var messageRecipient=data.from;
if(openTokSessionID==''){
console.log('The session ID is: ' + openTokSessionID + '++++++++');openTokSessionID= ot.create_session(location, function(openTokSessionID){
var data= {'to':messageRecipient, 'message':{'token': ot.generate_token({'session_id':openTokSessionID, 'role': "publisher"}), 'sessionID': openTokSessionID, 'apikey':key}, 'from': 'openTok', 'messageType':'demoTokenInfo', 'privateSessionID':''};
console.log('NEW session id is: ' + openTokSessionID + '. token is: ' + data.message.token);
// privateMessageSend(data);
// sendToUser(data);
connectedUsersObject[messageRecipient].emit('private message', data);
console.log ('message recipient is: ' + messageRecipient);
});
}
else{
console.log('OpenTok Session ID is: ////' + openTokSessionID);
var data= {'to':messageRecipient, 'message':{'token': ot.generate_token({'session_id':openTokSessionID, 'role': "publisher"}), 'sessionID': openTokSessionID, 'apikey':key}, 'from': 'openTok', 'messageType':'demoTokenInfo', 'privateSessionID':''};
console.log('session id is: ' + openTokSessionID + '. token is: ' + data.message.token);
connectedUsersObject[messageRecipient].emit('private message', data);
console.log ('message recipient is: ' + messageRecipient);
}
}
});

Here you're trying to use the return value from an asynchronous call, and as a result you're setting your variable to undefined:
openTokSessionID= ot.create_session(location, function(openTokSessionID){
...
Because you gave your callback argument the same name as your variable, it masked your variable within the callback so it looked OK the first time, but your actual variable got trashed.
You need to change it to something like:
ot.create_session(location, function(sessionID){
openTokSessionID = sessionID;
...

Related

Uncaught (in promise) TypeError: s.createConnection is not a function at n.register.c.connect

I'm currently tring to exploit a RSS feed to get latest articles from a website.
What I'm doing is to store these data in a MySQL DB. I do that with Javascript, to take informations from the RSS feed.
When I host the script on my server, it's not working anymore.
For the context of programming, on local, I used XAMPP, with a localhost. Then, I do a parcel build, the script being attached to a HTML page, so that I can call it just by loading the WebPage.
I got the error from the title :
Here is the code :
let Parser = require('rss-parser');
let parser = new Parser();
(async () => {
// Connecting to database
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'dataarticles'
});
connection.connect((err) => {
if (err) throw err;
console.log('Connected!');
});
let feed = await parser.parseURL('http://feedrinse.com/services/rinse/?rinsedurl=235e4f5244e1eeb21ce05fc3d4d68cc0');
//== Some console.log to check
// console.log(feed.items[0]['content:encoded']);
//== Some console.log to check
// console.log(feed.items[0].title + "\n"
// + feed.items[0].link + "\n"
// + feed.items[0].contentSnippet + "\n"
// + feed.items[0].pubDate);
// As the feed doesn't provide the minia of article, I take the first image in the content of the test, by searching it
let firstPos = feed.items[0]['content:encoded'].search("https://droidsoft.fr/wp-content/uploads/");
let SecondPos = feed.items[0]['content:encoded'].search('alt="');
let image = feed.items[0]['content:encoded'].substring(firstPos, SecondPos - 2);
let pubDate = feed.items[0].pubDate.substring(5, 16);
//== Some console.log to check
// console.log(image);
// console.log(pubDate);
// We take first item (items[0]) as it's the latest feed. This script is triggered only when there is a new element, so there shouldn't be
// any problem of duplication
connection.query('INSERT INTO `dataarticles` (`Titre`, `URL`, `Description`, `Image`, `date`) VALUES ("' + feed.items[0].title + '", "' + feed.items[0].link + '", "' + feed.items[0].contentSnippet + '", "' + image + '", "' + pubDate + '")', (err, rows) => {
// if (err) throw err;
console.log(rows);
});
})();

Socketio 1.0 get attributes from all clients

I am currently working on a simple socketio application in which i am sending some parameters to envents and i am storing them into each socket.
socket.on('add user', function (data) {
if (addedUser) return;
// we store the username in the socket session for this client.
socket.nickname = data.nickname;
socket.userId = data.userId;
...
Then i am getting all socketio clients using var io.engine.clients and i am trying to obtain that parameters in other event like this:
socket.on('new message', function (data) {
var clientsRoom = io.engine.clients;
for(var c in clientsRoom){
console.log(" Client: " + c.userId); //Error
console.log(" Client: " + c); //outputs the socket ID
console.log(" Client: " + c['userId']); //Error
}
...
but i am unable to get my userID previously stored for all sockets. ¿What am i doing wrong?
Thanks.
Instead of io.engine.clients, you should use io.sockets.sockets (they aren't the same, socket.io adds an extra layer on top of engine.io). Also make sure that you treat it as an object, not an array:
var clientsRoom = io.sockets.sockets;
for (var id in clientsRoom) {
var c = clientsRoom[id];
console.log(" Client: " + c.userId);
console.log(" Client: " + id);
}

node.js / socket.io - keep track of clients

Dear friends I have a small issue while trying to keep track of a logged in users in chat. The chat is based on two separate channels that work with the help of namespaces:
chatInfra - to handle logged in users and send welcome messages.
chatCom - to handle messageing between users.
I have searched a lot but I found only theoretical explanations that the best solutions is to store users into array. Therefore I tried to keep the track of logged in users by storing them in array and then iterating through them but still the result is not good.
The problem is that after entering to the chat, only the first logged in user's name appears on screen, whereas the second user's name is not visible.
This is my server side code, I am trying to store users into clients array:
var clients = [];
var chatInfra = io.of("/chat_infra").on("connection", function(socket){
socket.on("set_name", function (data) {
clients.push(data.name);
socket.emit('name_set', data);
socket.send(JSON.stringify({
type:'serverMessage',
message:'Welcome!'
}));
socket.broadcast.emit('user_entered', data);
});
});
var chatCom = io.of("/chat_com").on("connection", function (socket) {
socket.on('message', function (message) {
message = JSON.parse(message);
for(var key in clients){
if(message.type == "userMessage"){
message.username = clients[key];
console.log('message : ', message);
socket.broadcast.send(JSON.stringify(message));
message.type = "myMessage";
socket.send(JSON.stringify(message));
}
}
});
});
Here is how it looks in browser: http://screencast.com/t/lshnfcGZ8E8
Here is the full code: https://gist.github.com/johannesMatevosyan/0b9f7e588338dbb6b7f5
I think you're creating an unnecessary overkill by using different namespaces. Here's a clearer working example achieving the same functionality:
server.js
var app = require("express")();
var server = require("http").Server(app);
var io = require("socket.io")(server);
var chat = io.of("/chat").on("connection", function(socket){
socket.on("set_name", function (data) {
socket.username = data.name;
socket.emit("name_set", data);
socket.emit("message", {
type :"serverMessage",
message :"Welcome!"
});
chat.emit("message", {
type :"serverMessage",
message : data.name + " has joined the room.!"
});
});
socket.on("message", function (message) {
message.username = socket.username;
chat.emit("message", message);
});
});
app.get("/", function (req, res) {
res.sendfile(__dirname + "/index.html");
});
server.listen(3000);
client.js
var socket = io.connect('http://localhost:3000/chat');
socket.on('name_set', function (data) {
$('#nameform').hide();
$('#messages').append('<div class="systemMessage">Hello ' + data.name + '</div>');
});
socket.on('message', function (message) {
var userNameHtml = message.username ? '<span class="name">' + message.username + ':</span>' : '';
$('#messages').append('<div class="' + message.type + '">' + userNameHtml + message.message + '</div>');
});
$(function () {
$('#setname').click(function () {
socket.emit("set_name", { name: $('#nickname').val() });
});
$('#send').click(function () {
socket.emit("message", {
message : $('#message').val(),
type : 'userMessage'
});
$('#message').val('');
});
});
I don't think you need a separate event handler for user_entered, since you are treating it as a regular message and not doing anything else with the event. Also a couple of things:
You don't need to first connect to the server and then to the namespace address, connecting to the later is just fine.
Don't set event listeners within callbacks, that will result in setting them multiple times.

Socket not saving data inside handshake object?

I am trying to save session data inside a handshake object from io.set('authorization')
var io = sio.listen(server);
io.set('authorization', function (handshake, callback) {
if(handshake.headers.cookie) {
var cookies = cookie.parse(handshake.headers.cookie);
var sid = cookieParser.signedCookie(cookies['xygaming'], secrets.sessionSecret);
sessionStore.load(sid, function(err, session) {
if(err || !session) {
return callback('Error retrieving session!', false);
}
// this is not storing the data into the handshake object
handshake.balloons = {
user: session.passport.user,
room: /\/(?:([^\/]+?))\/?$/g.exec(handshake.headers.referer)[1]
};
return callback(null, true);
});
} else {
return callback('No cookie transmitted.', false);
}
});
I have an adapter for pub sub
io.adapter(redisIo({
host: 'localhost',
port: 6379,
pubClient: pub, // just redis.createClient()
subClient: sub // just redis.createClient()
}));
Then I want to access the handshake data inside the io.sockets.on('connection') but its not there? Any idea why its not passing? In the original repo it works on express 3x, but since I upgraded to 4x and made some modifications of my own it does not pass through?
io.sockets.on('connection', function (socket) {
console.log(socket.handshake);
// I want to pass the handshake data here, but its undefined??
var hs = socket.handshake
, nickname = hs.balloons.user.username
, provider = hs.balloons.user.provider
, userKey = provider + ":" + nickname
, room_id = hs.balloons.room
, now = new Date()
// Chat Log handler
, chatlogFileName = './chats/' + room_id + (now.getFullYear()) + (now.getMonth() + 1) + (now.getDate()) + ".txt"
// , chatlogWriteStream = fs.createWriteStream(chatlogFileName, {'flags': 'a'});
socket.join(room_id);
});

Undefined class variable when defined in constructor

Just started using CoffeeScript and have hit a wall. In my code below I construct WebSocketServer with a number as the first argument and a function as the second argument. When the code is ran and the websocket receives a message, #msgHandler is now magically undefined. I tried to work around this by setting a variable handler to #msgHandler but that ended up being undefined as well. If anyone has any ideas I'd love to hear them, thanks!
main.coffee
#Used to communicate with browser interface
webSocketServ = new sio.WebSocketServer Sauce.Server.WebSocketPort, (data, socketId) ->
try
json = JSON.parse(data)
msgType = json.msgType
catch error
return
if (this.isAuthed(socketId))
switch msgType
when "auth"
else
io.websocket 'TODO: ' + cmd
else
if msgType is 'auth'
token = json.token
socket.coffee
class WebSocketServer
constructor: (#port, #msgHandler) ->
#webSockets = []
#handlers = {}
#test = []
#authedSockes = []
#listen(#port);
console.log #msgHandler #msgHandler is defined here as [ Function ]
listen: (port) ->
#wsServ = engine.listen port
#wsServ.on 'connection', #onConnect
io.socket "WebServer socket started on port #{port}"
onConnect: (client) ->
io.websocket 'New connection with id of ' + client.id
handler = #msgHandler ##msgHandler is undefined here?
client.on 'message', (data) ->
handler data, client.id
io.websocket '[' + this.id + '] ' + JSON.stringify(data)
client.on 'close', ->
io.websocket '[' + this.id + '] Disconnect'
client.on 'error', (err) ->
io.websocket "IO error: " + err
compiled socket.coffee
WebSocketServer = (function() {
function WebSocketServer(port, msgHandler) {
this.port = port;
this.msgHandler = msgHandler;
this.webSockets = [];
this.handlers = {};
this.test = [];
this.authedSockes = [];
this.listen(this.port);
console.log(this.msgHandler);
}
WebSocketServer.prototype.listen = function(port) {
this.wsServ = engine.listen(port);
this.wsServ.on('connection', this.onConnect);
return io.socket("WebServer socket started on port " + port);
};
WebSocketServer.prototype.onConnect = function(client) {
var handler;
io.websocket('New connection with id of ' + client.id);
handler = this.msgHandler;
client.on('message', function(data) {
handler(data, client.id);
return io.websocket('[' + this.id + '] ' + JSON.stringify(data));
});
client.on('close', function() {
return io.websocket('[' + this.id + '] Disconnect');
});
return client.on('error', function(err) {
return io.websocket("IO error: " + err);
});
};
WebSocketServer.prototype.isAuthed = function(socketId) {
return __indexOf.call(this.authedSockets, user) >= 0;
};
WebSocketServer.prototype.authSocket = function(socketId) {
this.authedSockets.push(socketId);
return io.websocket('Authed socket with ID of ' + socketId);
};
WebSocketServer.prototype.deauthSocket = function(socketId) {
return this.authedSockets = this.authedSockets.filter(function(word) {
return word !== socketId;
});
};
return WebSocketServer;
})();
It's not an undefined class variable, you mean that you cannot access an instance property. It's caused by the common this context issue in callbacks - you cannot just pass a method and expect it to know the instance.
Fortunately, this can be trivially fixed in CS using the fat arrow syntax for the method definition and other callbacks:
onConnect: (client) =>
# ^^
io.websocket 'New connection with id of ' + client.id
handler = #msgHandler # # is now the expected instance
client.on 'message', (data) =>
# ^^
handler data, client.id
io.websocket '[' + #id + '] ' + JSON.stringify(data)
# ^ or did you mean to use `client.` here?
client.on 'close', =>
# ^^
io.websocket '[' + #id + '] Disconnect'
client.on 'error', (err) ->
io.websocket "IO error: " + err
A different (and possibly better) approach might be to let your WebSocketServer class inherit from the engine's class, instead of building a wrapper around it. Since all callbacks are called on the server instance usually, you could access your properties directly without needing to bind the callbacks.

Categories