baudic_j
baudic_j

Reputation: 45

JS change socket namespace from client when click on button

I'm developping simple app with nodejs and socket.io. I created two channels and I want my client connect one of channels when click on button. The problem is I don't get response from server

This is my code :

// SERVER side

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

var nameSpaceWeek = io.of('/week');
var nameSpaceDay = io.of('/day');

app.get('/', function(req, res){
res.sendfile('MDC.html');
});

io.on('connection', function(socket){
    console.log("User = " + socket.id)
});

nameSpaceDay.on('connection', function(socket){
    console.log('someone connected on namespace day');
    nameSpaceDay.emit('hiDay', 'Hello everyone on namespace day!');
});

nameSpaceWeek.on('connection', function(socket){
    console.log('someone connected on namespace week');
    nameSpaceDay.emit('hiWeek', 'Hello everyone on namespace week!');
});

http.listen(3000, function(){
    console.log('listening on localhost:3000');
});

// CLIENT SIDE

<!DOCTYPE html>
<html>
    <head><title>Hello world</title></head>
    <script src="/socket.io/socket.io.js"></script>
    <script>
    var socket = io();

    function setDay(){
        console.log("setDay");
        socket = io.connect('/day');
        console.log(socket)
    }

socket.on('hiDay',function(data){
    console.log("hiDay")
    console.log("data = ." + data + ".")
    document.getElementById('message-container').innerHTML = 'Update day'
    console.log("data = ." + data + ".")
});

function setWeek(){
    console.log("setWeek");
    socket = io.connect('/week');        
    console.log(socket)
}

socket.on('hiWeek',function(data){
    console.log("hiWeek")
    document.getElementById('message-container').innerHTML = 'Update Week'
    //document.getElementById('message-container').innerHTML = data
    console.log(data)
});

</script>
<body>
    <div id="message-container"></div>
    <div id="error-container"></div>
    <button type="button" name="button" onclick="setWeek()">Week</button>
    <button type="button" name="button" onclick="setDay()">Day</button>
</body>

In my client, I created two button and when I click on one I want change socket namespace

Upvotes: 0

Views: 882

Answers (2)

Woodsy
Woodsy

Reputation: 3377

If you create a connect(ns) function you can reconstruct the socket event listener when the namespace changes. The following should work:

        <script>
            var connect = function (ns) {
                return io.connect(ns, {
                    query: 'ns=' + ns,
                    resource: "socket.io"
                }).on('hiWeek', function (data) {
                    console.log("hiWeek")
                    document.getElementById('message-container').innerHTML = 'Update Week'
                    //document.getElementById('message-container').innerHTML = data
                    console.log(data)
                }).on('hiDay', function (data) {
                console.log("hiDay")
                console.log("data = ." + data + ".")
                document.getElementById('message-container').innerHTML = 'Update day'
                console.log("data = ." + data + ".")
            });
            }

            var socket = io();

            function setDay() {
                console.log("setDay");
                socket = connect('/day');
                console.log(socket);
            }

            function setWeek() {
                console.log("setWeek");
                socket = connect('/week');        
                console.log(socket);
            }


        </script>

Upvotes: 0

jfriend00
jfriend00

Reputation: 707318

When you call setDay() or setWeek(), you are creating a whole new socket.io connection and thus overwriting your previous socket variable. The socket.on(hiDay, ...) and socket.on('hiWeek', ...) handlers you have are ONLY on the first socket you created, not on the newly created sockets, thus you never see the messages on those.

To fix, add those message handlers only to the right socket after you've connected to that namespace.

function setWeek() {
    // close previous socket.io connection
    socket.close();

    // make new connection to new namespace
    console.log("setWeek");
    socket = io.connect('/week');        
    console.log(socket)

    // add event handler for new socket
    socket.on('hiWeek',function(data){
        console.log("hiWeek")
        document.getElementById('message-container').innerHTML = 'Update Week'
        console.log(data)
    });
}

Then, do the same thing for the setDay() function.

And, as shown here you probably want to disconnect the previous connection when changing namespaces too so you don't necessarily leave connections that you aren't using any more.


FYI, you also had a typo where this:

nameSpaceDay.emit('hiWeek', 'Hello everyone on namespace week!');

should have been this:

nameSpaceWeek.emit('hiWeek', 'Hello everyone on namespace week!');

Final, tested and working code is this:

<!DOCTYPE html>
<html>
    <head><title>Hello world</title></head>
    <script src="/socket.io/socket.io.js"></script>
    <script>
    var socket = io();

    function setDay(){
        socket.close();

        console.log("setDay");
        socket = io.connect('/day');

        socket.on('hiDay',function(data){
            console.log("hiDay")
            document.getElementById('message-container').innerHTML = 'Update day';
            console.log(data);
        });     
    }



    function setWeek() {
        // close previous socket.io connection
        socket.close();

        // make new connection to new namespace
        console.log("setWeek");
        socket = io.connect('/week');        

        // add event handler for new socket
        socket.on('hiWeek',function(data){
            console.log("hiWeek");
            document.getElementById('message-container').innerHTML = 'Update Week';
            console.log(data);
        });
    }

</script>
<body>
    <div id="message-container"></div>
    <div id="error-container"></div>
    <button type="button" name="button" onclick="setWeek()">Week</button>
    <button type="button" name="button" onclick="setDay()">Day</button>
</body>

And server code:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');

var nameSpaceWeek = io.of('/week');
var nameSpaceDay = io.of('/day');

app.get('/', function(req, res){
    res.sendFile(path.join(__dirname, 'socket-io-namespace.html'));
});

io.on('connection', function(socket){
    console.log("User = " + socket.id)
});

nameSpaceDay.on('connection', function(socket){
    console.log('someone connected on namespace day');
    nameSpaceDay.emit('hiDay', 'Hello everyone on namespace day!');
});

nameSpaceWeek.on('connection', function(socket){
    console.log('someone connected on namespace week');
    nameSpaceWeek.emit('hiWeek', 'Hello everyone on namespace week!');
});

http.listen(3000, function(){
    console.log('listening on localhost:3000');
});

Upvotes: 2

Related Questions