原生JavaScript+WebSocket+nodejs实现聊天室功能

码字不易,有帮助的同学希望能关注一下我的微信公众号:Code程序人生,感谢!代码自用自取。

WebSocket也是前端非常重要的技术栈。

现在各种网站、App、小程序都伴有即时通信的功能。WebSocket的主要应用就是即时通信

WebSocket的介绍在网上非常非常多,也非常详细,我就不做过多介绍了。

WebSocket的出现解决了远古时期http轮询的”丑陋“。

我这期视频使用原生JavaScript+nodejs实现一个最基本的聊天室功能。

我先介绍一个目录文件:
在这里插入图片描述

前端内容存放在chat文件夹中,一共两个页面,entry.htmlindex.html后端内容存放在server文件夹中,主要逻辑写在index.js中。

前端部分:

entry.html内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text" id="username"  placeholder="请输入用户名"/>
    <button id="enter">进入聊天室</button>
    <script>
        ;((doc,storage,location) => {
     
     
            const oUsername = doc.querySelector('#username');
            const oEnterBtn = doc.querySelector('#enter');

            const init = () => {
     
     
                bindEvent(); 
            }

            function bindEvent(){
     
     
                oEnterBtn.addEventListener('click',handleEnterBtnClick,false);
            }
            function handleEnterBtnClick(){
     
     
                const username = oUsername.value.trim();
                console.log(username);
                if(username.length < 6){
     
     
                    alert('用户名不能小于6位');
                    return;
                }
                storage.setItem('username',username);
                location.href = 'index.html';
            }
            init();
        })(document,localStorage,location);
    </script>
</body>
</html>

这个页面主要是做一个登录,做的有点粗糙,没写UI,主要还是为了存放一个localStorage用于下个页面通信。

index.html内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id="list">
        <input type="text" id="message" placeholder="请输入消息" />
        <button id="send">发送</button>
    </ul>
    <script>
        const oList = document.querySelector('#list');
        const oMessage = document.querySelector('#message');
        const oSendBtn = document.querySelector('#send');
        let username = '';

        const ws = new WebSocket('ws:localhost:8000');

            oSendBtn.addEventListener('click',handleSendBtnClick,false);
            ws.addEventListener('open',handleOpen,false);
            ws.addEventListener('close',handleClose,false);
            ws.addEventListener('error',handleError,false);
            ws.addEventListener('message',handleMessage,false);
        function handleSendBtnClick(){
     
     
            console.log('send message');
            const msg = oMessage.value;
            if(!msg.trim().length){
     
     
                return;
            }
            ws.send(JSON.stringify({
     
     
                user:username,
                dateTime:new Date().getTime(),
                message:msg
            }))

            oMessage.value = '';
        }
        function handleOpen(){
     
     
            console.log('WebSocket open');
            username = localStorage.getItem('username');

            if(!username){
     
     
                location.href = 'entry.html';
                return;
            }
        }
        function handleClose(){
     
     
            console.log('WebSocket close');
        }
        function handleError(){
     
     
            console.log('WebSocket error');
        }
        function handleMessage(e){
     
     
            console.log('WebSocket message');
            console.log(e);
            const msgData = JSON.parse(e.data);
            oList.appendChild(createMsg(msgData));
        }
        function createMsg(data){
     
     
            const {
     
     user,dateTime,message} = data;
            const oItem = document.createElement('li');
            oItem.innerHTML = `
                <p>
                    <span>${
       
       user}</span>
                    <i>${
       
       new Date(dateTime)}</i>    
                </p>
                <p>消息:${
       
       message}</p>
            `
            return oItem;
        }
    </script>
</body>
</html>

这个页面是聊天室的内容,伴随了很多dom操作,可能有点乱,我也没有分模块,全写在一起了,方便复制粘贴。

前端部分其实主要就是实例化了一个WebSocket对象,无论是前端还是后端,WebSocket都是一个以事件驱动的方式存在。

前端主要事件是open、close、error、message

open、close、error的功能就和名字一样,不做过多解释。

主要是message事件,它主要是接收来自后端推送过来的信息

后端部分

后端在编写之前要先安装ws模块,打开控制台输入

npm i ws -s

index.js

const ws = require('ws');
;((ws)=>{
    
    
    const server = new ws.Server({
    
    port:8000});
    const init = () => {
    
    
        bindEvent();
    }

    function bindEvent() {
    
    
        server.on('open',handleOpen);
        server.on('close',handleClose);
        server.on('error',handleError);
        server.on('connection',handleConnection);
    }
    function handleOpen(){
    
    
        console.log('WebSocket open');
    }
    function handleClose(){
    
    
        console.log('WebSocket close');
    }
    function handleError(){
    
    
        console.log('WebSocket error');
    }
    function handleConnection(ws){
    
    
        console.log('WebSocket connection');
        ws.on('message',handleMessage);
    }
    function handleMessage(msg){
    
    
        console.log('WebSocket message');
        console.log(msg);
        server.clients.forEach(function(c){
    
    
            c.send(msg);
        })
    }
    init();
})(ws);

后端使用nodejs,也是采用事件驱动的方式执行。

主要事件有:open、close、error、message、connection
前三个事件还是形如其名。

message事件存放于connection事件的参数里的,所以要在connection中绑定message事件

connection就是代表通信是否连接成功的事件。

message的参数就是前端传过来的信息。
然后要做的就是把接收到的前端信息分发聊天室所有的人。

在代码的最顶部,我们实例化了一个ws模块的Server对象
Server对象里有一个clients属性,所有登录在聊天室的人都挂载在这个clients属性上。
所以我们只需要forEach循环把接收到的前端信息分发给每一个人即可。

其实到现在为止我们就完成了一个最基本基于WebSocket技术原生JavaScript实现的聊天室

我分别打开了一个chrome浏览器和uc浏览器。
我们看一下效果:
在这里插入图片描述

没有任何问题,一个最基本的聊天室的内容已经搭建完成。
如果你想商用,或者参加一些比赛,可以美化一下UI,把一些细节操作优化一下。

可以直接复制文章中的代码,粘贴使用,按照操作来,不会有任何问题
如果想要源代码文件,关注我的公众号回复聊天室即可。


有微信小程序课设、毕设需求联系个人QQ:505417246

关注下面微信公众号,可以领取微信小程序、Vue、TypeScript、前端、uni-app、全栈、Nodejs、Python等实战学习资料
最新最全的前端知识总结和项目源码都会第一时间发布到微信公众号,请大家多多关注,谢谢!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_46171043/article/details/113126405