WebSocket【B/S】前后端链接通信——simple_Chat实现(三)

一、前端实现登录页——css及script

body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}
.login-container {
    width: 300px;
    padding: 40px;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
input[type="text"], input[type="password"] {
    width: 93%;
    padding: 10px;
    margin: 10px 0;
    border: 1px solid #ccc;
    border-radius: 4px;
}
input[type="submit"] {
    width: 100%;
    padding: 10px;
    background-color: #5cb85c;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
input[type="submit"]:hover {
    background-color: #4cae4c;
}
#registId {
    float: right;
    font-size: 9px;
    color: blue;
}
       const url = 'http://127.0.0.1:8080';

        function logIn() {
            const name = document.getElementById("name").value;
            const password = document.getElementById("password").value;

            // 如果需要发起POST请求,并发送数据
            const postData = {
                name:name,
                password:password
            };

            fetch(url + "/login", {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(postData)
            })
                .then(response => response.json())
                .then(result => {
                    if (result.errCode == 200) {
                        const data = result.data;
                        console.log('data:', data);
                        console.log(encodeURIComponent(data));
                        window.location.href = url + "/chat?user=" + encodeURIComponent(JSON.stringify(data));

                        return;
                    } else {
                        //console.log('error:', result);
                        alert(result.errCode+":" + result.msg);
                    }
                })
                .catch(error => {
                    console.error('Fetch error:', error);
                });
        }

二、前端实现注册页——css及script

body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}
.login-container {
    width: 300px;
    padding: 40px;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/*#name::placeholder {*/
/*    color: red;*/
/*}*/
input[type="text"], input[type="password"] {
    width: 93%;
    padding: 10px;
    margin: 10px 0;
    border: 1px solid #ccc;
    border-radius: 4px;
}
input[type="submit"] {
    width: 100%;
    padding: 10px;
    background-color: #5cb85c;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
input[type="submit"]:hover {
    background-color: #4cae4c;
}
#registId {
    float: right;
    font-size: 9px;
    color: blue;
}

/**弹窗**/
/* 模态背景 */
.modal {
    display: none; /* 默认隐藏 */
    position: fixed; /* 固定位置 */
    z-index: 1; /* 位于顶层 */
    left: 0;
    top: 0;
    width: 100%; /* 全屏宽度 */
    height: 100%; /* 全屏高度 */
    overflow: auto; /* 超出时滚动 */
    background-color: rgb(0,0,0); /* 背景颜色 */
    background-color: rgba(0,0,0,0.4); /* 背景颜色 w/ 透明度 */
}

/* 模态内容 */
.modal-content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #fefefe;
    padding: 20px;
    border: 1px solid #888;
    width: 34%;
}

/* 关闭按钮 */
.close {
    color: #aaa;
    float: right;
    font-size: 23px;
    font-weight: bold;
}

.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}
       // 假设后端服务的URL是 http://localhost:8080/api/data
        const url = 'http://127.0.0.1:8080';

 /*       // 发起GET请求
        fetch(url + "/register")
            .then(response => {
                if (response.ok) {
                    return response.json(); // 如果后端返回的是JSON数据
                }
                throw new Error('Network response was not ok.');
            })
            .then(data => {
                console.log('Received data:', data);
            })
            .catch(error => {
                console.error('Fetch error:', error);
            });*/

        function regist() {
            const value = registCheck();
            if (value != 1) {
                return;
            }

            const name = document.getElementById("name").value;
            const password = document.getElementById("password").value;
            const passwordEnter = document.getElementById("passwordEnter");
            if (password != passwordEnter.value) {
                passwordEnter.placeholder = "俩次密码输入不一致,请重新输入!!!";
                return;
            }

            // 如果需要发起POST请求,并发送数据
            const postData = {
                name:name,
                password:password
            };

            fetch(url + "/register", {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(postData)
            })
                .then(response => response.json())
                .then(data => {
                    console.log('Received data:', data);
                    showAlert();
                })
                .catch(error => {
                    console.error('Fetch error:', error);
                });
        }

        function checkNull(event) {
            const input = event.target;
            if (!input.value) {
                // 输入内容为空
                input.placeholder = '输入数据不能为空!!!';
                // 重设焦点
                const name = document.getElementById("name");
                if (name.value == '') {
                    name.focus();
                    return;
                }
                input.focus();
            }
        }

        // 注册数据校验
        function registCheck() {
            const name = document.getElementById("name");
            if (name.value == '') {
                name.placeholder = '输入数据不能为空!!!';
                name.focus();
                return 0;
            }

            const password = document.getElementById("password");
            if (password.value == '') {
                password.placeholder = '输入数据不能为空!!!';
                password.focus();
                return 0;
            }

            return 1;
        }

        /**弹窗**/
        function showAlert() {
            // 获取模态窗口
            const modal = document.getElementById('modal');
            modal.style.display = "block";

            // 获取 <span> 元素,用于关闭模态窗口
            const span = document.getElementsByClassName("close")[0];
            // 当用户点击span元素或点击模态窗口的其他地方时关闭模态窗口
            span.onclick = function() {
                modal.style.display = "none";
            }
            // 当用户点击任何地方时检查,如果点击的是模态内容则不关闭窗口
            window.onclick = function(event) {
                if (event.target == modal) {
                    modal.style.display = "none";
                }
                window.location.href = "index.html";
            }
        }

