目 录CONTENT

文章目录

聊天室案例

Administrator
2020-07-24 / 0 评论 / 0 点赞 / 14040 阅读 / 10237 字

聊天室案例

聊天室案例采用WebSocket的方式来进行,代码分为前端代码与后端代码,后端代码采用nodejs来完成

效果图地址

效果图

1567217999700

1567218209324

后端代码

const ws = require("nodejs-websocket");
const createServer = () => {
    
    let server = ws.createServer(connection => {
        //console.log(connection);
        connection.on('text', function (result) {
            // console.log('收到消息', result);
            //接收到消息以后,然后再进行转到,发送到每一个客户端
            
            broadcast(server,result);
        })
        connection.on('connect', function (code) {
            console.log('开启连接', code)
        })
        connection.on('close', function (code) {
            console.log('关闭连接', code)
        })
        connection.on('error', function (code) {
            console.log('异常关闭', code)
        })
    });
    return server;
}

// 服务端广播
function broadcast(server, msg) {
    server.connections.forEach(function (conn) {
        console.log(conn);
        conn.sendText(msg);
    })
}

let server=createServer();

server.listen(9998,function(){
    console.log("服务开启成功");
})

前端代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>H1904Chat</title>
    <link rel="stylesheet" href="https://at.alicdn.com/t/font_1307637_7wuk1w2g5l4.css">

    <style>
        .main {
            width: 900px;
            margin: auto;
            border: 1px solid lightgray;
        }

        .resultDiv {
            width: 100%;
            height: 600px;
            box-shadow: 0px 0px 15px 3px lightgray inset;
            box-sizing: border-box;
            padding: 20px;
            overflow: auto;
        }

        .main .bottom {
            height: 45px;
            display: flex;

        }

        #txtMsg {
            flex: 1;
            box-sizing: border-box;
            padding: 0px 10px;
        }

        #btnSend {
            width: 120px;
            height: 100%;
            border: none;
            font-size: 22px;
            cursor: pointer;
        }

        #btnSend:disabled {
            cursor: no-drop;
            /* 禁用 */
        }

        .resultDiv>div {
            line-height: 1.5;
        }

        .msg {
            margin-top: 15px;
            word-break: break-all;
        }

        .msg>.userInfo {
            font-weight: bold;
            font-size: 14px;
        }

        .msg>.msgContent {
            margin-top: 5px;
            padding: 5px 10px;
            background-color: white;
            /* border: 1px solid lightgray; */
            border-radius: 5px;
            box-shadow: 0px 0px 15px 3px lightsteelblue inset;
            min-height: 34px;
            display: flex;
            align-items: center;
            width: fit-content;
            /*  元素还是块级元素,宽度随内容撑开    */

        }

        .icon-tupian {
            font-size: 26px;
            cursor: pointer;
        }

        .imgBox {
            width: 100%;
        }

        .imgBox>img {
            max-width: 400px;
            max-height: 400px;
        }
        .videoDiv{
            width: 600px;
            position: fixed;
            left: 50%;
            top: 50%;
            transform: translate(-50%,-50%);
            border: 1px solid black;
            display: none;
        }
        .videoDivBottom{
            display: flex;
            justify-content: space-around;
        }
    </style>
</head>

<body>
    <div class="main">
        <h1 style="text-align: center">H1904聊天室</h1>
        <div class="resultDiv">

        </div>
        <div>
            <input type="file" id="f1" style="display: none" onchange="fileChange(this)">
            <span class="iconfont icon-tupian" onclick="this.previousElementSibling.click()"></span>
            <button type="button" onclick="openVideo()">截图发送</button>
        </div>
        <div class="bottom">
            <input type="text" id="txtMsg" oninput="txtMsgInput(this)" placeholder="请输入聊天内容">
            <button type="button" disabled id="btnSend" onclick="sendMsg()">发送消息</button>
        </div>
    </div>
    <!--div显示视频 -->
    <div class="videoDiv">
        <video id="v1" width="600px" height="400px"></video>
        <canvas id="c1" width="600px" height="400px" style="display: none"></canvas>
        <div class="videoDivBottom">
            <button type="button" onclick="takePhoto()">拍照</button>
            <button type="button" onclick="document.querySelector('.videoDiv').style.display='none'">关闭</button>
        </div>
    </div>

    <template id="msgtemp">
        <div class="msg">
            <div class="userInfo">{{userNickName}} {{currentTime}}</div>
            <div class="msgContent">{{msgContent}}</div>
            {{if base64}}
            <div class="imgBox">
                <img src="{{base64}}">
            </div>
            {{/if}}
        </div>
    </template>
