node 实现简易聊天室

61 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第35天,点击查看活动详情

node 是我们前端程序员强大的服务工具,现在其不仅可以完成我们前端大部分的文件操作,本地服务操作,甚至已经有了很完善的中台系统,这里我们使用一个简单的聊天窗口,使用 node 启动服务来实现。

  • HTML
    我们先使用 html 来写出来一个页面,大家先来看一下最终实现的效果是什么样子的:

Snipaste_2022-12-24_17-42-32.png 这里的话,我把 node 服务端代码 和 js 代码分开了, 我把 js 直接写在了 HTML 中, 因为本身也没有多少代码,就没有外链,页面上的实现是比较简单的,就是一个表单,一个文本域,然后我们需要获取这些元素的相关 DOM 侦听对应事件,发送消息我们使用 post 请求,获取消息我们使用 get 请求

// css
    <style>
        textarea{
            width: 1200px;
            height: 600px;
            resize: none;
            background-color: white;
            overflow: auto;
        }
        input{
            height: 30px;
            line-height: 30px;
            font-size: 25px;
        }
        input[name=msg]{
            width: 800px;
           
        }
        button{
            width: 80px;
            height: 30px;
        }
    </style>
// body
<body>
    <textarea disabled></textarea>
    <form action="#">
        <input type="text" name="user">说:
        <input type="text" name="msg">
        <button type="submit">提交</button>
    </form>
    <script>
       var form,textarea;

        init();
       function init(){
        form=document.querySelector("form");
        textarea=document.querySelector("textarea");
        form.addEventListener("submit",submitHandler);
        setInterval(getMsg,100);
       }

       function submitHandler(e){
           e.preventDefault();
           var fd=new FormData(form);
           var data={};
           for(var [key,value] of fd){
               if(value.trim().length===0) return;
               data[key]=value;
           }
           sendMsg(JSON.stringify(data));
           form.children[1].value="";
       }

      async function getMsg(){
            var data=await fetch("http://localhost:4030/");
            data=await data.json();
            console.log(data)
            textarea.value=data.reduce((v,t)=>{
                return v+t.user+":"+t.msg+"\n";
            },"");
       }

     

      async function sendMsg(body){
           var data=await fetch("http://localhost:4030/send",{method:"post",body});
           data=await data.json();
          if(!data.result){
              console.log("通信失败")
          }
       }
    </script>
</body>
  • node
    下面是最主要的服务部分,这里我们使用 httpcreateServer 来启动一个服务,这里我们侦听了自己的端口号,但是如果我们在同一网络下,是可以使用另一台电脑,通过访问我们这台电脑的 ip 来进行互动的, 把上面 HTML 的请求,改成我们启动了这个服务的本机的 ip就可以。
    这里使用 nodemon 来启动服务

Snipaste_2022-12-24_17-43-42.png

const http=require("http");
const msgList=[];
const querystring=require("querystring");
http.createServer(async function(req,res){

    var type=req.url.split("?")[0];
    res.writeHead(200,{
        "Content-Type":"text/html;charset=utf-8",
        // 允许跨域访问发送数据
        "Access-Control-Allow-Origin":"*",
        // 允许跨域时修改请求方式
        "Access-Control-Allow-Methods":"PUT",
        // 允许前端发送来自定义的请求头
        "Access-Control-Allow-Headers":"X-Name",
        // 如果需要发送自定义响应头,需要浏览器可以获取必须使用这个来设置需要发送的自定义响应头
        "Access-Control-Expose-Headers":"X-Session-Id",
        "X-Session-Id":"1011101"
    })
    router(type,req,res)
}).listen(4030);

function getData(req){
    return new Promise(function(resolve,reject){
        var data="";
        req.on("data",function(chunk){
            data+=chunk;
        //    for(var i=0;i<chunk.length;i++){
        //         data+=String.fromCharCode(chunk[i]^2345);
        //    }
            // for(var i=0;i<chunk.length;i+=2){
            //     data+=String.fromCharCode(parseInt(chunk[i+1].toString(16).padStart(2,"0")+chunk[i].toString(16).padStart(2,"0"),16))
            // }
        })
        req.on("end",function(){
            resolve(data);
        })
    })
}

function router(type,req,res){
    switch(type){
        case "/send":
        return sendMsg(req,res);
        case "/":
        return getMsg(req,res);
    }
}
async function sendMsg(req,res){
    var data=await getData(req);
    try{
        data=JSON.parse(data);
    }catch(e){};
    msgList.push(data);
    res.end(JSON.stringify({result:true}))
}

function getMsg(req,res){
    res.end(JSON.stringify(msgList));
}