node.js和socket.io纯js实现的即时通讯实例分享

在这个例子中,其实node.js并没有真正起到服务器的作用,因为我们这里可以直接运行client.html文件,而不用输入url请求,当 然,要想输入url请求页面内容还需要加入请求静态文件的代码。这个实例中node.js最重要的作用就是将服务端迁移到了js,实现了客户端和服务端语 言上的统一,我们只要在浏览器上同时运行两个client.html客户端页面,即可进行简单的即是通讯了,socket.io才是我们真正用来实现即时 通讯的消息的收发。

var server = http.createServer(callback);//开启http服务

var io = require("socket.io").listen(server);//socketio来监听http服务器

接下来直接上客户端代码client.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>socketIO - Simple chat</title>
        <script src="./socketio.js"></script>
        <style>
            * { font-family:tahoma; font-size:12px; padding:0px; margin:0px; }
            p { line-height:18px; }
            div { }
            .textInput{width:500px;margin: 0 auto;margin-top: 50px;}
            #content { padding:5px; background:#ddd; border-radius:5px; overflow-y: scroll;
                border:1px solid #CCC; height: 160px;width: 400px;float: left;}
            #input { border-radius:2px; border:1px solid #ccc;
                margin-top:10px; padding:5px; width:400px;  }
            #status { width:88px; display:block; float:left; margin-top:15px; }
            .onlineList {
                width: 200px;
                height: 160px;
                background-color: #ccc;
                border: 1px solid #DDD;
                margin-top: 50px;
                margin-left: 420px;
            }
            li {
                display: inline;border: 1px solid red;
            }
            .ul {
                margin-left:auto; margin-right:auto;
                width: 600px;
               
            }
        </style>
    </head>
    <script type="text/javascript">
        //window.onbeforeunload = disConnect;   
    </script>
    <body>
        <div class="ul">
            <div id="content"></div>
            <div class="onlineList">
                当前在线:
                <div id="list">
                    
                </div>
            </div>
            
        </div>


        <div class="textInput">
            <span id="status">connecting</span>
            <input type="text" id="input" value="只能选择右上列表上的姓名进行登录"/>
        </div>
         
        <script src="./jquery.js"></script>
        <script src="./client.js"></script>
    </body>
</html>

对应的client.js文件

    "use strict";

    // for better performance - to avoid searching in DOM
    var content = $('#content');
    var input = $('#input');
    var statusObj = $('#status');
    var userList = $("#list");

    // my color assigned by the server
    var myColor = false;
    // my name sent to the server
    var myName = false;
    var connection = null;
    var currentToUser = null;
    connect();
    window.onbeforeunload = beforeDisConnect;//监听浏览器关闭前的事件
    window.onunload = disConnect;//监听浏览器关闭时

    /**
     * Send mesage when user presses Enter key
     */
    input.keydown(function (e) {
        if (e.keyCode === 13) {
            var msg = $(this).val();
            if (!msg) {
                return;
            }
            if (!myName) {
                myName = msg;//定义名字
                statusObj.text(myName);
                input.val("");
                
                if (connection) {
                    connection.json.send({ logicId: "login", username: myName });
                }
                return;
            }
            var time = new Date();
            var tmpTime = time.getFullYear() + "-" + ((time.getMonth() < 9 ? "0" : "") + (time.getMonth() + 1)) + "-" + ((time.getDate() < 10 ? "0" : "") + time.getDate()) + " "
                    + ((time.getHours() < 10 ? "0" : "") + time.getHours()) + ":" + ((time.getMinutes() < 10 ? "0" : "") + time.getMinutes()) + ":" + ((time.getSeconds() < 10 ? "0" : "") + time.getSeconds());
            // send the message as an ordinary text
            msg = { "@class": "test.EntityIn", logicId: "chat", username: myName, msg: input.val(),
            to:currentToUser,time:tmpTime};
            
            //alert(typeof(object));
            connection.json.send(msg);
            $(this).val('');
            // disable the input field to make the user wait until server
            // sends back response

        }
    });



    /**
     * Add message to the chat window
     */
    function addMessage(author, message, dt) {
        content.prepend('<p><span>' + author + '</span> @ '+dt+ ': ' + message + '</p>');
    }
    
