I'm trying to check the username in the NodeJs chat with the user session. Is there a secure way to do it? (My NodeJs server isn't in the same place as the host of the website). I'm using this code NodeJs + express to do the chat application.
Code:
var express = require('express');
var app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server, { log: false });
server.listen(8080);
app.get('/chat.js', function(req, res) {
res.sendfile('chat.js');
});
/* CHAT FUNCTIONS */
io.sockets.on('connection', function (socket) {
socket.on('send', function (data) {
// I wanna get the user session
// something like this:
// (code below does not exist)
var username = session['username'];
console.log(username + " is here.");
io.sockets.emit('message', data);
});
});
How can I do this?
You need to use common storage for sessions e.g. memcached or redis.
Than u will have common access.
Related
I just set up SocketIO in my PHP project. I am completly new to websockets at all so bear with me.
I am defining the socketIO variable globally
let socketIO = io("http://localhost:3000");
When people are logging in to my application, they are connected to it with their ID comming from the database. The login script just gives back true which redirects the user in very simplified terms:
// get component
$.get(url, data, (data) => {
if (data.status) {
// connect with Node JS server
socketIO.emit("connected", data.user_id);
// redirect
load_new_page("/users/" + data.user_id);
}
});
My concern here now is that people could just go and change the data.user_id to anything they want and receive what ever the chosen id would receive.
My server.js:
// initialize express server
var express = require("express");
var app = express();
// create http server from express instance
var http = require("http").createServer(app);
// include socket IO
var socketIO = require("socket.io")(http, {
cors: {
origin: ["http://localhost"],
},
});
// start the HTTP server at port 3000
http.listen(process.env.PORT || 3000, function () {
console.log("Server started running...");
// an array to save all connected users IDs
var users = [];
// called when the io() is called from client
socketIO.on("connection", function (socket) {
// called manually from client to connect the user with server
socket.on("connected", function (id) {
users[id] = socket.id;
});
});
});
How can I prevent something like this?
I am on the process of building a chat application with nodejs, reactjs mongo and socket.io.My chat app consists of both one to one and group chats.I have built a schema for group chat and i am inserting group names along with its members and their chats in the table.Since im a beginner towards socket.io, I dont know where to put the socket logic that needs to be fired after the db post operation.Can some one suggest any examples for me?
Update your code accordingly:
=> server.js file
// Declare socket.io
const io = require('socket.io')(server);
// Add middleware to set socket.io in
app.use((req, res, next)=>{ res.locals['socketio'] = io; next(); });
=> In your controller file
// Get the value of socket.io
module.exports = your_function_name = (req, res) => {
const io = res.locals['socketio']
// Use io when you need.
});
Hope this solves your query.
You can separate you socket related code by following way :
==>app.js
var express = require('express');
var socket = require('./socketServer');
var app = express();
var server = app.listen((config.node_port || 3000), function () {
console.log('Listening on port ' + (config.node_port || 3000) + '...');
});
socket.socketStartUp(server);
module.exports = app;
==>socketServer.js
var io = require('socket.io')();
var socketFunction = {}
socketFunction.socketStartUp = function (server) {
io.attach(server);
io.on('connection', function (socket) {
console.log("New user is connected with socket:", socket.id);
})
}
module.exports = socketFunction;
You can also check node API startup code with socket functionality in below link:
Node API Start up
Hope this answer is helpful to you
With the following code snippet:
var express = require('express'),
app = express(),
server = require('https').createServer(app),
io = require('socket.io')(server);
app.get('/', function(req, res, next) {
res.sendFile(__dirname + '/assets/html/index.html');
});
/** More routing functions **/
io.on('connection', function(socket) {
components.socket.onConnect(socket, config);
});
io.on('save', function(data){
var saved = save(data);
io.emit('response', saved);
});
/** More Socket.io functions **/
server.listen(443, function() {
console.log("Server Ready.");
});
Assuming this server side setup (with ssl cert) and the clients connect securely, are the data value on save and the saved value emitted back with socket.io also encrypted with the ssl cert like the web data would be too?
The answer is yes as long as you use https for the initial connection. In your example, since you're only ever using https, this will never be a problem for you.
I would like use nodeJS to refresh my view, every time a function has made changes to the database. If we take MEAN-stack as an example, I don't want to send an $http-request every x seconds to check if changes have been made to the database. I would like the front end to get notified automatically and then update the view.
What are best practices for this? I would use some kind of Oberserver pattern in the server side, but do not know how I could notify the front end with that.
To get the front end to get notified automatically and then update the view you could use Socket.io framework.
You can find all of the documentation on their site: http://socket.io/
And here is a basic example:
app.js ( to set up the server)
var http = require('http');
var express = require('express');
var port = normalizePort(process.env.PORT || '1000');
var app = express();
var server = http.createServer(app);
server.listen(port);
io = require('socket.io')(server);
///ROUTES
var routes = require('./routes/index')(io);
var users = require('./routes/users');
///////
I pass the io object to route index(and ofcourse there is a lot more stuff on app.js..this is just a basic example...).
mysql.js (to create a pool for connections)
var mysql = require("mysql");
var pool = mysql.createPool({
host : 'host',
user : 'user',
password : 'pass',
database : 'db_name',
connectionLimit: 1000
});
exports.pool = pool;
index.js
module.exports = function(io) {
var express = require('express');
var router = express.Router();
var mysql = require('../mysql.js').pool;
io.on('connection', function (socket) {
socket.on('event_name', function (data) {
mysql.getConnection(function(err,connection){
if (err) {
connection.release();
return;
}
connection.query("SQL STUFF",function(err,rows){
if(rows.length>0){//checks if there are more than 0 rows returned.....
socket.emit('do_something',data_you_want_to_pass);
}
else{
socket.emit('do_something_else',data_you_want_to_pass);
}
connection.release();
});
connection.on('error', function(err) {
return;
});
});
});
});
router.get('/', function(req, res) {
res.render("index");
});
return router;
}
And then on html page you have socket.emit and socket.on again.....
I recommend you take a look at the documentation and a few other examples...
I hope I helped you.
I am working on realtime data visualization application using node.js, express and socket.io.
Requirement:
Have to emit the events based on the client request.
For example: If user enter the url as http://localhost:8080/pages socket.io should emit the topic pages to client and another user request for http://localhost:8080/locations socket should emit location to that particular user.
Code
var server = app.listen("8080");
var socket = require('socket.io');
var io = socket.listen(server);
var config = {};
io.on('connection', function (socket) {
config.socket = io.sockets.socket(socket.id);
socket.on('disconnect', function () {
console.log('socket.io is disconnected');
});
});
app.get('/*', function(req, res) {
var url = req.url;
var eventName = url.substring('/'.length);
//pages and locations
config.socket.volatile.emit(eventName, result);
});
Client Code:
//No problem in client code.Its working correctly.
Sample code as follows
socket.on('pages', function (result) {
console.log(result);
});
Problem:
It is emitting pages and locations to both the clients.
Any suggestion to overcome this problem.
I couldn't understand your approach on this, but because you said you're rendering different pages, It means you can serve different code, so what about doing it like this:
Server Side:
var server = app.listen("8080");
var socket = require('socket.io');
var io = socket.listen(server);
var config = {};
app.get('/pages', function(req, res) {
res.render('pages.html');
});
app.get('/locations', function(req, res) {
res.render('locations.html');
});
io.on('connection', function (socket) {
socket.on('pagesEvent', function(data){
socket.volatile.emit('pages', {your: 'data'});
});
socket.on('locationsEvent', function(data){
socket.volatile.emit('locations', {your: 'data'});
});
});
On Client side:
pages.html:
socket.on('connect', function(){
socket.emit('pagesEvent', {});
});
socket.on('pages', function(data){
// do stuff here
});
locations.html:
socket.on('connect', function(){
socket.emit('locationsEvent', {});
});
socket.on('locations', function(data){
// do stuff here
});
You are doing it wrong, WebSockets supposed to work same in both directions. Client emit event to Server, server emit back to Client/Subscribers.
The way you are doing things, seems like a way of implementing API, but for some reason you are trying to implement it with WebSockets, instead of XHR.