前端和后端的交互的方式有哪些?
前台里面能够发送网络请求的标签,基本上都可以和后端实现网络交互。
- ajax
- jsonp
- iframe
- websocket
- …
我们思考一个问题
在之前,我们知道前后端数据交互的过程中,都是前端发送请求,后端给予响应。但是有没有一种情况就是在前端没有发送请求的情况下,后端自动向前端一个响应?
其实是有这种情况的,就是服务器主动向客户端推信息,我们称之为coment技术(推技术)。
coment技术如何实现?
- ajax+定时器(轮询long-polling,伪实现)
- 长链接
- websocket
- …
WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
为了方便使用,我们可以使用第三方库socket.io
socket.io
socket.io是一个跨浏览器支持WebSocket的实时通讯的JS。
Socket.io支持及时、双向、基于事件的交流,可在不同平台、浏览器、设备上工作,可靠性和速度稳定。最典型的应用场景如:
- 实时分析:将数据推送到客户端,客户端表现为实时计数器、图表、日志客户。
- 实时通讯:聊天应用
- 二进制流传输:socket.io支持任何形式的二进制文件传输,例如图片、视频、音频等。
- 文档合并:允许多个用户同时编辑一个文档,并能够看到每个用户做出的修改。
Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,会根据情况选择方法来进行通讯。
Node.js提供了高效的服务端运行环境,但由于Browser对HTML5的支持不一,为了兼容所有浏览器,提供实时的用户体验,并为开发者提供客户端与服务端一致的编程体验,于是Socket.io诞生了。
Socket.io将WebSocket和Polling机制以及其它的实时通信方式封装成通用的接口,并在服务端实现了这些实时机制相应代码。
socket.io基本使用方式
- 安装
npm install socket.io
- 使用
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
// 静态资源
app.use(express.static('./public'));
app.get('/', (req, res) => {
res.send("hello")
});
io.on('connection', (socket) => {
// emit 参数:
// 参数1:代表是触发事件需要实现在websocket的客户端进行监听
// 参数2:传递给客户端的数据
setInterval(() => {
socket.emit('msg', '服务器端' + Math.random());
},1000)
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>客户端</h1>
<button id="btn">点击连接websocket服务器</button>
<div class="content"></div>
</body>
<!-- 书写websocket客户端代码 -->
<!--1. 使用一个第三方的websocket客户端库实现websocket服务-->
<script src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script> // 2. 编写客户端代码 var socketServerUrl = 'http://localhost:3000'; $("#btn").click(() => {
// 3. 发送链接请求 var socketClient = io(socketServerUrl); // 4. 得到一个websocket客户端 // 5. connect是客户端一旦链接websocket服务器成功,回调函数立即执行 socketClient.on('connect', () => {
console.log("链接服务器成功" ) }) socketClient.on('msg', (data) => {
$(".content").append(data + "<hr>"); }) }) </script>
</html>
启动服务,在浏览器地址栏输入:http://localhost:3000/
点击按钮,客户端和服务器成功链接一次,这次链接后,将保持链接,之后每一秒钟服务器端都会主动向客户端发送响应。
使用webscoket实现一个简单的即时聊天工具
const express = require('express')
const app = express();
const moment = require('moment')
const http = require('http').createServer(app);
const io = require('socket.io')(http);
// 静态资源
app.use(express.static('./public'));
// 客户端月服务端连接 短连接服务
app.get('/', (req, res) => {
res.send('hi web!');
});
// websocket 客户端---> websocket 服务器 长链接服务
// on 代表事件监听 connection 链接事件,服务器现在监听websocket客户端的链接,一般 链接成功 回调函数执行,socket 参数代表是当前链接的对象,我们可以通过该对象和客户端进行交互。
io.on('connection', (socket) => {
// console.log(socket);
console.log('a user connected');
// emit 单词翻译过来触发。
// 参数1:代表是触发事件需要实现在websocket的客户端进行监听
// 参数2: 传递给客户端的数据
// 监听客户端发送的 joinUs 事件
socket.on('joinUs', (data)=> {
console.log(data);
// 广播给所有的客户端,有新人加入聊天(暴照)
io.emit('guangbo', data);
})
// 监听 用户发送聊天信息
socket.on('sendMsg', (data) => {
// 广播给所有人
data.time = moment().format('YYYY-MM-DD HH:mm:ss');
io.emit('chat', data);
})
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
<!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>
<div class="i-body">
<h1>请输入你的昵称:</h1>
<form id="usernameForm">
<input type="text" id="nickname">
</form>
</div>
</body>
</html>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script> $("#usernameForm").submit( (event) => {
event.preventDefault(); // 阻止表单默认的提交 var nickname = $("#nickname").val().trim(); // 自己跳转到 room.html // 现在要和 room.html 页面共享 nickname这个用户名 localStorage.setItem('nickname', nickname); location.href = '/room.html'; } ) </script>
<!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="content">
<button class="c-btn" id="msgBtn">发送</button>
</div>
</div>
</div>
</body>
</html>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script> ;(()=>{
var nickname = localStorage.getItem('nickname'); if(!nickname){
location.href = '/index.html'; return; } // 设置连接地址 var socketServerUrl = 'http://localhost:3000'; // 连接请求 var socketClient = io(socketServerUrl); // connect是客户端一旦链接websocket服务器成功,回调函数立即执行 socketClient.on('connect', () => {
console.log('链接服务器成功!'); }) // 将数据发送给websocket服务器,发布广播 socketClient.emit('joinUs', {
nickname}); // 点击发送按钮 $("#msgBtn").click(()=> {
var content = $("#content").val().trim(); if(!content){
alert('聊天信息不能为空!'); return; } // 将数据发送给websocket服务器,发布广播 socketClient.emit('sendMsg', {
nickname, content}); $("#content").val(''); }) // 监听事件 socketClient.on('guangbo', (data)=>{
console.log('guangbo', data); var html = `<li class="c-item"> <div class="c-join-info">【${
data.nickname}】加入聊天室</div> </li> `; $(".c-list").append(html) }) // 监听事件 socketClient.on('chat', (data) => {
console.log('data', data); // 聊天的信息放置页面 data.nickname 信息发送者 var html = ``; if(nickname == data.nickname){
// 代表自己发送 my-item 类名 底纹 html = ` <li class="c-item my-item"> <img class="c-avatar" src="./imgs/3.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/3.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); }) })(); </script>
启动服务,在浏览器地址栏输入:http://localhost:3000/index.html
输入昵称,回车,加入聊天室:
可以发送消息:
当另一个用户也进入了聊天室,可以看到提示:
当另一个人发送消息:
至此,简单的聊天室实现了。
当然,在实际开发中,我们大可不必自己写聊天室,有现成的一些网站就提供了很好的即时聊天功能,比如:
http://kedou.workerman.net/
https://www.easemob.com/
https://layim.layui.com/
参考文档:
https://socket.io/get-started/chat/
https://www.jianshu.com/p/4e80b931cdea
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88367.html