Socket.io kick specific user - javascript

I have an event from the client side that passes the socket id to be kicked to the server, socket.emit('kick', socketId);.
My intention is to find the socket using this socketId server side, and then call socketToBeKicked.disconnect(). How do I find the specific socket? I tried looking at other posts but most of the solutions do not work anymore. Or is there a better way that I can implement the kick function?

I figured out a solution. Instead of trying to find the socket obj on the server side, we can emit an event from the server to the client to that is going to get kicked and emit another event back to the server to get the client's socket obj.
client.js
socket.emit('kick', socketId); // sent by the host
socket.on('kick helper', () => { // sent by the user getting kicked
socket.emit('kick helper');
}
server.js
socket.on('kick', (socketId) => {
socket.to(socketId).emit('kick helper');
}
socket.on('kick helper', () => { // now this socket obj is the user getting kicked
socket.disconnect();
}
It still feels like quite a long way around to get the socket object of the user to be kicked. Please share if you have a better solution, I would love to know!

Related

Ideal way to handle multiple socket rooms?

So I am creating a chat application and I want to handle multiple chat rooms. Now I watched some tutorials and came up with a way.
const io = require("socket.io")(http);
io.on("connection", (socket) => {
socket.on("joinRoom", (roomid) => {
//Joining the room
socket.join(roomid)
//Broadcasting all previous messages
io.to(roomid).emit("messages",allPreviousMessages)
})
socket.on("chatMessage", (data) => {
//Saving msg to dB then broadcasting
io.to(roomid).emit("message",receivedMessage)
})
socket.on("disconnect",(data) => {
//updating user's lastSeen info in dB
})
})
So on my frontend when user clicks on a chatroom we call the "joinRoom" event and connect to the room and on clicking another chatroom make the same process of joining room.
Is this an ideal way for handling multiple chatrooms? If not so please let me know a better solution.
I think the best way to implement private rooms or channels or chats is this way. I have implemented an example for these three sections. Link
User token and api must be authenticated before connecting to socket.io. If this part is ok it will connect to socket.io otherwise it can't cause you to see the event that is there. Something happens by calling each of them. For example, by calling this onNotificationForVoiceCall event, the received data is first checked, then it is checked whether this user is present in the list of online users or not, and the state of the next step is checked. Whether or not this room has already been created in the database, the response of all these operations is returned to the user by socket.emit,
And I fixed some bug in project.

How to create sockets that particular to user and disposable on Socket.Io

I write a Node.Js app and I use Socket.Io as the data transfer system, so requests should be particular to per user. How can I make this?
My actual code;
node:
io.on('connection', (socket) => {
socket.on('loginP', data => {
console.log(data);
})
})
js:
var socket = io('',{forceNew : false});
$("#loginbutton").click(function() {
var sessionInfo = {
name : $("#login input[name='username']").val(),
pass : $("#login input[name='pass']").val()
}
socket.emit("loginP", sessionInfo)
})
It returns one more data for per request and this is a problem for me. Can I make this on Socket.Io or should I use another module, and If I should, which module?
If I understand your question correctly (It's possible I don't), you want to have just one connection from each user's browser to your nodejs program.
On the nodejs side, your io.on('connection'...) event fires with each new incoming user connection, and gives you the socket for that specific connection. So, keep track of your sockets; you'll have one socket per user.
On the browser side, you should build your code to ensure it only calls
var socket = io(path, ...);
once for each path (your path is ''). TheforceNew option is for situations where you have multiple paths from one program.

How to get Socket to send to the requesting client only?

I am having an issue practicing with socket.io. I have a function set up, where on connection, the users data is refreshed, only it seems to only be happening AFTER the initial connection.
When one user connects, nothing on new user refreshes. Aditional new user connects, Old connection refreshes, but new connection remains untouched.
Am I not able to send data during connection?
This is just some simple practice for me, trying to get better with websockets, and can't seem to get past the general broadcast.emit.
I have tried socket.to(socket.id).broadcast.emit, of course, however no luck there either. You will see in my code.
// Setup socket.io
socketIo.on('connection', socket => {
getDataByUser(user, socket)
socket.on('disconnect', function() {
delete CLIENTS[socket.id];
console.log(`${username} disconnected`)
});
function getDataByUser(user, socket) {
var items = [1,2,3];
items.forEach(element => {
socket.broadcast.emit('server:data', element)
socket.broadcast.to(socket.id).emit('data', 'for your eyes only');
});
}
As you can see in the getData function, I use both a general emit, and an emit to, in order to test it. I have proper listeners set up, however the socket itself is only refreshed apon a new connection. Perhaps this is only called when socket a makes a new connection?
I would like to have this function called imediately apon socket connection. for only the user who has connected. Any help would be greatly appreciated.
I think the way you can deal with this is to not broadcast it.
Try to emit only to the socket who got connected at that time.
I did not get what you are trying to achieve so if the code below does not resolve you problem please say what output do you expect.
socketIo.on('connection', socket => {
var items = [1,2,3];
items.forEach(element => {
socket.emit('server:data', element)
socket.emit('data', 'for your eyes only');
});
socket.on('disconnect', function() {
socket.disconnect();
console.log(`${username} disconnected`)
});
when you use the socket object you adress to that client only...the one who establised the connection.

How can I connect a node.js server page to my sockets server as though it were a client?

I've seen many similar questions here, like this one about connecting servers to sockets, however, that doesn't seem to be working.
My goal is to have one of my server pages occasionally emit an "advance" event to all of the connected clients. My sockets server listener (sockets.js) looks like this
io.on('connection', function (socket) {
socket.on('advance', function () {
console.log('advancing clients');
io.emit('advance');
});
});
and my other server page (queue.js) has this code
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
I have also tried
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.emit('advance');
Both of those were in the other question I linked, however both of those failed. In the case of the first example, I received the error
socket.on is not a function
and on the second
socket.emit is not a function
it would seem that socket.connect worked, however, socket.on and socket.emit both failed. The idea is that queue.js will emit an event to all the clients, so they know to request the next song from the server.
As bonus points, I happen to be using passport.socketio to authenticate my users (though I don't seem to be getting the "ioAuthFail" message that would normally occur when a user attempts to connect and is not authenticated).
for what it's worth, my socket authentication code looks like
io.use(passportSocketIo.authorize({
//cookieParser:
key:'user',
secret:'secret',
store:new MongoStore({mongooseConnection:mongoose.connection}),
success:onAuthorizeSuccess,
fail:function(){console.log('ioAuthFail')}
}));
If there's a better way to advance the clients than using socket.io, i would also accept that, but for now it seems like this is the best way for me, assuming I can get this working.
EDIT
as mentioned through comments, changing my code to
var io = require('socket.io-client');
socket = io.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
socket.emit('advance');
doesn't break it, but it doesn't work, either.

Meteor client disconnected event on server

Simple question, maybe simple answer: how do I know on the server that a certain client has disconnected? Basic use case: the serve would need to know if a player has dropped the connection.
In the publish function, you can watch socket close event as follows.
this.session.socket.on "close", -> # do your thing
Meteor.publish("yourPublishFunction", function()
{
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function()
{
console.log(id); // called once the user disconnects
}, function(e){console.log(e)}));
return YourCollection.find({});
});
I've created a pretty comprehensive package to keep track of all logged-in sessions from every user, as well as their IP addresses and activity:
https://github.com/mizzao/meteor-user-status
To watch for disconnects, you can just do the following, which catches both logouts and browser closes:
UserStatus.on "sessionLogout", (userId, sessionId) ->
console.log(userId + " with session " + sessionId + " logged out")
You can also check out the code and do something similar for yourself.
Maybe (in the server code)
Meteor.default_server.sessions.length
or
Meteor.default_server.stream_server.open_sockets.length
you can do one thing make a event on server and call it from browser with ajax which call after some small time interval settimeinterval using with session values into header and if server din`t get request from user it means he dropped connection

Categories