Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client not receiving Server emit when sending to specific room (Angular) #3673

Closed
Joris63 opened this issue Nov 5, 2020 · 5 comments
Closed
Labels
invalid This doesn't seem right

Comments

@Joris63
Copy link

Joris63 commented Nov 5, 2020

So I am trying to emit a User list to the room after someone joins the room by using the io.to(room.id).emit() function but the client doesn't seem to receive anything.

My 3 main files in question are:

Lobbies.component.ts

constructor(private socketService: SocketService, private accountService: AccountService) { }

  ngOnInit(): void {
    this.initIoConnection();

    this.accountService.GetUserbyID(this.accountService.GetUserID()).subscribe((data: User) => {
      this.user = data;
    })

  }

  //create lobby method which emits to the socket service 
  //while sending the user and the given lobby name
  CreateLobby(){
      this.socketService.emit('create', {
        user: this.user,
        name: this.lobbyName
      });
      this.lobbyName = "";
      this.RefreshRooms()
  }

  private initIoConnection(): void {
    //these methods receive the data from the socket service when ever they get a response
    this.socketService.listen('getRooms')
      .subscribe((data: any) => {
        this.lobbyList = data;
      });

    this.socketService.listen('join')
      .subscribe((data: any) =>{
        this.inWaitingRoom = data.joinedLobby;
        //emit to getUsers to retrieve the user list every time a user joins the lobby
        this.socketService.emit('getUsers', data.room);
      })

    this.socketService.listen('getUsers')
      .subscribe((data: any) => {
        this.userList = data;
      })
  }

  //this method allows a user to join a lobby
  JoinLobby(data){
    this.socketService.emit('join', {
      user: this.user,
      room: data
    });
  }

Socket.service.ts

constructor(){
        //initialize the connection
        this.socket = socketIo(environment.serverUrl)
    }   
    
    socket: any;

    //this method listens to the server emits and returns the info to the component
    listen(eventName: string): Observable<any>{
        return new Observable((subscriber) => {
            this.socket.on(eventName, (data) => {
                //when this method gets called from the server it'll send the data to the component
                console.group();
                    console.log('----- SOCKET INBOUND -----');
                    console.log('Action: ', eventName);
                    console.log('Payload: ', data);
                console.groupEnd();
                subscriber.next(data);
            });
            return () => this.socket.off(eventName);
        });
    }
    
    //this method emits data to the server and activates the socket.on() methods in the server
    emit(eventName: string, data?: any){
        console.group();
            console.log('----- SOCKET OUTBAND -----');
            console.log('Action: ', eventName);
            console.log('Payload: ', data);
        console.groupEnd();

        this.socket.emit(eventName, data);
    }

Server.js

var express = require('express');
var app = express();
var path = require('path');
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
const uuid = require('uuid/v1');

app.use(express.static(path.join(__dirname, 'public')));

//list of all rooms made
const Rooms = [];

const joinRoom = (socket, user, room) =>{
    var isInList = false;
    var joinedLobby = false;
    //retrieve correct room using the given id
    var result = Rooms.find(r => r.id == room.id);
    //search through the room's users to find if user has already joined the room
    for (var i = 0, len = result.users.length; i < len; i++) {
        if(result.users[i].id == user.id){
            isInList = true;
        }
    }
    //make the user join if he isn't found in the list
    if(isInList == false){
        result.users.push(user);
        socket.join(room.id);
        console.log(user.username, "Joined", room.name);
        joinedLobby = true;
    }
    //return boolean
    return joinedLobby;
}

io.on('connection', (socket) => {
    socket.id = uuid();
    console.log("A new user has connected!");

    socket.on('create', (data) =>{
        //create the room
        var room = {
            id: uuid(),
            name: data.name,
            users: [],
            started: false,
        };
        //create the user and give him host role
        data.user['role'] = "Host";
        //add the room to the list
        Rooms.push(room);
        var boolean = joinRoom(socket, data.user, room);
        //create an object to return all properties
        var result = {
            joinedLobby: boolean,
            room: room
        }
        socket.emit('join', result); 
    });

    socket.on('join', (data) => {
        //give the user the client role
        data.user['role'] = "Client";
        var boolean = joinRoom(socket, data.user, data.room);
        var result = {
            joinedLobby: boolean,
            room: data.room
        }
        socket.emit('join', result);
    });
    
    socket.on('getRooms', async () => {
        //make a list and put all the rooms which haven't started yet
        const allOpenRooms = [];
        for (var i = 0, len = Rooms.length; i < len; i++) {
            if(!Rooms[i].started){
                allOpenRooms.push(Rooms[i]);
            }
        }
        socket.emit('getRooms', allOpenRooms);
    });

    socket.on('getUsers', (data) => {
        //make a list and put all the users from the room in them
        const allUsers = [];
        var room = Rooms.find(r => r.id == data.id);
        for(var i = 0, len = room.users.length; i < len; i ++) {
            allUsers.push(room.users[i]);
        }
        //I want to send the lsit of users to all the people in the lobby
        //upon someone joining but the client is not getting a response

        //It does seem to work with socket.emit but then every room gets the same list
        //and that is not what i want to happen
        io.to(room.id).emit('getUsers', allUsers);
    });

    socket.on('disconnect', () => {
        console.log('User disconnected.');
    });

});

server.listen(port, function () {
    console.log(`listening on :${port}`);
});

With socket.emit() it seems to display the user list fine but it is not what i need as it dispays it for everyone even though they are in different lobbies.

I hope someone can help me with this issue. I am very desperate for answers as i've been struggling with it for days.

Thanks for your time!

@yanush
Copy link

yanush commented Nov 12, 2020

Having the same issue after migrating from v2 to v3.

Env:
Server: Node 14.13.0
Client: React Native 0.63.3
socket.io: 3.0.1
socket.io-redis: 5.4.0
socket.io-client 3.0.1

Any solutions?

@yanush
Copy link

yanush commented Nov 14, 2020

Upgrading to socket.io-redis 6.0.1 seems to solve my issue

@Joris63
Copy link
Author

Joris63 commented Nov 17, 2020

For me, the problem was that I changed the socket.id to my own given which apparently makes the socket unable to join the room.

@darrachequesne
Copy link
Member

darrachequesne commented Oct 14, 2022

For future readers:

The culprit here is calling socket.id = uuid();, as the socket ID is used internally and can only be changed in a middleware (not in the "connection" handler). Editing the socket.id or calling socket.leave(socket.id); will indeed have unexpected consequences.

Please reopen if needed.

PS: that being said, I think the library should prevent this from happening. Open to suggestions on this!

@BroManDudeGuyPhD
Copy link

For future readers:

The culprit here is calling socket.id = uuid();, as the socket ID is used internally and can only be changed in a middleware (not in the "connection" handler). Editing the socket.id or calling socket.leave(socket.id); will indeed have unexpected consequences.

Please reopen if needed.

PS: that being said, I think the library should prevent this from happening. Open to suggestions on this!

THANK YOU!
I was losing my mind on this, removing the randomization fixed my issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

4 participants