前端和后端的交互的方式有哪些?

前台里面能够发送网络请求的标签,基本上都可以和后端实现网络交互。

  • 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基本使用方式

  1. 安装
npm install socket.io
  1. 使用
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

Node.js学习笔记(五)——WebSocket相关推荐

  1. 【Node.js学习笔记五】npm(Node包管理器)命令行选项

    Node包管理器(Node Packaged Manager,NPM) Node封装模块(Node Packaged Module,module)   选项 说明 示例  1  search  在存储 ...

  2. 千锋Node.js学习笔记

    千锋Node.js学习笔记 文章目录 千锋Node.js学习笔记 写在前面 1. 认识Node.js 2. NVM 3. NPM 4. NRM 5. NPX 6. 模块/包与CommonJS 7. 常 ...

  3. node.js学习笔记

    # node.js学习笔记标签(空格分隔): node.js---## 一 内置模块学习 ### 1. http 模块 ``` //1 导入http模块 const http =require('ht ...

  4. node.js学习笔记14—微型社交网站

    node.js学习笔记14-微型社交网站 1.功能分析 微博是以用户为中心,因此需要有注册和登录功能. 微博最核心的功能是信息的发表,这个功能包括许多方面,包括:数据库访问,前端显示等. 一个完整的微 ...

  5. Node.js学习笔记8

    Node.js学习笔记8 HTTP服务器与客户端 Node.js的http模块,封装了一个高效的HTTP服务器和一个简易的HTTP客户端 http.server是一个基于事件的HTTP服务器,核心由N ...

  6. node.js学习笔记5——核心模块1

    node.js学习笔记5--核心模块1 Node.js核心模块主要内容包括:(1)全局对象 (2)常用工具 (3)事件机制 (4)文件系统访问 (5)HTTP服务器与客户端 一: 全局对象 Node. ...

  7. node.js 学习笔记(二)模板引擎和C/S渲染

    node.js 学习笔记(二)模板引擎和C/S渲染 文章目录 node.js 学习笔记(二)模板引擎和C/S渲染 一.初步实现Apache功能 1.1 使用模板引擎 1.2 在 node 中使用模板引 ...

  8. 唤醒手腕 - 前端服务器端开发 Node.Js 学习笔记(学习中,更新中)

    唤醒手腕 - Node.Js 学习笔记 唤醒手腕个人的学习记录,时间在2021年12月13日 ~ 2021年12月14日,学习方式看官方文档和B站视频,如有错误或者代码问题的地方,欢迎C站大佬能够帮忙 ...

  9. Vue.js 学习笔记 五 常用的事件修饰符

    介绍几个常用的事件修饰符 直接上代码 <div id="divApp"><div class="divColor" v-on:click=&q ...

  10. node.js学习笔记Day2

    目录 第一部分:用npm安装mysql模块 第二部分:在项目内创建 第三部分:引用opreateDB方法 第四部分:解决异步方法的问题 第五部分:关于热启动 第六部分:关于接收参数和带参查询数据 今天 ...

最新文章

  1. An Algorithm Summary of Programming Collective Intelligence
  2. OpenGL Texture Coordinates纹理坐标的实例
  3. Content management workbench DMWB
  4. 【渝粤教育】广东开放大学 企业项目报表分析 形成性考核 (35)
  5. fdtd中时间监视器怎么放_利用FDTD软件仿真拓扑光子(六)-单向传播仿真与软件设置...
  6. php xml 实例教程,php解析xml方法实例详解,解析xml实例详解_PHP教程
  7. Hawk 浩客 K950 3.0 免开机互拷易驱线 新产品 新科技
  8. cad怎样弄出放线的坐标_利用CAD绘制全站仪放线用的坐标点
  9. elasticsearch-mathc和term的区分
  10. JavaScript之事件委托和事件代理
  11. js进行txt文件下载方式或oss文件访问下载跨域解决
  12. Docker与Dragonfly详细多机部署
  13. springboot配置https
  14. antd自定义样式主题
  15. js 数组entries迭代方法
  16. 不联网安装 SQL server 2012 的问题
  17. 浙商银行入职计算机考试,浙商银行计算机笔试心得
  18. 全球都在研发的虚拟气候设备,是治愈“失眠”的最优解吗?
  19. 小程序模拟表格-可左右滑动
  20. 迅睿cms微信抖音小程序生成管理系统V1.0开源

热门文章

  1. macOS安装wget
  2. ADRC自抗扰控制,有手就行
  3. 【dede】列表页调用二三级导航栏
  4. spring boot企业合同管理系统毕业设计源码161456
  5. html 科赫雪花,CSS3 科赫雪花分形V1
  6. R语言epiDisplay包的codebook函数计算dataframe中所有变量的基础描述统计信息和一维列联表(频数表)、连续变量(样本数、均值、中位数、标准差、最大值、最小值)、离散变量(列联表)
  7. php云erp进销存v8手机端,PHP仿金蝶云ERP进销存V8网络多仓版源码
  8. 点可云ERP-V7.0-国产免费开源的ERP进销存系统 附带安装详细教程
  9. Oracle Update语句的几种方式
  10. 分享倒计时小工具(两个)