WebSocket实现实时通信

WebSocket 是一种数据通信协议,也是用于客户端和服务端数据通信,类似于我们常见的 http

既然有 http,为啥还要 WebSocket
http 通信是单向的
请求 + 响应
没有请求也就没有响应

初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。

举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。

轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。

WebSocket 协议在 2008 年诞生,2011 年成为国际标准。所有浏览器都已经支持了。

它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

简单理解:

  1. HTTP 打电话:
    我问一句
    你回答一句
    没有提问就没有回答,即便对方主动给你说话,我也是个聋子听不见

  2. WebSocket 打电话:
    双向对话
    在这里插入图片描述

HTTP 和 WebSocket 通信模型

其他特点包括:

(1)和 HTTP 一样属于应用层协议,也是建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段(第 1 次建立连接)采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源跨域限制,客户端可以与任意服务器通信。

WebSocket 不是用来代替 HTTP 的,它是用来解决实时通信的业务场景。如果业务不需要实时性,那就没必要使用 WebSocket。

WebSocket 也是有资源消耗的,因为它要实时通信,也是需要和服务端保持一定的通信连接。

WebSocket 也是需要服务端配合才能使用。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

(7)浏览器专门为 WebSocket 通信提供了一个请求对象 WebSocket

XmlHttPRequest 请求对象,发起 HTTP 协议请求

ws://example.com:80/some/pathhttp https
ws   wss

使用原生 WebSocket(了解)

参考文档:

MDN - WebSocket

浏览器为 HTTP 通信提供了 XMLHttpRequest 对象,同样的,也为 WebSocket 通信提供了一个通信操作接口:WebSocket。

通信模型:

拨号(建立连接)
通话(双向通信)
结束通话(关闭连接)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><script>// WebSocet 通信模型// 1. 拨打电话(建立连接)// 注意:wss://echo.websocket.org 是一个在线的测试接口,仅用于 WebSocket 协议通信测试使用var ws = new WebSocket("wss://echo.websocket.org");// 当连接建立成功,触发 open 事件ws.onopen = function(evt) {console.log("建立连接成功 ...");// 连接建立成功以后,就可以使用这个连接对象通信了// send 方法发送数据ws.send("Hello WebSockets!");};// 当接收到对方发送的消息的时候,触发 message 事件// 我们可以通过回调函数的 evt.data 获取对方发送的数据内容ws.onmessage = function(evt) {console.log("接收到消息: " + evt.data);// 当不需要通信的时候,可以手动的关闭连接// ws.close();};// 当连接断开的时候触发 close 事件ws.onclose = function(evt) {console.log("连接已关闭.");}
</script>
</body>
</html>

在这里插入图片描述
怎么查看 WebSocket 请求日志?
在这里插入图片描述
朝上的绿色箭头是发出去的消息

朝下的红色箭头是收到的消息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用socket.io搭建一个实时聊天机器人

一、安装socket.io npm i socket.io --save二、使用 第一种&#xff1a;服务端使用原生node // 创建http服务器 const http require(http) var fs require(fs) const app http.createServer()app.on(request, (req, res) > {fs.readFile(__dirname /index.html, funct…

真随机和伪随机区别_用骰子DIY真随机助记词 | 火星号精选

免责声明&#xff1a;本文旨在传递更多市场信息&#xff0c;不构成任何投资建议。文章仅代表作者观点&#xff0c;不代表火星财经官方立场。小编&#xff1a;记得关注哦

EasyDarwin开源流媒体服务器性能瓶颈分析及优化方案设计

EasyDarwin现有架构介绍 EasyDarwin的现有架构对网络事件的处理是这样的&#xff0c;每一个Socket连接在EasyDarwin内部的对应存在形式就是一个Session&#xff0c;不论是RTSP服务对应的RTSPSession&#xff0c;还是HTTP服务对应的HTTPSession&#xff0c;都是一个继承自Task类…

Vue 中的组件缓存

一、介绍 先来看一个问题&#xff1f; 从首页的区块链模块切换到文章详情页面&#xff0c;再从文章详情页面回到首页&#xff0c;我们发现首页重新渲染原来的状态没有了&#xff0c;又回到了推荐模块。 首先&#xff0c;这是正常的状态&#xff0c;并非问题&#xff0c;路由…

SQLlite 分页

如果我要去11-20的Account表的数据 Select * From Account Limit 9 Offset 10; 以上语句表示从Account表获取数据&#xff0c;跳过10行&#xff0c;取9行 嗯&#xff0c;我觉得这个特性足够让很多的web中型网站使用这个了。 也可以这样写 select * from account limit10,9和上面…

thief book怎么用_战略管理工具箱--30个好用的战略管理好工具

-原创转载请告知-十年多年前&#xff0c;在上海做咨询的时候&#xff0c;曾经在书店买了一本《战略管理工具箱》的Poket小书&#xff0c;一直看一直看&#xff0c;里面包含常用的战略管理工具&#xff08;30个&#xff09;&#xff0c;虽然不用都用上&#xff0c;用其中几个常用…

Vue中使用axios的响应拦截器处理请求失败的情况(处理token过期问题)以及 登录成功跳转回原来页面问题

