1、nodejs实现一个简单的聊天

部分代码如下

chatServer.js文件

let ws = require("nodejs-websocket");
process.stdin.setEncoding("utf8");
console.log("开始建立连接...");
let userObj = {};
let server = ws
  .createServer(function (conn) {
    conn.on("text", function (str) {
      let newStr = eval("(" + str + ")");

      const { memberId, targetId, content } = newStr;
      console.log("收到的信息为:" + content);
      console.log("用户id:" + memberId);
      userObj[memberId] = {
        coon: conn,
        isOnline: true,
      };

      if (content !== "已经建立连接") {
        //如果接收方在线
        if (userObj[targetId]) {
          userObj[targetId].coon.sendText(memberId + ":" + content);
        }
        conn.sendText(memberId + ":" + content);
      }

      //像前端页面发送推送
      process.stdout.write("请输入发送的值:");
      process.stdin.on("data", function (chunk) {
        conn.sendText(chunk);
      });
    });

    conn.on("close", function (code, reason) {
      console.log("关闭连接");
    });
    conn.on("error", function (code, reason) {
      console.log("异常关闭");
    });
  })
  .listen(8801);
console.log("WebSocket建立完毕");

客户端代码

用下面两个链接来测试 ?后面的分别是自己的id跟对方的id

 http://127.0.0.1:5500/user.html?memberId=1&targetId=2

 http://127.0.0.1:5500/user.html?memberId=2&targetId=1

<!--
 * @Description: 
 * @Version: 
 * @Autor: Candy
 * @Date: 2021-12-23 11:34:46
 * @LastEditors: Candy
 * @LastEditTime: 2022-03-31 18:56:15
-->
<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <title>websocket(用户1)</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
        integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script type="text/javascript">
        let ws = null;
        let wsUrl = 'ws://127.0.0.1:8801/';
        let lockReconnect = false;

        function getParam(url, name) {
            try {
                var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
                var r = url.split('?')[1].match(reg);
                if (r != null) {
                    return r[2];
                }
                return "";//如果此处只写return;则返回的是undefined
            } catch (e) {
                return "";//如果此处只写return;则返回的是undefined
            }
        };

        //http://127.0.0.1:5500/user.html?memberId=1&targetId=2

        //http://127.0.0.1:5500/user.html?memberId=2&targetId=1

        let memberId = getParam(window.location.href, 'memberId')
        let targetId = getParam(window.location.href, 'targetId')
        console.log('memberId', memberId, 'targetId', targetId)
        let commonInfo = {
            memberId,
            targetId,
        }

        //创建一个websocket
        function createWebSocket(url) {
            try {
                if ("WebSocket" in window) {
                    ws = new WebSocket(wsUrl);
                } else if ("MozWebSocket" in window) {
                    ws = new MozWebSocket(wsUrl);
                } else {
                    alert(
                        "您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!"
                    );
                }

                initEventHandle();
            } catch (e) {
                reconnect(wsUrl);
            }
        }

        //监听ws
        function initEventHandle() {

            ws.onclose = function () {
                console.log("ws连接关闭!" + new Date().toUTCString());
                document.getElementById('Bridge').style.display = 'block'
            };
            ws.onerror = function () {
                reconnect(wsUrl);
                console.log("ws连接错误!");
            };
            ws.onopen = function () {
                heartCheck().reset().start(); //心跳检测重置
                console.log("ws连接成功!" + new Date().toUTCString());
                let senObj = {
                    ...commonInfo,
                    content: '已经建立连接',
                }
                let sendStr = JSON.stringify(senObj)
                sendMessage(sendStr);
                document.getElementById('Bridge').style.display = 'none'

            };
            ws.onmessage = function (event) {
                //如果获取到消息,心跳检测重置
                heartCheck().reset().start(); //拿到任何消息都说明当前连接是正常的
                console.log("ws收到消息啦:" + event.data);
                onMessage(event.data)
            };
        }

        function onMessage(message) {
            // const msgData = JSON.parse(event.data);

            console.log(message)
            var li = document.createElement("li");
            li.innerHTML = message;
            if (message.indexOf(commonInfo.memberId) > -1) {
                li.setAttribute("style", 'color: #E91E63;font-weight: 700;text-align: right;');
            } else {
                li.setAttribute("style", 'color: #2196F3;font-weight: 700;');
            }
            document.getElementById('chat-list').appendChild(li)
        }


        //关闭连接
        function closeWebSocket() {
            ws.close();
        }

        function sendMessage(sendStr) {
            ws.send(sendStr);
        }

        //重连
        function reconnect(url) {
            if (lockReconnect) return;
            lockReconnect = true;
            setTimeout(function () {
                //没连接上会一直重连,设置延迟避免请求过多
                createWebSocket(url);
                lockReconnect = false;
            }, 2000);
        }

        //心跳检查
        function heartCheck() {
            return {
                timeout: 5 * 60 * 1000,
                timeoutObj: null,
                serverTimeoutObj: null,
                reset: function () {
                    var self = this;
                    clearTimeout(self.timeoutObj);
                    clearTimeout(self.serverTimeoutObj);
                    return self;
                },
                start: function () {
                    var self = this;
                    self.timeoutObj = setTimeout(function () {
                        //这里发送一个心跳,后端收到后,返回一个心跳消息,
                        //onmessage拿到返回的心跳就说明连接正常
                        ws.send("ping");
                        console.log("ping!");
                        self.serverTimeoutObj = setTimeout(function () {
                            //如果超过一定时间还没重置,说明后端主动断开了
                            ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                        }, self.timeout);
                    }, self.timeout);
                },
            };
        }

        window.onload = function () {
            document.querySelector("#btnSend").onclick = function (e) {
                var chatBox = document.getElementById('chatBox').value;

                let senObj = {
                    ...commonInfo,
                    content: chatBox,
                }
                let sendStr = JSON.stringify(senObj)
                // Web Socket 已连接上,使用 send() 方法发送数据
                sendMessage(sendStr);
                document.getElementById('chatBox').value = '';
            }
        }
    </script>

</head>

<body>
    <div class="col-sm-6">
        <ul id="chat-list"></ul>

        <div class="form-group">
            <p></p>
            <textarea id="chatBox" class="col-sm-2 form-control" rows="3" style="margin-bottom:10px"></textarea>
            <button type="button" onclick="createWebSocket()" class="btn btn-primary" id="Bridge"
                style="float: left;margin-right: 10px">建立连接</button>
            <button type="button" id='btnSend' class="btn btn-success">发送信息</button>
        </div>
    </div>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值