2016.4.5_基于nodejs的聊天室【笔记】

1.下载安装nodeJs到一个目录。装好后文件夹下会包括一个node_modules文件夹,一个node.exe文件还有一些其他文件。(懒得重装,可能就是下图选中的那些文件)

每一个chatdemo文件夹都是一个工程,里面包含了js前端、后端文件。

2.server.js文件是服务端js,启动工程就是从它开始。

3.启动工程:

找到nodejs安装目录里的Node.js command prompt,长得和cmd一样。

打开D盘:【d:回车】

打开D盘下chatdemo4文件夹:【cd chatdemo4】

启动js文件:【node server.js】

3.浏览器输入localhost:4000就能看到效果。

4.代码:

server.js

//服务器及页面部分
var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server), 
    users=[];//保存所有在线用户的昵称

    app.use('/', express.static(__dirname + '/www'));
    server.listen(4000);

//socket部分
io.on('connection', function(socket) {
    //昵称设置&初始登录
    socket.on('login', function(nickname) {
        var uservalue;
        var all='';
         if (users.indexOf(nickname) > -1) {
             socket.emit('nickExisted');
         } else {
 
             socket.userIndex = users.length; 
             socket.nickname = nickname;
             users.push(nickname);

             for (var i =0; i<users.length; i++) {
                uservalue = users[i];
                all=all+uservalue+',';  
            }
             all= all.slice(0,-1);

             socket.emit('loginSuccess');
             io.sockets.emit('system', nickname, users.length, all,'login');
         
         }; 
    
     });


    //断开连接的事件
    socket.on('disconnect', function() {
        var uservalue;
        var all='';
        //将断开连接的用户从users中删除
        users.splice(socket.userIndex, 1);

        for (var i =0; i<users.length; i++) {
                uservalue = users[i];
                all=all+uservalue+',';  
            }
             all= all.slice(0,-1); 
             
        //通知除自己以外的所有人
      socket.broadcast.emit('system', socket.nickname, users.length,all,'logout');
        //io.sockets.emit('system', nickname, users.length, all,'login');
    }); 

    //接收新消息
    socket.on('postMsg', function(msg,color) {
        //将消息发送到除自己外的所有用户
        socket.broadcast.emit('newMsg', socket.nickname, msg,color); 
    });

    //接收用户发来的图片
    socket.on('img', function(imgData) {
        //通过一个newImg事件分发到除自己外的每个用户
         socket.broadcast.emit('newImg', socket.nickname, imgData);
    });
 
  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.nickname
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.nickname
    });
  });



});

 package.json

{
    "name": "hichat",
    "description": "a realtime chat web application",
    "version": "0.4.0",
    "main": "server.js",
    "dependencies": {
        "express": "3.4.x",
        "socket.io": "0.9.x"
    },
    "engines": {
        "node": "0.10.x",
        "npm": "1.2.x"
    }
}

 

index.html

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="author" content="Wayou">
        <meta name="description" content="hichat | a simple chat application built with node.js and websocket">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>hichat</title>
        <link rel="stylesheet" href="styles/main.css">
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
        <link rel="icon" href="favicon.ico" type="image/x-icon"> 
    </head>
    <body onclick=test()>
        <div class="wrapper">
            <div class="banner">
                <div id="ul">Welcome to Chat Room  (•̀ᴗ•́)و ̑</div>
                <span id="status"></span>
            </div>
            <div id="historyMsg">
            </div>
            <div class="controls" >
                <div class="items">
                    <input id="colorStyle" type="color" />
                    <input id="emoji" class="Btn" type="button" value="emoji" title="emoji" />
                    <label for="sendImage" class="imageLable">
                        <input id="imageBtn" class="Btn" type="button" value="image"  />
                        <input id="sendImage" type="file" value="image"/>
                    </label>
                    <input id="clearBtn" class="Btn" type="button" value="clear" title="clear screen" />
                </div>
                <textarea  id="messageInput" placeHolder="Enter to Send"></textarea> 
                <div id="emojiWrapper">
                </div>
            </div>
        </div>
        <div id="loginWrapper">
            <p id="info">connecting to server...</p>
            <div id="nickWrapper">
                <input type="text" placeHolder="" id="nicknameInput" />    
            </div>
        </div>
        <script src="/socket.io/socket.io.js"></script>
        <script src="scripts/hichat.js"></script>
        
    </body>