参考axios官方文档 // 响应拦截器 // Add a response interceptor request.interceptors.response.use(// 在2xx范围内的任何状态代码都会触发此函数&#xff0c;这里主要用于处理响应数据response > {return response},// 任何超出2xx范围的状态码都会触发此函数&#xff0…

cocoapods 命令

1.使用CocoaPods a 新建一个项目&#xff0c;名字cocoapods b 终端中&#xff0c;cd到项目总目录&#xff08;直接拖过来&#xff09; [objc] copy? cd /Users/pengjian/Desktop/cocoapodsc 建立Podfile&#xff08;配置文件&#xff09; 接着上一步&#xff0c;终端输入 v…

Vue项目中使用 路由导航守卫 处理页面的访问权限

参考Vue-Router官方文档 Vue-Router导航守卫 效果展示 1、给需要登录状态才能访问的页面路由对象的 meta 中添加配置属性 { // 小智同学name: user-chat,path: /user/chat,component: () > import(/views/user-chat),meta: { requiresAuth: true } },2、通过路由拦截器…

失败,因为你其实太过傲慢

因为你太过傲慢&#xff0c;不肯放低姿态去向他人学习&#xff0c;勤加练习&#xff0c;所以失败。转载于:https://www.cnblogs.com/panie2015/p/5667464.html

Uniapp学习笔记(数据展示、数据循环、条件编译、计算属性、组件的使用、组件插槽、生命周期)

1.项目准备 1.1开发方式 uni-app为我们提供2种开发方式&#xff1a; 使用DCloud公司提供HBuilderX工具来快速开发&#xff1b; 使用脚手架来快速开发&#xff08;我们这次项目使用此方式&#xff09;&#xff1b; 1.2脚手架搭建项目 全局安装&#xff0c;如果你以前安装过…

word图片嵌入式为何只能看到一部分_Word排版的正确姿势!(Word论文排版教学)...

Hello&#xff0c;最近正值着手写毕业论文的初期&#xff0c;趁着这个时间点&#xff0c;我做了一个简易的&#xff0c;简单的&#xff0c;0基础的Word论文排版教学&#xff0c;帮助你在撰写论文的时候不再花费大量的时间浪费在调整格式里。初次做视频&#xff0c;难免有错误&a…

云计算三种服务模式SaaS、PaaS和IaaS及其之间关系(顺带CaaS、MaaS)

云计算架构图 很明显&#xff0c;这五者之间主要的区别在于第一个单词&#xff0c;而aaS都是as-a-service&#xff08;即服务&#xff09;的意思&#xff0c;这五个模式都是近年来兴起的&#xff0c;且这五者都是云计算的落地产品&#xff0c;所以我们先来了解一下云计算是什么…

uni-ui介绍uni-api

一、uni-ui介绍 安装 二、uni-api 解决uni-app中的跨域问题&#xff1a; "h5" : {"router" : {"mode" : "hash"},"devServer": {"https": false,"proxy": {"/web": {"target": …

一、uniapp项目(封装异步请求、moment.js时间处理、封装手势滑动组件、下载图片到本地)

一、封装异步请求&#xff1a; 1. 为什么要封装&#xff1f; 2. 封装的思路 export default (params) > {// 显示加载中uni.showLoading({title: "加载中"})return new Promise((resolve, reject) > {wx.request({...params,success(res) {resolve(res)},fail…

.net中如何发送HTTP请求网络资源

应用场景 应该说只要是需要通过发送Http请求获取网络资源的地方都要使用它&#xff0c;网络资源可以是指以URI来表示的资源&#xff0c;比如web api接口等。 HttpWebRequest .net2.0 ~ .net4.0使用HttpWebRequest 代码如下&#xff1a; 1 //.net2.0 ~ .net4.0使用HttpWebReque…

二、uniapp项目(分段器的使用、scroll-view、视频下载、转发)

一、分段器组件的使用 uniapp官方文档 <template><view class"category"><view class"category_tab"> <view class"category_tab_title"><view class"title_inner"><uni-segmented-control :curr…

problem b: 一年中的第几天_第九届蓝桥杯B组试题

1.标题&#xff1a;第几天2000年的1月1日&#xff0c;是那一年的第1天。那么&#xff0c;2000年的5月4日&#xff0c;是那一年的第几天&#xff1f;注意&#xff1a;需要提交的是一个整数&#xff0c;不要填写任何多余内容。“手动分割”大小月判断&#xff1a;https://jingyan…

一、express 路由 todos案例

一、express路由 动态路由参数 params 路径参数 query 二、 todos案例 2.1 准备工作 新建一个文件夹01-demo执行npm init -y 生成package.json配置文件执行npm install express --save 安装express新建app.js文件&#xff0c;这是程序的入口文件新建db.json文件&#xff0…

二、express中间件

一、中间件引入 实现加入日志模块功能&#xff1a; 1. 我们能想到的方案&#xff1a; 将日志输出代码封装到函数中&#xff0c;然后需要日志输出的地方调用这个函数即可。 app.js文件&#xff1a; const express require(express)const app express()const myLogger (r…