您的位置:首页 > 编程学习 > > 正文

nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)

更多 时间:2021-10-09 00:14:56 类别:编程学习 浏览量:114

nodejs实现websocket服务端

Node.js+express+socket实现在线实时多人聊天室

本文实例为大家分享了Node.js+express+socket实现在线实时多人聊天室的具体代码,供大家参考,具体内容如下

文件结构如下:

nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)

前端部分:

登录页面Login部分:

login.html

  • <!DOCTYPE html>  
    <html lang="en"> 
    
    <head>  
        <meta charset="UTF-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">  
        <meta http-equiv="X-UA-Compatible" content="ie=edge">  
        <title>login</title>  
        <link rel="stylesheet" href="css/login.css" >  
    </head> 
    
    <body>  
        <li class="login-box flex-box">  
            <!--登录标题栏-->  
            <h2 class="sign-title box-width">LOGIN</h2>  
            <!--头像栏-->  
            <li class="picture-carousel">  
                <li class="arrow left-arrow">  
                    <li class="before-arrow"></li>  
                </li>  
                <img class="p1 img-setting" src="./img/1.jpg" alt="nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)" border="0" />
    
  • login.css

  • * {  
        padding: 0;  
        margin: 0;  
        font-family: "Microsoft Yahei";  
    } 
    
    html,  
    body {  
        width: 100%;  
        height: 100%;  
        font-family: "Microsoft Yahei";  
        display: flex;  
        justify-content: center;  
        align-items: center;  
    } 
    
    body {  
        background: linear-gradient(-135deg, #51D15B, #42A855);  
        background: -moz-linear-gradient(-135deg, #51D15B, #42A855);  
        background: -webkit-linear-gradient(-135deg, #51D15B, #42A855);  
        background: -o-linear-gradient(-135deg, #51D15B, #42A855);  
    } 
    
    .flex-box {  
        display: flex;  
        justify-content: center;  
        align-items: center;  
    } 
    
    .box-width {  
        width: 80%;  
    } 
    
    
    /*最外层*/ 
    
    .login-box {  
        width: 20%;  
        min-width: 304px;  
        max-width: 404px;  
        height: 50%;  
        min-height: 368px;  
        max-height: 468px;  
        flex-direction: column;  
        box-shadow: 1px 1px 15px #7B8C99;  
        background: #fff;  
    } 
    
    
    /*LOGIN标题*/ 
    
    .sign-title {  
        color: #42A855;  
        border: 2px solid #42A855;  
        border-top: transparent;  
        border-left: transparent;  
        border-right: transparent;  
    } 
    
    
    /*图片切换*/ 
    
    .picture-carousel {  
        position: relative;  
        display: flex;  
        margin: 10%;  
    } 
    
    
    /*图片切换箭头*/ 
    
    .arrow {  
        z-index: 3;  
        position: absolute;  
        font-size: 60px;  
        height: 100%;  
        width: 30%;  
        display: flex;  
        justify-content: center;  
        align-items: center;  
        color: #ffffff;  
    } 
    
    .arrow:hover {  
        cursor: pointer;  
    } 
    
    .left-arrow {  
        left: 0;  
    } 
    
    .before-arrow {  
        width: 0px;  
        height: 0px;  
        border-width: 30px;  
        border-style: solid;  
        border-color: transparent #51D15B transparent transparent;  
    } 
    
    .right-arrow {  
        right: 0;  
    } 
    
    .after-arrow{  
         width: 0px;  
        height: 0px;  
        border-width: 30px;  
        border-style: solid;  
        border-color: transparent  transparent transparent #51D15B;   
    } 
    
    .picture-carousel img {  
        width: 80px;  
        height: 80px;  
        transition: all 0.2s linear;  
        -moz-transition: all 0.2s ease-out;  
        -webkit-transition: all 0.2s ease-out;  
        -o-transition: all 0.2s ease-out;  
    } 
    
    .img-setting {  
        margin: 0px -15px;  
    } 
    
    .p1 {  
        transform: scale(0.6);  
        z-index: 1;  
    } 
    
    .p1:hover {  
        transform: scale(0.8);  
    } 
    
    .p2 {  
        transform: scale(0.8);  
        z-index: 2;  
    } 
    
    .p2:hover {  
        transform: scale(1);  
    } 
    
    .p3 {  
        transform: scale(1);  
        z-index: 3;  
    } 
    
    .p3:hover {  
        transform: scale(1.2);  
    } 
    
    
    /*用户名*/ 
    
    .name-box {  
        display: flex;  
        justify-content: center;  
        border: 1px solid #51D15B;  
    } 
    
    .name-box .user-name {  
        width: 100%;  
        text-align: center;  
        padding: 10px;  
        outline-color: #42A855;  
        border: none;  
        font-size: 16px;  
    } 
    
    /* 登录按钮 */
    .button-box{
        display: flex;
        justify-content: center;
        margin: 10px 0 20px;
    }
    
    .button-box .login-button{
        width: 100%;
        padding: 10px 20px;
        outline:none;
        border: none;
        background: #42A855;
        color: white;
        font-size: 16px;
    }
    
    /* 错误信息 */
    .error-box{
        color: #42A855;
        border: 2px solid #42A855;
        border-top: transparent;
        border-left: transparent;
        border-right: transparent;
    }
    
    .error-box span{
        visibility: hidden;
        color: #d43f3a;
        font-size: 14px;
    }
    
  • login.js

  • // 用于存储图片顺序
    var imgArray = ['1','2','3','4','5'];
    
    // 获取箭头
    var leftArrow = document.getElementsByClassName('left-arrow')[0];
    var rightArrow = document.getElementsByClassName('right-arrow')[0];
    
    // 获取用户名
    var userName = document.getElementsByClassName('user-name')[0];
    
    // 获取登录按钮
    var loginButton = document.getElementsByClassName('login-button')[0];
    
    // 获取错误信息栏
    var errorMessage = document.getElementsByClassName('error-message')[0];
    
    // 添加左箭头监听事件
    leftArrow.addEventListener('click',function(){
        imgArray.unshift(imgArray[imgArray.length - 1]);     //  向数组的开头添加一个元素    //  
        imgArray.pop();    //  删除并返回数组的最后一个元素
        carouselImg();       //  切换图片
    });
    
    // 添加右箭头监听事件
    rightArrow.addEventListener('click',function(){
        imgArray.push(imgArray[0]);     //  把第一个元素放在最后
        imgArray.shift();           //  删除并返回数组的第一个元素
        carouselImg();           //  切换图片
    });
    
    // 切换图片
    function carouselImg(){
        for(var count = 0;count < imgArray.length;count++){
            document.getElementsByTagName('img')[count].src = './img/' + imgArray[count] + '.jpg" alt="nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)" border="0" />
    
  • index.html

  • <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>chat-room</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="./css/index.css" />
    </head>
    <body>
        <li class="chat-box">
            <!-- 聊天框头部 -->
            <li class="chat-header">
                <li class="button-box">
                    <input type="button" class="log-out" value="LOGOUT" />
                </li>
            </li>
            <!-- 聊天框主体 -->
            <li class="chat-body">
                <!-- 聊天框左侧 -->
                <li class="chat-body-left">
                    <!-- 聊天框左侧聊天内容 -->
                    <li class="chat-content"></li>
                    <!-- 聊天框左侧聊天输入框 -->
                    <li class="chat-edit">
                        <input type="text" class="edit-box" placeholder="Please Type You Message" maxlength="15"/>
                        <input type="button" class="edit-button" value="SEND" />
                    </li>
                </li>
                <!-- 聊天框右侧 -->
                <li class="chat-body-right">
                    <!-- 聊天框右侧统计人数 -->
                    <li class="online-count">Online:0</li>
                    <!-- 聊天框右侧用户名 -->
                    <li class="user-name">user-name</li>
                    <!-- 聊天框右侧头像 -->
                    <img class="user-img"  />
                </li>
            </li>
        </li>
    </body>
    </html>
    
    <script src="./js/socket.io.js"></script>
    <script src="./js/index.js"></script>
    
  • index.css

  • *{
        margin: 0;
        padding: 0;
        font-family: "Microsoft Yahei"
    }
    html,body{
        width: 100%;
        height: 100%;
    }
    
    /* 背景色 */
    body{
        display: flex;
        justify-content: center;
        align-items: center;
        background: linear-gradient(-135deg,#51D15B,#42A855);
        background: -moz-linear-gradient(-135deg,#51D15B,#42A855);
        background: -webkit-linear-gradient(-135deg,#51D15B,#42A855);
        background: -o-linear-gradient(-135deg,#51D15B,#42A855);
    }
    
    /* 最外层 */
    .chat-box{
        width: 50%;
        max-width: 720px;
        min-width: 400px;
        height: 80%;
        min-height: 530px;
        max-height: 530px;
        display: flex;
        flex-direction: column;
        background: #fff;
        box-shadow: 1px 1px 15px #333;
    }
    
    /* 头部 */
    .chat-header{
        margin: 5px;
        box-shadow: 1px 1px 15px #7B8C99;
    }
    
    .button-box{
        display: flex;
        justify-content: flex-end;
    }
    
    .log-out{
        height: 100%;
        font-size: 14px;
        font-weight: bold;
        padding: 5px 15px;
        color: #79C2EA;
        background: #fff;
        outline: none;
        border: none;
        border-radius: 15px;
        cursor: pointer;
    }
    
    /* 主体 */
    .chat-body{
        height: 90%;
        display: flex;
        flex-direction: row;
        justify-content: space-around;
        align-items: center;
        margin: 5px;
        padding: 5px;
    }
    
    /* 主体左侧 */
    .chat-body-left{
        height: 100%;
        width: 70%;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        margin: 5px;
    }
    
    /* 左侧内容 */
    .chat-content{
        box-shadow: 1px 1px 15px #7B8C99;
        height: 100%;
        margin-bottom: 5px;
        overflow: scroll;
    }
    
    /*聊天气泡*/ 
    
    .my-message-box {  
        display: flex;  
        justify-content: flex-end;  
        align-content: center;  
        margin: 5px;  
    } 
    
    .other-message-box {  
        display: flex;  
        justify-content: flex-start;  
        align-content: center;  
        margin: 5px;  
    } 
    
    .message-content {  
        display: flex;  
        justify-content: center;
        align-content: center;
        background-color: #51D15B;  
        padding:5px 10px;
        border-radius: 15px;  
        color: #fff;  
    } 
    
    .other-message-content{
        display: flex;
        justify-content: center;
        align-content: center;
        background-color: #79C2EA;
        padding: 5px 10px;
        border-radius: 15px;
        color: #fff;
    }
    
    .message-content span{
        padding:20px 0px;
    }
    
    .user-chat-img {  
        width: 50px;  
        height: 50px;  
    } 
    
    .other-message-content span{
        padding: 20px 0px;
    }
    
    .message-arrow{
        width: 0;
        height: 0;
        border-width:8px;
        border-style: solid;
        border-color: transparent transparent transparent #51D15B;
        align-self: center;
    }
    
    .other-message-arrow{
        width: 0;
        height: 0;
        border-width: 8px;
        border-style: solid;
        border-color: transparent #79C2EA transparent transparent;
        align-self: center;
    }
    
    .user-information{
        display: flex;
        flex-direction: column;
        align-content: flex-end;
    }
    .other-user-information{
        display: flex;
        flex-direction: column;
        align-content: flex-end;
    }
    
    .user-chat-name{
        color: #333;
        font-size: 16px;
        text-align: center;
    }
    
    /* 聊天输入框 */
    .chat-edit{
        margin-top: 5px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        box-shadow: 1px 1px 15px #7B8C99;
        overflow: hidden;
    }
    
    /* 聊天输入框输入区域 */
    .edit-box{
        width: 80%;
        height: 100%;
        margin: 5px;
        border: none;
        outline: none;
    }
    
    /* 聊天输入框按钮 */
    .edit-button{
        height: 100%;
        padding: 5px 15px;
        background: #fff;
        color: #79C2EA;
        outline: none;
        border: none;
        border-radius: 15px;
        cursor: pointer;
        font-size: 14px;
        font-weight: bold;
    }
    
    /* 主体右侧 */
    .chat-body-right{
        height: 100%;
        width: 30%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        margin: 5px;
        box-shadow: 1px 1px 15px #7B8C99;
    }
    
    .user-name{
        margin: 15px;
        font-size: 18px;
        font-weight: bold;
        color: #79C2EA;
    }
    
    .user-img{
        width: 100px;
        height: 100px;
        margin: 5px;
    }
    
    .online-count{
        font-size: 18px;
        font-weight: bold;
        color: #79C2EA;
    }
    
    /* 兼容小屏幕 */
    @media screen and (max-width:420px){
        .chat-box{
            width: 50%;
            max-width: 720px;
            min-width: 300px;
            height: 80%;
            min-height: 530px;
            max-height: 530px;
        }
        .chat-body-left{
            height: 100%;
            width: 100%;
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            margin: 5px;
        }
        .chat-body-right{
            display: none;
        }
    }
    
  • index.js

  • // 获取url里面的内容
    var url = decodeURI(location.href).split('?')[1].split('&'); //..数组第一个元素为图片路径,第二个元素为用户名
    
    console.log(url);
    
    // 获取聊天内容框
    var chatContent = document.getElementsByClassName('chat-content')[0];
    
    // 获取聊天输入框
    var editBox =  document.getElementsByClassName('edit-box')[0];
    
    // 获取聊天输入框发送按钮
    var editButton = document.getElementsByClassName('edit-button')[0];
    
    // 获取用户名栏
    var userName = document.getElementsByClassName('user-name')[0];
    
    // 获取在线人数栏
    var onlineCount = document.getElementsByClassName('online-count')[0];
    
    // 登录页面的名称放在右侧
    userName.innerHTML = url[1].split('=')[1];
    var userImg = document.getElementsByClassName('user-img')[0];
    
    // 把登录页面的头像放在右侧
    userImg.src = `./img/${url[0].split('=')[1]}`;
    var logOut = document.getElementsByClassName('log-out')[0];
    
    // 发送按钮绑定点击事件
    editButton.addEventListener('click',sendMessage);
    
    // 登出按钮绑定点击事件
    logOut.addEventListener('click',closePage);
    
    // 绑定Enter键和发送事件
    document.onkeydown = function(event){
        var e = event || window.event;
        if(e && e.keyCode === 13){
            if(editBox.value !== ''){
                editButton.click();
            }
        }
    };
    
    // 关闭页面
    function closePage(){
        var userAgent = navigator.userAgent;
        console.log(`userAgent=${userAgent}`);
    
        if(userAgent.indexOf('Firefox') != -1 || userAgent.indexOf("Chrome") != -1){  //..如果是火狐或者谷歌
            window.location.href = "about:blank";
        }else{
            window.opener = null;
            window.open("","_self");
            window.close();
        }
    }
    
    // socket部分
    var socket = io();
    
    // 当接收到消息并且不是本机时生成聊天气泡
    socket.on('message',function(information){
        console.log('收到消息',information);
        if(information.name !== userName.textContent){  //  不是本机时
            createOtherMessage(information);   //  生成聊天气泡
        }
    });
    
    // 当接收到有人连接进来
    socket.on('connected',function(onlinecount){
        console.log(`有人登录,在线人数为:${onlinecount}`);
        onlineCount.innerHTML = 'Online:' + onlinecount;
    });
    
    // 当接收到有人断开后
    socket.on('disconnected',function(onlinecount){
        console.log(`有人断开啦:当前人数为:${onlinecount}`);
        onlineCount.innerHTML = 'Online:' +onlinecount;
    });
    
    // 发送本机的消息
    function sendMessage(){
        if(editBox.value != ''){     //..如果发送内容不为空
            var myInformation = {
                name :userName.textContent,
                chatContent : editBox.value,
                img : userImg.src
            };
            socket.emit('message',myInformation);
            createMyMessage();    //  创建本机聊天气泡
            editBox.value = '';   //..清空文本框
        }
    }
    
    // 生成本机的聊天气泡
    function createMyMessage(){
        var myMessageBox = document.createElement('li');
        myMessageBox.className = 'my-message-box';
    
        var messageContent = document.createElement('li');
        messageContent.className = 'message-content';
        var text = document.createElement('span');
        text.innerHTML = editBox.value;
        messageContent.appendChild(text);
        myMessageBox.appendChild(messageContent);
    
        var arrow = document.createElement('li');
        arrow.className = 'message-arrow';
        myMessageBox.appendChild(arrow);
    
        var userInformation = document.createElement('li');
        userInformation.className = 'user-information';
        var userChatImg = document.createElement('img');
        userChatImg.className = 'user-chat-img';
        userChatImg.src = userImg.src;
        var userChatName = document.createElement('li');
        userChatName.className = 'user-chat-name';
        userChatName.innerHTML= userName.textContent;
        userInformation.appendChild(userChatImg);
        userInformation.appendChild(userChatName);
        myMessageBox.appendChild(userInformation);
    
        chatContent.appendChild(myMessageBox);
    
        chatContent.scrollTop = chatContent.scrollHeight;  //  滚动到最新聊天内容
    }
    
    // 生成其他用户的聊天气泡  
    function createOtherMessage(information) {  
        var otherMessageBox = document.createElement('li');  
        otherMessageBox.className = 'other-message-box'; 
    
        var otherUserInformation = document.createElement('li');  
        otherUserInformation.className = 'other-user-information';  
        var userChatImg = document.createElement('img');  
        userChatImg.className = 'user-chat-img';  
        userChatImg.src = information.img;  
        var userChatName = document.createElement('span');  
        userChatName.className = 'user-chat-name';  
        userChatName.innerHTML = information.name;  
        otherUserInformation.appendChild(userChatImg);  
        otherUserInformation.appendChild(userChatName);  
        otherMessageBox.appendChild(otherUserInformation); 
    
        var otherMessageArrow = document.createElement('li');  
        otherMessageArrow.className = 'other-message-arrow';  
        otherMessageBox.appendChild(otherMessageArrow); 
    
        var otherMessageContent = document.createElement('li');  
        otherMessageContent.className = 'other-message-content';  
        var text = document.createElement('span');  
        text.innerHTML = information.chatContent;  
        otherMessageContent.appendChild(text);  
        otherMessageBox.appendChild(otherMessageContent); 
    
        chatContent.appendChild(otherMessageBox); 
    
        chatContent.scrollTop = chatContent.scrollHeight;  
    } 
    
  • server.js

  • // 引入必须模棱
    var express = require('express');
    var app = express();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    var path = require('path');
    
    // 在线人数统计
    var onlineCount = 0;
    app.use(express.static(__dirname));
    
    // 路径映射
    app.get('/login.html',function(request,response){
        response.sendFile('login.html');
    });
    
    // 当有用户连接进来时
    io.on('connection',function(socket){
        console.log('a user connected');
    
        // 发送给客户端在线人数
        io.emit('connected',++onlineCount);
    
        // 当有用户断开
        socket.on('disconnect',function(){
    
                console.log('user disconnected');
    
                // 发送给客户端人数
                io.emit('disconnected',--onlineCount);
                console.log(onlineCount);
        });
    
        // 收到了客户端发来的消息
        socket.on('message',function(message){
            // 给客户端发送消息
            console.log('服务器收到的消息为:',message);
            io.emit('message',message);
        });
    });
    
    var server = http.listen(4000,function(){
        console.log('Server is running');
    });
    
  • 最后

    终端输入

  • node server.js
    
  • 浏览器地址栏输入

    http://localhost:4000/login.html

    nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)

    nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)

    nodejs实现websocket服务端(Node.js+express+socket实现在线实时多人聊天室)

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。

    标签:node.js 聊天室