PHP前端开发

html5新技术socket.io实现聊天室的方法

百变鹏仔 2个月前 (10-18) #H5教程
文章标签 新技术

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>1</title>    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">    <style>        .user{            color:lightskyblue;            cursor: pointer;        }    </style></head><body><div>    <div>        <div>            <div class="panel panel-default">                <div>                    <h4>欢迎来老王聊天室</h4>                </div>                <div>                    <ul id="messageUl">                    </ul>                </div>                <div>                    <div>                        <div>                            <input id="txtMsg" type="text" onkeydown="handleKeyDown(event)">                        </div>                        <div>                            <button class="btn btn-default" onclick="send()">发送                                <span class="glyphicon glyphicon-send"></span>                            </button>                        </div>                    </div>                </div>            </div>        </div>        <div>            <div class="panel panel-default">                <div>                    <h4>在线用户</h4>                </div>                <div>                    <ul id="userUl"></ul>                </div>                <div>                    <h4 id="onlineUsers">在线人数 0</h4>                </div>            </div>        </div>    </div></div><script src="/socket.io/socket.io.js"></script><script>    let txtMsg = document.querySelector(&#39;#txtMsg&#39;);    let onlineUsers = document.querySelector(&#39;#onlineUsers&#39;);    //此脚本会在window上增加一个io的属性    //http://localhost:8080/=/=空    let socket = io();    //当客户端连接服务器成功之后,向后台发送一个消息,问一下现在有哪些在线用户    socket.on(&#39;connect&#39;,function(){        socket.emit(&#39;users&#39;);    });    let messageUl = document.querySelector(&#39;#messageUl&#39;);    let userUl = document.querySelector(&#39;#userUl&#39;);    //监听服务器发过来的消息    socket.on(&#39;message&#39;,function(msgObj){        let li = document.createElement(&#39;li&#39;);        li.className = &#39;list-group-item&#39;;        li.innerHTML = `${msgObj.username}:${msgObj.content} <span>${new Date(msgObj.createAt).toLocaleString()}</span>`;        messageUl.appendChild(li);    });    socket.on(&#39;userList&#39;,function(userList){        userUl.innerHTML =  userList.map(item=>(            `<li>${item}</li>`        )).join(&#39;&#39;);        countUser();    });    socket.on(&#39;user-added&#39;,function(username){        let li = document.createElement(&#39;li&#39;);        li.className = &#39;list-group-item&#39;;        li.innerHTML = `<span>${username}</span>`;        userUl.appendChild(li);        countUser();    });    function countUser(){        onlineUsers.innerHTML = `在线人数 ${userUl.children.length}`;    }    //发送事件    function send(){        let content = txtMsg.value;//先拿到聊天的内容        socket.send(content);        txtMsg.value = &#39;&#39;;    }    function handleKeyDown(event){        if(event.keyCode == 13)            send();    }    //给父级绑定点击事件 事件委托    //要判断点的是span而非别的元素    userUl.addEventListener(&#39;click&#39;,function(event){        //如果事件源的类名是user的话        if(event.target.className == &#39;user&#39;){            let username = event.target.innerHTML;            txtMsg.value = `@${username} `;        }    })</script></body></html><!--npm i express socket.io -S -->

后台node

let express = require(&#39;express&#39;);let path = require(&#39;path&#39;);let app = express();app.get(&#39;/&#39;,function(req,res){    res.sendFile(path.resolve(&#39;index.html&#39;));});let server = require(&#39;http&#39;).createServer(app);//socket.io是依赖http服务器let io = require(&#39;socket.io&#39;)(server);//声明一个对象,保存所有的客户端用户名和它们的socket对应关系let clients = {};//监听客户端的连接,当连接到来的时候执行此回调函数io.on(&#39;connection&#39;,function(socket){    //在函数的内部声明一个变量,叫username    let username;    //监听客户端的发过来的消息,当消息发过来的时候执行回调函数    socket.on(&#39;message&#39;,function(data){        if(username){            //判断是公聊还是私聊            let reg = /@([^ ]+) (.+)/;            let result = data.match(reg);            if(result){//如果result有值则匹配上了                //此处是私聊                let toUser = result[1];                let content = result[2];                clients[toUser] && clients[toUser].send({                    username,                    content,                    createAt:new Date()                });            }else{//没匹配上                //正常发言,向所有的客户端进行广播                io.emit(&#39;message&#39;,{                    username,content:data,createAt:new Date()                });            }        }else{            username = data;//把这个消息当成用户名            //关联起来            clients[username]= socket;            //向所有的客户端广播说有新的用户加入聊天室            io.emit(&#39;message&#39;,{                username:&#39;系统&#39;,content:`欢迎 ${username} 加入聊天室`,createAt:new Date()            });            //事件的名字可以自定义            io.emit(&#39;user-added&#39;,username);        }    });    //监听客户端发过来的请求,把用户数组返回    socket.on(&#39;users&#39;,function(){        let userList = Object.keys(clients);        socket.emit(&#39;userList&#39;,userList);    });});server.listen(8080);/** * 1.实现匿名聊天 *   1. 在客户端里连接上服务器 *   2. 给发送按钮绑定点击事件,当点击此按钮的时候先获取文本框的内容,把文本框的内容发送到后台 *   3. 后台服务器把此消息广播给所有的客户端。 *   4. 所有的客户端收到消息后把此消息在ul列表里显示出来 * 2.实现具名聊天 *   1. 当此用户第一次向服务器发消息的时候 *   2. 服务器会判断此客户端的用户名是否设置过,如果没设置的话就把这个消息当成用户名,以后再发消息的话都会以这个作为用户名,如果设置过了就是正常发言 * 3. 私聊 *   1. 点击某个在线用户,点击后会在输入框里出现  @xxx yyy *   2. 服务收到私聊的请求后会找到xxx对应的客户端向他单个发消息 *   3 **/