Skip to content

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

Closed
@Joris63

Description

@Joris63

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    invalidThis doesn't seem right

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions