在浏览器重新加载页面之前,服务器永远不会触发socket.io连接/侦听器

时间:2014-10-19 05:16:14

标签: angularjs express socket.io

我熟悉socket.io,我遇到了一个奇怪的问题。除非客户端刷新浏览器,否则服务器永远不会从客户端接收“连接”事件。

expressjs服务器很简单:

// server_app.js  =========================

var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http)
var socketJwt = require('socketio-jwt');

app.use(express.static(__dirname + '/public'));

....

io.use(socketJwt.authorize({
    secret: 'secret',
    handshake: true
}));

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

    socket.on("user logged in" function(data) {
        console.log('user logged in');
        // Do stuff with data
    });
});

http.listen(3000, function() {
    console.log('Express app started');
});

客户端使用AngularJS:

// angular_app.js ===========================

var app = angular.module('app', ['ServiceMOdule', 'ngRoute', 'ControllerModule']);

var service_mod = angular.module('ServiceModule', []);
var controller_mod = angular.module('ControllerModule', []);

...

我的angularjs模块:

// ServiceModule.js =============================

service_mod.factory('FooService',
    function($http) {
        return {

            // Save token
            save: function(){ .... )},

            // Get token
            getToken: function(){ .... },

            // Login POST
            login: function(email, password) {
                return $http.post("/user/login", {"email": email, "password": password});
            }
        }
    }
 });


service_mod.factory('socketService',
    function($rootScope, FooService) {
        var token = FooService.getToken();
        var socket = io.connect('http://localhost:3000', {'query': 'token=' + token });

        console.log('servicesocket called');

        return {

            on: function(eventName, callback) {
                socket.on(eventName, function() {
                    var args = arguments;
                    $rootScope.$apply(function() {
                        callback.apply(socket, args);
                    });
                });
            },

            emit: function(eventName, data, callback) {

                // Print out the event name to see if this was fired!
                console.log(eventName);

                socket.emit(eventName, data, function() {
                    var args = arguments;
                    $rootScope.$apply(function() {
                        if (callback) {
                            callback.apply(socket, args);
                        }
                    });
                });
            }
         } 
});




// ControllerModule.js =====================================

controller_mod.controller('LoginCtrl', ['$scope', 'FooService', 'socketService', function($scope, FooService, socketService) {

    $scope.login = function(email, password) {
        FooService.login(email, password).success(function(data) {
            FooService.save(data['token']);
            socketService.emit('user logged in', {'token': data['token']});
        });
    }
}]);

当用户点击登录按钮时,angularjs会触发LoginCtrl.login(),保存从登录POST返回的令牌,然后继续执行emit()通知socket.io用户已登录从Firebug中的控制台输出,我可以看到打印出事件user logged in。在客户端,一切似乎都在膨胀。

问题是,服务器永远不会触发任何socket.io侦听器。 io.on('connection', function(socket){...});永远不会打印connection created。此外,尽管客户端在登录后调用user logged in,但emit()也永远不会被触发。

但是!如果我重新加载浏览器页面,connection created 打印出来,但user logged in仍未被触发,因为此时用户已登录。登录后立即浏览器刷新后,其他侦听器(此处未显示)也会触发。

为什么会发生这种情况?如何解决?

0 个答案:

没有答案