1

I’m using angular-fullstack-generator version 2.1.1

Every time the client refreshes the browser, then emits an event, it appears the functions on the server are called the ammount of times the browser has been refreshed.

The client is only emmiting the ‘send:message’ event once.

The server is receiving the ‘send:message’ event once.

The server then emits a single event: ‘messages:save’

The client receives the ‘messages:save’ event once

The amount of connected socket clients appear appropriate to the actual amount of connected clients.

I first notice the duplication on the mongoose middleware.

Both the

Messages.schema.post('save', function (doc) {
    console.log('save triggered', socket.id);
    onSave(socket, doc);
});

And the

function onSave(socket, doc, cb) {
    console.log('on save function running', socket.id);
    socket.emit('messages:save', doc);
}

Are triggered the same amount the browser has been refreshed each with the preceding and current socket.ids passed to them.

What is causing these function to be called incrementally according to the amount of browser refreshes?

Rooms.service.js

var loadChat = function() {
    roomData.currentRoom = JSON.parse(window.localStorage.getItem('currentRoom'));
    socket.socket.emit('join:room', roomData.currentRoom);
    queryChatMessages().then(function(result) {
        roomData.messages = result.messages;
        socket.syncUpdates('messages', roomData.messages);
    });
};


var send = function(user, message, room) {
    socket.socket.emit('send:message', {
        roomId: room._id,
        content: message,
        username: user.name
    });
 };

Room.controller.js

$scope.send = function() {
    roomService.send($scope.currentUser, $scope.message, $scope.roomData.currentRoom);
    $scope.message = '';
};

$scope.$on('$destroy', function () {
    socket.unsyncUpdates('messages');
});

Messages.socket.js

var Messages = require('./messages.model');
exports.register = function(socket) {
    Messages.schema.post('save', function (doc) {
        console.log('save triggered', socket.id);
        onSave(socket, doc);
    });
    Messages.schema.post('remove', function (doc) {
        onRemove(socket, doc);
    });
};

function onSave(socket, doc, cb) {
    console.log('on save function running', socket.id);
    socket.emit('messages:save', doc);
};
function onRemove(socket, doc, cb) {
    socket.emit('messages:remove', doc);
};

Socketio.js

var config = require('./environment');
var Messages = require('../api/messages/messages.model');

// When the user connects.. perform this
function onConnect(socket) {
    console.log('socket.id', socket.id);
    // When the client emits 'info', this listens and executes
    socket.on('info', function (data) {
        console.log('info event listener', data);
        console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2));
    });

socket.on('send:message', function(data) {
    console.log('send:message event listener', data);

    Messages.create(data, function(err, messages) {
        if(err) {
            console.log('some error?', err);
        } 
    });
});
    require('../api/files/files.socket').register(socket);
    require('../api/messages/messages.socket').register(socket);
    require('../api/organizations/organizations.socket').register(socket);
    require('../api/rooms/rooms.socket').register(socket);
    require('../api/tags/tags.socket').register(socket);
    require('../api/contacts/contacts.socket').register(socket);
    require('../api/thing/thing.socket').register(socket);
}

// Insert sockets below
var jwt = require('jsonwebtoken');
var Orgs = {};
var User = require('../api/user/user.model');

module.exports = function (socketio) {

    var Groups = {};
    socketio.on('connection', function(socket){
        console.log('socket.id', socket.id);
        //temp delete socket from namespace connected map
        delete socketio.sockets.connected[socket.id];

        var user;
        var org;

        var options = {
            secret: process.env.SESSION_SECRET,
            timeout: 5000 // 5 seconds to send the authentication message
        };

        var auth_timeout = setTimeout(function () {
            socket.disconnect('unauthorized');
        }, options.timeout || 5000);

        var joinGroup = function(data){
            console.log('socket.id - in joinGroup', socket.id);
            user = {
                userId: data._id,
                socketId: socket.id,
                inRooms: socket.rooms
            };
            org = {
                name: data.primary_org_id,
                id: data.primary_org_name
            };
            socket.group = org;
            socket.user = user;
            socket.join(socket.group.name, function(err) {
                if (err) {
                    console.log('Error with joining org room', err);
                } else {
                    if (!Groups[org.name]) {
                        Groups[org.name] = [];
                    }
                    Groups[org.name].push(user);
                }
                console.log('Groups', Groups);
            });
        };

        var authenticate = function (data) {
            console.log('socket.id - in authenticate', socket.id);
            clearTimeout(auth_timeout);
            jwt.verify(data.token, options.secret, options, function(err, decoded) {
                if (err){
                    socket.disconnect('unauthorized');
                }
                if (!err && decoded){
                    //restore temporarily disabled connection
                    socketio.sockets.connected[socket.id] = socket;

                    socket.decoded_token = decoded;
                    socket.connectedAt = new Date();

                    onConnect(socket);
                    joinGroup(data.user);

                    // Disconnect listener
                    socket.on('disconnect', function () {
                        console.info('SOCKET [%s] DISCONNECTED', socket.id);
                    });

                    console.info('SOCKET [%s] CONNECTED', socket.id);
                    socket.emit('authenticated');
                }
            })
        };

        socket.on('disconnect', function () {
            console.log('socket.id on disconnect', socket.id);
            if (socket.group) {
                Groups[socket.group.name].splice(Groups[socket.group.name].indexOf(socket.user), 1);
            }
            socket.disconnect();
            console.info('[%s] DISCONNECTED', socket.address);
        });

        socket.on('join:room', function(room) {
            socket.join(room._id);
            console.log(socket.rooms);
        });

        socket.on('leave:room', function(room) {
            socket.leave(room._id);
        });
        socket.on('authenticate', authenticate );
    });

};
Matthew Moran
  • 1,457
  • 12
  • 22
  • I haven't done much with sockets, but it sounds like the socket is remaining open after the refresh and a new one is created. That is what is causing it to increment. Check here for closing the connection: http://stackoverflow.com/questions/4812686/closing-websocket-correctly-html5-javascript – Ronnie Apr 13 '16 at 22:43
  • I do not understand how this can be. After a refresh, I do not see any connected sockets initially. I'm looking specifically at `socketio.server.clients`. After I call `socket.disconnect()` it is an empty object. When the client connects it is the relevant socket.id. It's only in those two functions that I see the duplication. Even though the console.log statements show that the function is being called multiple time, it only emits a single event. I would at least think that it would emit the number of events accordingly. – Matthew Moran Apr 14 '16 at 12:10

0 Answers0