</body>
<script src="./js/template-web.js" type="text/javascript"></script>
<script src="./js/time.js" type="text/javascript"></script>
<script>
    var btnSend = document.querySelector("#btnSend");
    var txtMsg = document.querySelector("#txtMsg");
    var resultDiv = document.querySelector(".resultDiv");
    var base64Str = "";
    //当页面加载的时候,我们就弹出一个输入框让用户输入信息
    var flag = true;
    while (flag) {
        var userNickName = prompt("请输入你的昵称");
        if (userNickName == null) {
            flag = true;
        } else if (userNickName != null && userNickName.trim() == "") {
            flag = true;
        } else {
            flag = false;
        }
    }
    //创建WebSocket  连接到服务器
    var ws = new WebSocket("ws://192.168.6.177:9998");
    ws.onopen = function () {
        ws.send(userNickName + " " + getCurrentTime() + " 进入了聊天室");
    }
    ws.onclose = function () {

    }
    ws.onerror = function () {

    }
    ws.onmessage = function (event) {
        //event.data
        appendMsg(event.data);
    }

    function txtMsgInput(obj) {
        if (obj.value.trim().length > 0) {
            btnSend.disabled = false;
        } else {
            btnSend.disabled = true;
        }
    }


    function appendMsg(msg) {
        var d = document.createElement("div");
        d.innerHTML = msg;
        resultDiv.appendChild(d);
        resultDiv.scrollTo(0, resultDiv.scrollHeight);

    }

    //格式化的方法
    function formatUserMsg(userNickName, currenTime, msgContent, base64) {
        var html = template("msgtemp", {
            userNickName: userNickName,
            currentTime: currenTime,
            msgContent: msgContent,
            base64: base64
        });
        return html;
    }

    //用户点击发送按钮以后
    function sendMsg() {
        var msg = formatUserMsg(userNickName, getCurrentTime(), txtMsg.value.trim(), base64Str);
        //在发送消息之前,我要检查一下,它是否还处理连接状态 
        if (ws.readyState == WebSocket.OPEN) {
            ws.send(msg);
            txtMsg.value = ""; //清除原来的东西
            btnSend.disabled = true; //按钮重新变成禁用状态
            txtMsg.disabled = true;
            base64Str="";    //清空base64图片地址
            setTimeout(function () {
                txtMsg.disabled = false;
            }, 1000);
        } else {
            alert("服务器已关闭");
        }
    }


    function fileChange(obj) {
        if (obj.files.length == 1) {
            var file = obj.files[0];
            var fr = new FileReader();
            fr.readAsDataURL(file);
            fr.onload = function (event) {
                var e = event || window.event;
                base64Str = e.currentTarget.result; //它是一个图片的base64
                obj.value="";

            }
        }
    }


    //打开视频
    function openVideo(){
        navigator.getMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia;
        navigator.getMedia({
            video:true,
            audio:false
        },function(stream){
            document.querySelector("#v1").srcObject=stream;
            document.querySelector("#v1").play();
            document.querySelector(".videoDiv").style.display="block";
        },function(err){
            console.log(err);
        });
    }


    function takePhoto(){
        var c1=document.querySelector("#c1");
        var ctx=c1.getContext("2d");
        var v1=document.querySelector("#v1");
        ctx.drawImage(v1,0,0,600,400);
        base64Str = c1.toDataURL("image/png");
        document.querySelector(".videoDiv").style.display="none";
    }
</script>

</html>

前端代码采用了template模板以及websocket的方式,同时还完成了浏览器调用摄像头完在视频截图发送的功能

0

评论区