三、前端实现聊天页——css及script

.container {
            grid-template-columns: repeat(3, 1fr); /* 每列宽度相等 */
            grid-template-columns: repeat(2, 1fr); /*俩列*/
            grid-gap: 10px; /* 格子间隔 */
            width: 330px;
            /*
            height: 100px;
            */
            display: flex;
            flex-direction: column;
            /*margin: 0 auto; 水平居中*/
            margin-left: 20%;
            margin-top: 3%;
        }

        .column {
            background-color: white; /* 格子背景色 */
            border: 0px solid #ccc; /* 格子边框 */
            align-items: center;
            font-size: 18px;
            padding: 0.1px; /* 格子内部填充 */
        }

    /*    #chat_id {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 90vh; !* 使div的高度为视口高度,可根据需要调整 *!
        }*/

        .container {
            font-size: 16px;
        }
        input[type="text"] {
            vertical-align: top; /* 或者使用 middle 或 bottom */
            padding: 5px;
            margin: 0;
            border: 1px solid #ccc;
        }

        #sendId {
            float: right;
        }
        #message {
            width: 200px;
            height: 150px;
        }
    // 页面入参
    const searchParams = new URLSearchParams(window.location.search);
    const user = JSON.parse(decodeURIComponent(searchParams.get('user')));
    //console.log('user:',user);

    // 获取currentUser元素
    const currentUserName = document.getElementById("currentUser");
    // 给span元素设置新的内容
    currentUserName.innerHTML = user.name;

    // webSocket链接
    var ws

    /**
     * 链接websocket
     */
    function connection() {
        const userId = user.id;
        ws = new WebSocket('ws://127.0.0.1:8080/sanqi_server/' + userId);

        ws.onopen = function(evt) {
            const currentUser = user.name;

            // 确保不在关闭状态中发送
            if (ws.readyState === WebSocket.OPEN) {
                console.log("Connection open ...");
                // 连接建立后可以在这里发送消息
                ws.send(JSON.stringify({ 'currentUser': currentUser,'sendFlag':'0','sendTo':userId}));
            } else {
                console.error('WebSocket is not open:', ws.readyState);
            }
        };

        ws.onmessage = function(evt) {
            console.log( "Received Message: " + evt.data);
            document.getElementById('output').innerHTML += "<p>" + evt.data + "</p>";
        };

        ws.onclose = function(evt) {
            console.log("Connection closed.");
        };
    }

    function sendMessage() {
        console.log("发送消息");
        const currentUser = user.name;
        const sendTo = user.id;
        const message = document.getElementById('sendMsg').value;
        ws.send(JSON.stringify({ 'currentUser': currentUser,'sendFlag':'2','sendTo':sendTo,'sendMsg': message }));
}

打包应用程序下载地址:https://download.youkuaiyun.com/download/u011154842/90167214
本文上续【WebSocket【B/S】前后端链接通信——simple_Chat实现(二)】,旨在补全其中的css和script,后端实现详情待后续更新!!!

