Socket.io断开事件触发新连接

时间:2013-12-19 14:31:41

标签: javascript html5 node.js socket.io

我正在尝试使用node和socket.io根据书中的教程构建聊天服务器和客户端。前端代码如下:

<html>
<head>
    <title>Socket.IO example application</title>
    <style type = "text/css">
    #input {
        width: 200px;
    }
    #messages {
        position: fixed;
        top: 40px;
        bottom: 8px;
        left: 8px;
        right: 8px;
        border: 1px solid #EEEEEE;
        padding: 8px;
    }
    </style>
</head>
<body>
    Your message:
    <input id = "input" type = "text" />
    <div id = "messages"></div>
    <script src = "http://localhost:4001/socket.io/socket.io.js"></script>
    <script type = "text/javascript">
    var messagesElement = document.getElementById('messages');
    var lastMessageElement = null;

    function addMessage (message) {
        var newMessageElement = document.createElement('div');
        var newMessageText = document.createTextNode(message);

        newMessageElement.appendChild(newMessageText);
        messagesElement.insertBefore(newMessageElement, lastMessageElement);
        lastMessageElement = newMessageElement;
    }

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

    socket.on('login', function() {
        var username = prompt('What username would you like to use?');
        socket.emit('login', username);
    });

    socket.on('serverMessage', function (content) {
        addMessage(content);
    });

    function sendCommand(command, args) {
        if(command === 'j') {
            socket.emit('join', args);
        } else {
            alert('unknown command: ' + command);
        }
    }

    function sendMessage(message) {
        var commandMatch = message.match(/^\/(\w*)(.*)/);
        if(commandMatch) {
            sendCommand(commandMatch[1], commandMatch[2].trim());
        } else {
            socket.emit('clientMessage', message);
        }
    }

    var inputElement = document.getElementById('input');

    inputElement.onkeydown = function(keyboardEvent) {
        if(keyboardEvent.keyCode === 13) {
            sendMessage(inputElement.value);
            inputElement.value = '';
            return false;
        } else {
            return true;
        }
    };
    </script>
</body>
</html>

后端是:

/*jslint node: true */
var httpd = require('http').createServer(handler);
var io = require('socket.io').listen(httpd);
var fs = require('fs');

function handler(req, res) {
    "use strict";
    fs.readFile(__dirname + '/index.html', function (err, data) {
        if (err) {
            res.writeHead(500);
            return res.end('Error Loading index.html');
        }

        res.writeHead(200);
        res.end(data);
    });
}

httpd.listen(4001);

io.sockets.on('connection', function (socket) {
    "use strict";
    socket.on('login', function(username) {
        socket.set('username', username, function (err) {
            if (err) {
                throw err;
            }
            socket.emit('serverMessage', 'Currently logged in as ' + username);
            socket.broadcast.emit('serverMessage', 'User ' + username + ' logged in');
        });
    });

    socket.on('clientMessage', function (content) {
        socket.emit('serverMessage', 'You said: ' + content);
        socket.get('username', function (err, username) {
            if (!username) {
                username = socket.id;
            }
            socket.get('room', function (err, room) {
                if (err) {
                    throw err;
                }
                var broadcast = socket.broadcast,
                    message = content;
                if (room) {
                    broadcast.to(room);
                }
                broadcast.emit('serverMessage', username + ' said: ' + message);
            });
        });
    });

    socket.on('join', function (room) {
        socket.get('room', function (err, oldRoom) {
            if (err) {
                throw err;
            }
            socket.set('room', room, function (err) {
                if (err) {
                    throw err;
                }
                socket.join(room);
                if (oldRoom) {
                    socket.leave(oldRoom);
                }
                socket.get('username', function (err, username) {
                    if (!username) {
                        username = socket.id;
                    }
                    socket.emit('serverMessage', 'You joined room' + room);
                });
                socket.get('username', function (err, username) {
                    if (!username) {
                        username = socket.id;
                    }
                    socket.broadcast.to(room).emit('serverMessage', 'User ' + username + ' joined this room');
                });
            });
        });
    });

    socket.on('disconnect', function() {
        socket.get('username', function (err, username) {
            if (!username) {
                username = socket.id;
            }
            socket.broadcast.emit('serverMessage', 'User ' + username + ' disconnected');
        });
    });

    socket.emit('login');
});

我面临的问题是,每当新用户登录时,所有之前的用户都会在新用户登录之前收到一条消息“User”+ randomID +“disconnected”,并且它正常运行。如果新用户在前一个用户登录后快速登录,则不会出现此问题(我猜测这与心跳有关)。我非常感谢任何帮助,找出每次新用户登录时为什么会触发此断开事件。谢谢。

2 个答案:

答案 0 :(得分:1)

javascript中的

alertprompt是阻止功能,它们会停止浏览器上的所有javascript事件。

这就是为什么socket.io中的'heart'会停止跳动。

更详细:

在每次心跳中,服务器都会向客户端发送一个数据包,以检查客户端是活还是死,如果客户端没有响应,服务器会认为它已经死了。

解决方案是用异步函数,弹出div,表单等替换prompt函数...

答案 1 :(得分:0)

我一直在复制你的代码,并在我的服务器上运行,我找不到你的问题你面临的问题,但我发现一个问题,当我取消usename输入窗口时,我的用户名是null,我发现我的用户ID是随机字符串。当我断开连接时,socket.io将会这样一个消息,

  

“用户”+ randomID +“已断开连接”