I can not join two users to the same room with socket.io

1

I'm doing an app with express, mongoose, and socket.io. My intention is to make that when a user enters, he joins a room whose name is the name of the city with which he registered. The idea is that when a user A and B belong to the same city, they are linked to the same room . But I can not get it to work for me. When a user A, issues information to the room , this information does not reach user B, nor the others connected to it.

This is my server-side file:

app.js

var express = require('express');
// .. others modules here .. 

var app = express();
var server = require("http").Server(app);
var io = require("socket.io")(server);

// my custom routes
var routes = require('./routes/index');

// socket.io config
io.on('connection',function(socket){

    console.log("new user connected id socket: "+socket.id);

    // evento disparado cuando un usuario inicia sesion
    socket.on("join", function(data){
        socket.join(data);
        console.log("connected to room: "+data);
        console.log(io.nsps["/"].adapter);
    });

    //evento que recibe el nombre de la ciudad a la que emitirán datos
    socket.on("notificar",function(ciudad){
        console.log("sending data to: "+ciudad);
        io.to(ciudad).emit("recibir",{message: "new "+ciudad});
    });

});

server.listen(3000, function () {
  //console.log('Example app listening on port 3000!');
});

All client-side pages include the socket-client.js script for the connection to the server.

socket-client.js

var socket = io.connect('http://localhost:3000');

socket.on('connection', function (data) {
    console.log(data);
});

// para enviar datos a la room
$("#form-report").on('submit',function(i,e){
    // city es la ciudad que será el nombre de la room
    var city = $("#report-city").html();
    socket.emit("notificar",city);
});

// para recibir datos de la room
socket.on('recibir', function(socketData){
    alert("recibiendo datos: "+socketData);
});

The file validate-user.js is a file that captures the user and password of the login form, and validates if it exists. If so, then fire the server's join event.

validate-user.js

// usuario y contraseña desdel el formulario 
input_email = $("form#form-login input#email");
input_pass = $("form#form-login input#password");

$("#btn-login").on('click',function(i,e){
    email = input_email.val();
    pass = input_pass.val();

    // petición para validar si existe
    $.ajax({
        type: 'post',
        dataType: 'json',
        url: 'http://localhost:3000/autenticate/'+email+'/'+pass,
        success: function(data){
            if(data.exist === false){
                $("#label-email").html(data.message);
                return true;
                input_email.val("");
                input_pass.val("");
            }else{
                // SI EXISTE disparar e vento "join" del servidor
                socket.emit("join",data.data.ciudad);
                location.href = "http://localhost:3000/"+email;
            }
        },
        error: function(err){
            console.log(err);
            return false;
        }
    });

    return false;
});

The problem then is that when the two users of the same city are connected, they do not join in the same room. Here I leave some screenshoots when user A was connected and later user B.

screenshoots

User A connected User B connected

    
asked by devmingo 10.05.2016 в 08:18
source

1 answer

0

The reason you are seeing only one room is because the client is disconnected when you change the url with location.href . Socket.io creates persistent connection using websockets or long pooling so when you change pages it is lost.

You can notice the symptom if you verify the ids of your connected users, in the first photo the id is iMrhv5ovjeojs7XEAAAA . In the second there are two completely different ids iYSCz-5kxqX_kAbyAAA and zDgiEMHg-NyFqz-KAAAC the reconnection of your first client and the new one that connects.

Possible solutions there are 2

The first is to include the file socket-client.js after validating all the data and you already know in what room you are going to put it, this would be after navigating to the url http://localhost:3000/{email}

socket-client.js

var socket = io.connect('http://localhost:3000');
var cuidad;

socket.on('connection', function (data) {
    console.log(data);

    socket.emit("join", ciudad);
});

// No se incluye los datos para unirse a la room porque esta se debe obtener de otra forma

// para recibir datos de la room
socket.on('recibir', function(socketData){
    alert("recibiendo datos: "+socketData);
});

The problem with this route is that you must obtain the city data again when you change pages. You can do this by requesting it to the server by ajax, passing it in the query or saving it in the localStorage.

The second way is not to change the page or use the hash so that the page is not updated and you lose the connection

fragment of validate-user.js

// .......
$.ajax({
    type: 'post',
    dataType: 'json',
    url: 'http://localhost:3000/autenticate/'+email+'/'+pass,
    success: function(data){
        if(data.exist === false){
            $("#label-email").html(data.message);
            input_email.val("");
            input_pass.val("");
        }else{
            // SI EXISTE disparar e vento "join" del servidor
            socket.emit("join",data.data.ciudad);
            // Eliminar esta línea o usar el hash(#) como se muestra debajo
            location.href = "http://localhost:3000/#"+email;
        }
    },
    error: function(err){
        console.log(err);
    }
});
// ....

This way your page will not change and the connection will not be lost. This variant is very useful if you are doing a SPA because the url yes will change without doing a full update of the page.

    
answered by 12.05.2016 / 16:51
source