WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
WebSocket允许服务端主动向客户端推送数据,并且浏览器和服务器只需要一次握手就可以建立一条数据互相传送的通道。通常运用现在即时聊天等方面。
现在的大部分网站中也会使用 Ajax轮询 技术,来实现推送数据,而这种技术指的是在特定的时间间隔,由浏览器向服务器请求数据,服务器响应请求给浏览器再推送在页面上,这种模式极大的浪费了很多带宽资源,因为浏览器需要不停地向服务器发送请求。
而WebSocket能更好的节约服务器资源和带宽,并且能够更实时地进行通讯。
案例::通过WebSocket制作简单同步聊天页面
此项目仅在同域,同ip下进行测试,node搭建服务器。
1.npm init -y
2.npm intall
3.npm moment 参考地址https://momentjs.com/
4.npm install --save socket.io 参考网址https://socket.io/get-started/chat/
服务器app.js代码部分:
var express = require('express'); //引入express var app = express(); //实例一个对象 var moment = require('moment'); //引入时间插件,先执行npm moment指令 var path = require('path'); //引入node核心模块path var http = require('http').createServer(app); //引入http模块创建服务器方法 app.use( express.static( path.resolve(__dirname, 'public/') ) ); //中间函数express.static访问静态资源目录。 var io = require('socket.io')(http); // 1. on 代表是事件监听 (事件的名称: connection, 当客户端连接之后,connection 回调函数立马执行) // 2. 回调函数的参数 socket 代表是当前的客户端 可以通过这个 socket 给客户端主动推送信息; io.on('connection', function(socket){ /* 监听加入事件 */ socket.on('joinUs', function (data) { console.log( data ); // 自己的信息全部广播出去 // allUsers.forEach(); // socket.emit('guangbo', data); // 内置广播 io.emit('guangbo', data); //io.emit广播出去 }); /* 监听聊天事件 */ socket.on('sendData', function (data) { // nickname, content, 添加2019年8月23日16:46:28 // data.time = new Date();// moment data.time = moment().format('YYYY-MM-DD HH:mm:ss'); io.emit('msgGuangbo', data); }) }); // 构建 websocket 服务器,不需要单独自己搭建,借助http协议 //监听服务器端口设置为3000 http.listen(3000, function(){ console.log('listening on *:3000'); });
//运行代码使用 node app.js 打开服务器
//在浏览器输入localhost:3000;打开
html代码部分index.html
</head> <body> <div class="i-body"> <h1>请输入你的昵称:</h1> <form id="nicknameForm"> <input type="text" id='nickname'> </form> </div> </body> </html> <script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script> <script type="text/javascript"> $("#nicknameForm").submit(function(event) { event.preventDefault(); // 阻止默认事件 var nickname = $("#nickname").val().trim(); if(!nickname){ alert('请输入昵称!'); return; } localStorage.setItem('nickname', nickname); location.href = '/room.html'; }); </script>
聊天代码HTML部分
<!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>迷你聊天室</title> <link rel="stylesheet" href="./style/style.css"> </head> <body> <header class="c-header"> <h1>迷你聊天室</h1> <div class="c-user"><img src="./imgs/1.jpg" title=""></div> </header> <div class="c-body"> <div class="c-main"> <ul class="c-list"> </ul> <div class="c-xxx"></div> <div class="c-chat"> <img class="c-avatar2" src="./imgs/1.jpg" alt=""> <input class="c-input" type="text" id="chatContent"> <button class="c-btn" id="chatBtn">发送</button> </div> </div> </div> </body> </html> <script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script> <script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script> <script type="text/javascript"> // 当有新的人加入到聊天室,把当前的人发送到服务器,服务器广播给所有的人。 var nickname = localStorage.getItem('nickname'); if(!nickname){ alert('请输出昵称后,在来聊天!'); location.href = '/index.html'; } var url = 'http://localhost:3000'; socket = io(url); socket.on('connect', function () { console.log( 'connect' ); }); socket.emit('joinUs', {nickname}); socket.on('guangbo', function (data) { console.log('广播', data ); var _html = `<li class="c-item"> <div class="c-join-info">【${data.nickname}】加入聊天室</div> </li>`; $(".c-list").append( _html ); }) socket.on('msgGuangbo', function (data) { console.log('msgGuangbo', data ); var _html = ``; if( data.nickname == nickname ){ // my-item 自己发送的增加底纹 _html = `<li class="c-item my-item"> <img class="c-avatar" src="./imgs/5.jpg" title=""> <div class="c-box"> <div class="c-info"> <div class="c-name">${data.nickname} ${data.time}</div> </div> <div class="c-content">${data.content}</div> </div> </li>`; }else{ _html = `<li class="c-item"> <img class="c-avatar" src="./imgs/5.jpg" title=""> <div class="c-box"> <div class="c-info"> <div class="c-name">${data.nickname} ${data.time}</div> </div> <div class="c-content">${data.content}</div> </div> </li>`; } $(".c-list").append( _html ); }) $("#chatBtn").click(function(event) { var content = $("#chatContent").val().trim(); if(!content){ alert('请输入聊天内容!'); return; } $("#chatContent").val(''); // 发送消息 socket.emit('sendData', {content, nickname}); }); </script>
Socket参考网址https://www.w3cschool.cn/socket/socket-1olq2egc.html
代码主要提供思路 ,原理都是一样!!