Reputation: 1478
I've been studying Nodejs and Socket.io, the problem is I'm struggling on how to get an url parameter (www.example.com/sample/:sampleid) and use it on my socket connection.
Here's an example:
var roomname;
var username;
app.get('/room/:roomname/user/:username', function(req, res){
var room = {
username: req.params.username,
roomname: req.params.roomname
};
roomname = room.roomname;
username = room.username;
res.render('room', room);
});
var users = {};
io.sockets.on('connection', function (socket) {
socket.username = username;
socket.room = roomname;
users[username] = username;
console.log("joining room: " + roomname)
socket.join(roomname);
console.log("emiting to room: " + roomname)
socket.broadcast.to(roomname).emit('newUser', username);
});
I'm simply storing the name on roomname and using it inside io.sockets.on
, but I think that's a hack and should be a better way to achieve this...
What's a good way to solve this kind of situations?
Upvotes: 0
Views: 8655
Reputation: 59
I had the same question and arrived at a different solution, where I pass the parameters at the time of connection.
//it's my connection in client side
let socket = socketio(`http://localhost:4444?user=${uuid}&room=${room}`);
// where UUID is my user ID and room id
So on the server side we can get that parameters like below
let userUUID = socket.handshake.query.user;
let roomId = socket.handshake.query.room;
The good thing is that when connection is lost you do not depend on the fact that the client will call your custom connection event again, you can put your logic into the default io.on('connection',);
More info here https://socket.io/docs/server-api/#socket-handshake
Upvotes: 2
Reputation: 1314
Since you're using res.render
and you're already passing room
as a data parameter, I think it's best to make use of that and do something like this (I use EJS in my example since I'm used to that):
Client:
<script>socket.emit('join', {room: '<%- room.roomname %>' });</script>
Server:
io.on('connection', (socket) => {
socket.room = '';
socket.on('join', (msg) => {
socket.room = msg.room;
});
});
Otherwise it could be an idea to emit document.location.pathname
, but then you'd have to parse the path yourself to get the roomname out of it.
EDIT:
What you're doing at the moment is actually very dangerous, because of the following scenario:
User 1 opens the page, "global" variables username
and room
get set (let's set them both to foo
for now), but user 1 has slow internet, so it takes some time to load and for socket.io to connect.
Now User 2 opens the page, the "global" variables username
and room
are changed to the new values (let's use bar
), before user 1 opens up the socket.io connection.
Now User 1 and User 2 connect with socket.io, but since user 2 has faster internet than user 1, var username
and var roomname
are now both set to value bar
even though User 1 has username
and roomname
foo
.
Just a heads up.
Upvotes: 1
Reputation: 830
socket can emit any event because socket object is EventEmitter
so that it can fire(emit) event in any time and on anther side server can listen to this events by .on function
example
socket.emit('join',{name:"ahmed"})
server
io.sockets.on('join',function(data){
console.log(data.name)
})
Upvotes: 1