</html>

 

Hichat.js

window.onload = function() {
    //初始化程序
    var hichat = new HiChat();
    hichat.init();
};

    var step=0;
    var _title1=document.title;
    var _title2='New Message';
    var flag=0;
    for(var i=0;_title2.length<=_title1.length-1;i++) {_title2+='.';}
    function flash_title()
    {
        if(flag==0){ 
          step++;
          if (step==3) {step=1;}
          if (step==1) {document.title=_title2;}
          if (step==2) {document.title=_title1;}
          setTimeout("flash_title()",500);
        }
    }

    function test()
    {
        flag=1;
        document.title = 'hichat | ' + document.getElementById('nicknameInput').value;
    } 
       
//定义我们的hichat类
var HiChat = function() {
    this.socket = null;
};

//向原型添加业务方法
HiChat.prototype = {
    init: function() {//此方法初始化程序
        var that = this;
        //建立到服务器的socket连接
        this.socket = io.connect();
        //监听socket的connect事件,此事件表示连接已经建立
        this.socket.on('connect', function() {
            //连接到服务器后,显示昵称输入框
            document.getElementById('info').textContent = 'whats your nickname';
            document.getElementById('nickWrapper').style.display = 'block';
            document.getElementById('nicknameInput').focus();
        });
 
        document.getElementById('nicknameInput').addEventListener('keyup', function(e) {
              if (e.keyCode == 13) {
                  var nickName = document.getElementById('nicknameInput').value;
                  if (nickName.trim().length != 0) {
                      that.socket.emit('login', nickName);
                  } else {
                    //否则输入框获得焦点
                    document.getElementById('nicknameInput').focus();
                  };
              };
          }, false);

        this.socket.on('nickExisted', function() {
             document.getElementById('info').textContent = 'nickname has been taken, choose another pls'; 
             //显示昵称被占用的提示
         });
 
        this.socket.on('loginSuccess', function() {
             document.title = 'hichat | ' + document.getElementById('nicknameInput').value;
             document.getElementById('loginWrapper').style.display = 'none';//隐藏遮罩层显聊天界面
             document.getElementById('messageInput').focus();//让消息输入框获得焦点
         }); 

        this.socket.on('system', function(nickName, userCount, all, type) {
            var msg = '【' + nickName + '】' + (type == 'login' ? ' Joined' : ' left');
            //指定系统消息显示为红色
            that._displayNewMsg('system', msg, 'red'); 
           
            //将在线人数显示到页面顶部
            document.getElementById('status').textContent = userCount + (userCount > 1 ? ' users' : ' user') + ' online : ' + all + '.';
        });
 
          document.getElementById('messageInput').addEventListener('keyup', function(e) {
              var messageInput = document.getElementById('messageInput'),
                  msg = messageInput.value,
                  color = document.getElementById('colorStyle').value;

                flag=0;
                document.title = 'hichat | ' + document.getElementById('nicknameInput').value;

              if (e.keyCode == 13 && msg.trim().length != 0) {
                  messageInput.value = '';
                  that.socket.emit('postMsg', msg, color);
                  that._displayNewMsg('me', msg, color);
              };
          }, false); 
 
             //接收后台消息 
            this.socket.on('newMsg', function(user, msg, color) {
                that._displayNewMsg(user, msg, color);  
                flash_title();
             });
 
          document.getElementById('sendImage').addEventListener('change', function() {
            //检查是否有文件被选中
             if (this.files.length != 0) {
                //获取文件并用FileReader进行读取
                 var file = this.files[0],
                     reader = new FileReader();
                 if (!reader) {
                     that._displayNewMsg('system', '!your browser doesn\'t support fileReader', 'red');
                     this.value = '';
                     return;
                 };
                 reader.onload = function(e) {
                    //读取成功,显示到页面并发送到服务器
                     this.value = '';
                     that.socket.emit('img', e.target.result);
                     that._displayImage('me', e.target.result);
                 };
                 reader.readAsDataURL(file);
             };
         }, false);

          this.socket.on('newImg', function(user,img,color) {
          that._displayImage(user,img,color);
        });

          this._initialEmoji();
         document.getElementById('emoji').addEventListener('click', function(e) {
             var emojiwrapper = document.getElementById('emojiWrapper');
             emojiwrapper.style.display = 'block';
             e.stopPropagation();
         }, false);

         document.body.addEventListener('click', function(e) {
             var emojiwrapper = document.getElementById('emojiWrapper');
             if (e.target != emojiwrapper) {
                 emojiwrapper.style.display = 'none';
         };
         });

        document.getElementById('emojiWrapper').addEventListener('click', function(e) {
        //获取被点击的表情
        var target = e.target;
        if (target.nodeName.toLowerCase() == 'img') {
            var messageInput = document.getElementById('messageInput');
            messageInput.focus();
            messageInput.value = messageInput.value + '[emoji:' + target.title + ']';
            };
        }, false);

        document.getElementById('clearBtn').addEventListener('click', function(e) {
          document.getElementById('historyMsg').innerHTML="" ;
        }, false);


},

    _displayNewMsg: function(user, msg, color) { 
         var container = document.getElementById('historyMsg'),
         msgToDisplay = document.createElement('p'),
         date = new Date().toTimeString().substr(0, 8),
         //将消息中的表情转换为图片
         msg = this._showEmoji(msg);
         msgToDisplay.style.color = color; 
         if (user == 'system'){

            msgToDisplay.style.textAlign = 'center'; 
            msgToDisplay.style.clear = 'both'; 
            user="----System Message : ";
            msgToDisplay.innerHTML = user + msg + ' at ' + date + ' ----' ;

            }else if(user == 'me'){ 

            user="Me"; 
            
            msgToDisplay.style.float = 'right'; 
            msgToDisplay.style.textAlign = 'right'; 
            msgToDisplay.style.width= '600px';
            msgToDisplay.style.wordWrap = 'break-word';
            msgToDisplay.style.wordBreak = 'normal'; 
            msgToDisplay.innerHTML = '<span class="me">' + user + ' </span>' + '<span class="timespan">(' + date + ') </span>' +  '<br>'+ msg;

            }else{

            msgToDisplay.style.float = 'left'; 
            msgToDisplay.style.width= '600px';
            msgToDisplay.style.wordWrap = 'break-word';
            msgToDisplay.style.wordBreak = 'normal'; 
            msgToDisplay.innerHTML = '<span class="other">' + user + ' </span>' + '<span class="timespan">(' + date + ')</span>' +  '<br>'+ msg;

            }
         
         container.appendChild(msgToDisplay);
         container.scrollTop = container.scrollHeight;
    },

    _displayImage: function(user, imgData, color) {
        var container = document.getElementById('historyMsg'),
        msgToDisplay = document.createElement('p'),
        date = new Date().toTimeString().substr(0, 8);
        msgToDisplay.style.color = color || '#000';
        if (user == 'me')
        { 
            user="Me";  
            msgToDisplay.style.float = 'right';  
            msgToDisplay.style.textAlign = 'right'; 
            msgToDisplay.style.width= '600px';
            msgToDisplay.innerHTML = '<span class="me">' + user + ' </span>' + '<span class="timespan">(' + date + '): </span> <br/>' + '<a href="' + imgData + '" target="_blank"><img src="' + imgData + '"/></a>';
        }else{
            msgToDisplay.innerHTML = user + '<span class="timespan">(' + date + '): </span> <br/>' + '<a href="' + imgData + '" target="_blank"><img src="' + imgData + '"/></a>';
        }
        container.appendChild(msgToDisplay);
        container.scrollTop = container.scrollHeight;
    },

    _initialEmoji: function() {
        var emojiContainer = document.getElementById('emojiWrapper'),
            docFragment = document.createDocumentFragment();
        for (var i = 20; i > 0; i--) {
            var emojiItem = document.createElement('img'); 
            emojiItem.src = '../content/emoji/' + i + '.png';
            emojiItem.title = i;
            docFragment.appendChild(emojiItem);
        };
        emojiContainer.appendChild(docFragment);
    },

    _showEmoji: function(msg) {
        var match, result = msg,
        reg = /\[emoji:\d+\]/g,
        emojiIndex,
        totalEmojiNum = document.getElementById('emojiWrapper').children.length;
        while (match = reg.exec(msg)) {
            emojiIndex = match[0].slice(7, -1);
        if (emojiIndex > totalEmojiNum) {
            result = result.replace(match[0], '[X]');
        } else {
            result = result.replace(match[0], '<img class="emoji" src="../content/emoji/' + emojiIndex + '.png" />');
        };
    };
    return result;
    }

};

 