### WebSocket协议概述 WebSocket是一种用于在服务器与客户端之间实现高效的双向通信的机制[^2]。这种技术解决了传统HTTP请求对于高实时性应用场景下的不足之处,例如在线聊天、在线教育以及金融市场的即时报价等场景。 ### WebSocket事件处理方式 WebSocket API 是纯事件驱动型接口。应用程序通过监听WebSocket对象上发生的各种事件来响应不同的操作需求,如接收新消息或是连接状态的变化。这种方式使得开发者无需频繁地向服务端发起查询请求以获取最新数据;相反,当有新的信息可用时,这些更新会自动推送到客户端并触发相应的事件处理器[^1]。 为了开始监听来自WebSocket连接的消息和其他重要通知,可以通过设置特定属性作为回调函数的方式来进行绑定,或者利用`addEventListener()`方法注册多个类型的事件监听器: ```javascript // 创建一个新的WebSocket实例并与指定URL建立连接 const socket = new WebSocket('ws://example.com/socket'); // 定义接收到消息后的动作 socket.onmessage = function(event) { console.log(`Message from server: ${event.data}`); }; // 使用 addEventListener 添加更多种类的事件监听 socket.addEventListener('open', () => { console.log('Connected to the server'); }); ``` 上述代码片段展示了如何创建一个WebSocket实例,并为其配置两个不同形式的事件处理器——一个是针对传入消息流而设计的专用属性`onmessage`,另一个则是通用性的`addEventListener`调用来捕捉连接成功的时刻。 ### 应用实例:简易版在线聊天室 下面给出一段简单的HTML页面配合JavaScript脚本实现了基本功能的一个例子,它允许用户输入昵称加入房间后与其他参与者交流文字内容: #### HTML部分 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Simple Chat Room</title> <style> /* 简单样式 */ body { font-family: Arial, sans-serif; } input[type=text], button { padding: 5px; margin-bottom: 10px;} #messages { border: 1px solid black; height: 300px; overflow-y: scroll;} .message {padding: 5px;border-bottom: 1px dashed gray;} </style> </head> <body> <h2>Welcome to Simple Chat!</h2> <div id="chatbox"> <div id="messages"></div> <!-- 用户名 --> Nickname:<br><input type="text" id="nickname"><br> <!-- 发送框 --> Message:<br><textarea rows="4" cols="50" id="msgInput"></textarea><br> <button onclick="sendMessage()">Send</button> </div> <script src="./chat.js"></script> </body> </html> ``` #### JavaScript (chat.js) ```javascript let nickname; let ws; function connectToServer(name){ // 构建完整的WebSocket URL路径 const url = `wss://${window.location.host}/chat?nick=${encodeURIComponent(name)}` try{ // 尝试开启到WebSockets服务器的新链接 ws = new WebSocket(url); // 当成功建立了握手之后执行的动作 ws.onopen = ()=>{ log(`${nickname} has joined.`); }; // 接收到来自其他用户的广播消息时的操作 ws.onmessage = ({data})=>{ let messageObj = JSON.parse(data); displayMessage(messageObj.nick,messageObj.text); }; // 如果发生错误,则记录下来供调试之用 ws.onerror=(error)=>{ console.error("Error occurred:", error); } // 断开连接前的通知 ws.onclose=()=>{ log(`${nickname} disconnected`); } }catch(e){ alert("Failed to establish a connection."); } } document.querySelector('#nickname').addEventListener('keypress',(e)=>{ if(e.key === 'Enter'){ nickname=document.getElementById('nickname').value.trim(); if(nickname.length===0)return false; document.getElementById('nickname').readOnly=true; connectToServer(nickname); } }); function sendMessage(){ var msgText = document.getElementById('msgInput').value.trim(); if(!msgText || !ws || ws.readyState !== WebSocket.OPEN )return ; ws.send(JSON.stringify({ nick:nickname , text : msgText })); document.getElementById('msgInput').value=''; } function log(text){ appendMessage(`<span class='log'>${text}</span>`,'log') } function displayMessage(sender,body){ appendMessage(`<strong>${sender}: </strong>${body}`) } function appendMessage(htmlContent,type='message'){ let div = document.createElement('DIV'); div.className=`${type}`; div.innerHTML=htmlContent; document.getElementById('messages').appendChild(div); // 自动滚动到底部显示最新的对话条目 setTimeout(() =>{ document.getElementById('messages').scrollTop = document.getElementById('messages').scrollHeight; },0); } ``` 此示例提供了一个基础框架,可以根据实际项目的需求进一步扩展和完善其特性集,比如增加身份验证流程、支持多媒体文件传输等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走一路_拈花瓣翩翩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值