function connect() {
    // open connection
    connection = io.connect('http://127.0.0.1:1337', { 'reconnect': false });
    connection.on('connect', function (data) {
        // first we want users to enter their names
        input.removeAttr('disabled');
        statusObj.text('登录:');
        connection.send(1);
    });

    connection.on("error", function (error) {
        // just in there were some problems with conenction...
        content.html($('<p>', {
            text: 'Sorry, but there\'s some problem with your '
                + 'connection or the server is down.'
        }));
    });

    // most important part - incoming messages
    connection.on("message", function (message) {
        var logicId = message.logicId;
        if (logicId == 'conn_success') {//连接成功
            var users = message.users;
            for (var i = 0; i < users.length; i++) {
                userList.append('<a href="#" onclick="chatToSb(this.innerHTML)">'+users[i]+'</a></br>');
            }
        } else if (logicId == "chat") {
            addMessage(message.from,message.msg,message.time);
        }else if(logicId == "history"){
            var historyMsgs = message.historyMsgs;
            for(var i = 0; i < historyMsgs.length; i++){
                addMessage(historyMsgs[i].from,historyMsgs[i].msg,historyMsgs[i].time);
            }
        }

    });
}

function chatToSb(username) {
    currentToUser = username;
}

function disConnect(){
    connection.disconnect();
    //alert("断开连接");
    
}

function beforeDisConnect() {
    return "确认离开";
}

接下来就是重头戏的服务端了server.js

    "use strict";  
      
      
      
    var http = require('http');  
      
    /** 
     * Global variables 
     */  
    var history = [];  
    // list of currently connected clients (users)  
    var users = ["user1","user2"];  
    var clients = [];  
      
      
      
    /** 
     * HTTP server 
     */  
    var server = http.createServer(function (request, response) {  
        // Not important for us. We're writing socket.io server, not HTTP server  
    });  
    server.listen(1337);  
      
    /** 
     * socketio server 
     */  
    var io = require("socket.io").listen(server);  
      
    //io监听socket事件  
    io.on('connection', function (connection) {  
        console.log((new Date()) + ' Connection from origin ' + connection.id + '.');  
        var json = { logicId:"conn_success",users: users };  
        connection.json.send(json);  
        var userName = false;  
      
        console.log((new Date()) + ' Connection accepted.');  
      
        connection.on('message', function (message) {  
            console.log(message);  
            if (message.logicId == "login") {  
                clients[message.username] = connection; //将用户名与连接对应  
                connection.username = message.username;  
            }else if(message.logicId == "chat") {//用户发起会话  
                //1、查找该用户是否有历史消息  
                var toUser = message.to;//会话目标  
                var from = message.username;//会话发起人  
                if(history[toUser]&&history[toUser][from]){  
                    var historyMsgs = [];  
                    for (var i = 0; i < history[toUser][from].length; i++) {  
                        historyMsgs.push(history[toUser][from][i]);  
                    };  
                    connection.json.send({logicId:"history",historyMsgs:historyMsgs});  
                }  
                //2、检查目标用户是否在线,若在线,转发用户请求,否则,存为历史会话中  
                var objConnect = clients[toUser];  
                var chatJson = {logicId:"chat", from: from, time: message.time, msg: message.msg };  
                    connection.json.send(chatJson);  
                if (objConnect) {  
                    objConnect.json.send(chatJson);  
                } else {//存储于历史会话中  
                    if (!history[from]||!history[from][toUser]) {  
                        if (!history[from]) {  
                            history[from] = [];  
                        }  
                        history[from][toUser] = [];  
                    }  
                    history[from][toUser].push(chatJson);  
                }  
            }  
        });  
      
        // user disconnected  
        connection.on('disconnect', function (socket) {  
            console.log("关闭连接:" + socket);  
            delete clients[connection.username];//删除用户的连接  
              
      
        });  
      
    });  

这里都假设大家是在win7的环境下,并且装了node.js,方便调试的话还可以安装node-inspector调试工具,或者用 webStorm IDE,具体的可以参看我的前一篇博文,除了这三个文件当然还需要服务端和客户端的socket.io文件,node.js就是下载第三方包的方式了,客 户端的socket.io文件网上可以找到的。

接下来简单介绍一下以上代码实现的功能以及用法,打开页面后首先就是登录,由于例子比较简单,并没有单独的登录页面,直接在文本框中输入用户名,注 意(这里的用户名只能是user1或者user2,读者可以在server.js的users添加自己需要的用户名,这里其实是固定的),然后回车,就是 登录了,然后输入需要发送的信息,并且点击接受者的用户名,否则会接收者是空的,关闭页面的时候,我们会监听页面关闭事件,给服务端发送 disconnect事件,删除当前用户名的连接。根据这个流程,代码其实很简单,就不再详解了。

转载:http://blog.csdn.net/jiangcs520/article/details/11173749

posted on 2015-11-29 02:25  今天又进步了  阅读(1400)  评论(0编辑  收藏  举报

导航