main.css

html, body {
    margin: 0;
    background-color: #efefef;
    font-family: sans-serif;
    overflow-y: hidden; 
}
html, input {
    font: arial,helvetica,sans-serif;
}
.wrapper {
    width: 1200px;
    height: 700px;
    padding: 5px;
    margin: 0 auto;
    background-color: #ddd;
}
#nicknameInput ,#loginBtn ,#info{
    font-size: 250%;  
    text-align:center;
}
#loginWrapper {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(5, 5, 5, .9);
    text-align: center; 
    color: #fff;
    display: block;
    padding-top: 200px;
}
#ul {
     font-size: 150%;
     padding: 0 0 0 20px ;
}
#status { 
     padding: 0 0 0 20px ; 
     color: #A1A1A1;
}
#nickWrapper {
    display: none; 
}
.banner {
    height: 60px;
    width: 100%;  
}
.banner p {
    float: right;
    display: inline-block; 
}
.controls {
    height: 100px;
    margin: 5px 0px;
    position: relative;
}
#historyMsg {
    height: 480px;
    background-color: #fff;
    overflow: auto;
    padding: 0 15px 0 15px;  
    margin:   0 15px 0 15px;
    border-radius: 20px;
} 
.mydiv{ 
   text-align: center; 
}
#historyMsg img {
    max-width: 30%;
}
.timespan {
    color: #ddd; 
}
.me {
    color: #050505;  
    font-weight: bold; 
}
.other {
    color: #050505;
}
.items {
    height: 30px; 
    overflow:hidden;   
    padding-left: 15px; 

}
#colorStyle {
    width: 50px;
    border: none;
    padding: 0;
    height: 26px;  
    margin: 0 10px; 
} 
.Btn{ 
    width: 60px; 
    height: 26px; 
    vertical-align: middle;
    margin:0 5px 15px 0;   
    display: inline-block;  
    cursor: pointer;
    border: 1px solid #BBB;
    overflow: visible;
    font: bold 13px arial,helvetica,sans-serif;
    text-decoration: none;
    white-space: nowrap;
    color: #555;
    background-color: #DDD;
    background-image: -moz-linear-gradient(center top , #FFF, rgba(255, 255, 255, 0)), url("data:image/png;base64,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");
    transition: background-color 0.2s ease-out 0s;
    background-clip: padding-box;
    border-radius: 3px;
    box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.3), 0px 2px 2px -1px rgba(0, 0, 0, 0.5), 0px 1px 0px rgba(255, 255, 255, 0.3) inset;
    text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.9);
} 
.Btn:hover {
    background-color: #EEE;
    color: #555;
}
/*custom the file input*/

.imageLable {
    position: relative;
}
#sendImage { 
    position: absolute;
    width: 52px;
    left: 0;
    opacity: 0;
    overflow: hidden; 
}
/*end custom file input*/

#messageInput { 
    height: 50px;
    max-height: 60px;
    width: 1150px;;
    padding: 8px;   
    border-radius: 10px;
    resize: none;  
    margin: 0 15px 0 15px;
    font: arial,helvetica,sans-serif;
} 
#emojiWrapper {
    display: none;
    width: 500px;
    bottom: 105px;
    position: absolute;
    background-color: #aaa;
    box-shadow: 0 0 10px #555;
}
#emojiWrapper img {
    margin: 2px;
    padding: 2px;
    width: 25px;
    height: 25px;
}
#emojiWrapper img:hover {
    background-color: blue;
}

footer {
    text-align: center;
}

 

参考:

http://www.cnblogs.com/Wayou/p/hichat_built_with_nodejs_socket.html

http://www.tuicool.com/articles/rieI7v

https://www.zybuluo.com/bornkiller/note/6163

http://www.plhwin.com/2014/05/28/nodejs-socketio/

posted @ 2016-04-05 10:03  fieldcatalog  阅读(508)  评论(0编辑  收藏  举报