深入理解WebSocket,让你入门音视频

news2024/12/26 9:31:28

😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD
如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊 座右铭:不想当开发的测试,不是一个好测试✌️。
如果感觉博主的文章还不错的话,还请点赞、收藏哦!👍

原文在这里https://testerhome.com/topics/34427

文章目录

  • WebSocket浅析
    • 一、 WebSocket概念
    • 二、为什么需要WebSocket协议
      • 2.1 `WebSocket`的出现主要是为了弥补HTTP半双工通信的缺陷。
      • 2.2 websocket与http有着良好的兼容性
    • 三、WebSocket通信原理
    • 四、WebRTC中websocket的使用
    • 五、使用 node.js 实现简易聊天室

WebSocket浅析

一、 WebSocket概念

WebSocket是一种在单个TCP连接上进行全双工通信的网络协议。意为:经过一次TCP握手就可以直接创建持久性连接,进而可实现服务端和客户端双向数据传输。websocket的协议标识是ws和wss

websocket的应用场景:

  • 在线聊天
  • 协作文档编辑
  • 大型多人在线游戏
  • 股票交易应用
  • webrtc

二、为什么需要WebSocket协议

2.1 WebSocket的出现主要是为了弥补HTTP半双工通信的缺陷。

在websocket没有出现之前,为了让http能够实现即时通信,前辈们也做了一些研究,常用的有三种方法:

  1. HTTP轮询

    HTTP轮询(polling):在固定的时间间隔,由浏览器向服务器发起http请求,无论服务器中的数据有没有更新,都会给客户端作出响应。

    但如果知道信息交付的精确间隔,那么轮询也是一个好的方案,但对于一些实时的数据是不能预测的,所有就会导致发出一些不必要的请求。

  2. 长轮询

    长轮询( long polling):客户端向服务端请求信息,并在设定的时间段内打开一个连接。服务器如果没有任何信息,会保持请求打开,直到有客户端可用的信息,或者直到指定的超时时间用完为止。

    长轮询中客户端必须频繁地重连到服务器以读取服务端的信息,会增大服务端到压力。

  3. 流化技术

    客户端向服务端发起一个长连接请求,服务端收到请求后响应它并不断更新连接状态,以确保连接在客户端与服务端之间一直有效。服务端可以通过这个连接将数据主动推送到客户端。

    但存在一个问题:每当服务器有需要交付给客户端的信息时,它就会更新响应,但是服务器从不发出完成http响应,从而导致连接一直打开,在这种情况下,代理和防火墙可能会缓存一个响应,就会导致信息交付的延迟增加。

以上三种方法都实现了近乎实时的通信,但都涉及HTTP请求和响应,当然也包含了许多附加和不必要的延迟,此外,在每一种情况下,客户端必须主动给服务器发送消息,且客户端都必须等待请求返回,才能发出后续的请求,再一次增加了延迟。

2.2 websocket与http有着良好的兼容性

默认端口是80和443, 并且握手阶段采用HTTP协议,因此握手的时候不容易屏蔽,能通过各种的HTTP代理。

三、WebSocket通信原理

以七牛webrtc demo为例:https://demo-rtc.qnsdk.com/

在这里插入图片描述

详解:

每个WebSocket连接都开始于一个http请求,这个请求和其他请求类似,但是websocket连接请求中包含一个特殊的首标,Upgrade:websocket,意为:客户端想将HTTP协议升级为websocket协议。如果服务端同意,则响应Connection:Upgrade,同时 101 Switching Protocols 也表示协议切换成功,这个过程叫做初始握手

但为了成功地完成握手,websocket服务器必须根据客户端请求消息中的Sec-WebSocket-Key,响应SHA-1的信息摘要,即:Sec-WebSocket-Accept 。其中:Sec-WebSocket-Key是一个随机字符串,服务端接收到Key之后,会对其进行加密,并进行base-64编码,然后将结果响应给客户端;客户端将Key使用同样的加密算法进行加密并进行base-64编码,当得到的值与服务端响应的值保持一致时,表示真正的握手成功。

至此,HTTP已经完成了它所有的工作,接下来就是完全按照Websocket协议进行通信。

四、WebRTC中websocket的使用

在webrtc中websocket充当信令服务器,那何为信令服务器?信令可理解为信息的传递或者命令的执行,主要是传输用户的一些信息。在webrtc中如果没有信令服务器,webrtc之间是不能够通信的。

在这里插入图片描述

蓝色区域表示发送端(Caller)和接收端(Callee),如果两者想要传递媒体数据,那么有两个信息必须经过信令服务器交换;

1)媒体信息:通过SDP协议进行交换,SDP是一个描述多媒体连接内容的协议,其中包含了分辨率、编解码方式、格式、是否支持音频、视频等。例如,Caller想给Callee发一个H264的视频,需要先问一下Callee能不能解H264的视频,如果可以解码,则可以通信;如果Callee只能解H265的视频,则不可通信。

2)网络信息:通常指的是ip地址、端口、以及数据存放地址,我们称之为ICE,这是一个基于offer/answer模式解决NAT穿越的协议集合。在ICE中主要包含STUN+TURN主要协议。当Callee想要接收数据时,需要将所有的网络相关的信息传到信令服务器,信令服务器再转发给Caller,Caller拿到信息之后,发现处于同一个局域网,则可通信,如果不在同一个局域网,则通过TURN协议进行NAT穿越,再利用Relay转发,两者即可通信。

因为TCP的超时时间为60s,如果要保持长连接的话,最好加一个ping/pong的心跳检测,就是服务端给客户端发一个ping的消息(绿色),客户端再给服务端发送一个pong的消息(红色),就是在server端加一个定时调用函数setInterval,即可实现

setInterval(() => {
        connect.send('ping');
    }, 3000);

在这里插入图片描述

五、使用 node.js 实现简易聊天室

第一步:实现服务器

安装第三方依赖库:nodejs-websocket

具体实现如下

const ws = require('nodejs-websocket')
const PORT = 3003
const TYPE_ENTER = 0
const TYPE_LEAVE = 1
const TYPE_MSG = 2

//1. 记录当前连接上来的总的用户数量
let count = 0
//2.conn每个连接到服务器的用户,都会有一个conn
const server = ws.createServer(conn => {
    console.log('有用户进来')
    count++
    conn.userName = `用户${count}`
   
    broadcast({
        type:TYPE_ENTER,
        msg:`${conn.userName}进入了聊天室`,
        time:new Date().toLocaleTimeString()
    })

    //每当接收到用户传递过来的数据,这个text事件会被触发
    conn.on('text',data =>{
        console.log('接受到用户的数据',data)  
        broadcast({
            type:TYPE_MSG,
            msg:data,
            time:new Date().toLocaleTimeString()
        })
    })
  
    conn.on('close',() => {
        console.log('连接断开了')
        count--
        broadcast({
            type:TYPE_LEAVE,
            msg:`${conn.userName}离开了聊天室`,
            time:new Date().toLocaleTimeString()
        })

    })
    conn.on('error',() => {
        console.log('用户连接异常')
    }) 
})

// 通过广播,给所有的用户发送消息
function broadcast(msg){
    //server.connections:表示所有用户
    server.connections.forEach(item => {
        item.send(JSON.stringify(msg))
    })
}
server.listen(PORT,() => {
    console.log('websocket服务启动成功了,监听了端口' + PORT)
})

第二步:实现客户端

<html>
    <head>
        <title>在线聊天室</title>
    </head>
    <body>   
        <input type="text" placeholder="输入内容">
        <button>发送请求</button>
        <!--接收消息-->
        <div></div>
        <script>     
            var input = document.querySelector('input');
            var button = document.querySelector('button');
            var div = document.querySelector('div');
            const TYPE_ENTER = 0
            const TYPE_LEAVE = 1
            const TYPE_MSG = 2
             //创建websocket对象
            var socket = new WebSocket('ws://localhost:3003');
            socket.addEventListener('open',function(){
                div.innerHTML = '连接服务器成功'

            })
            //主动给websocket服务发送消息
            button.addEventListener('click',function(){
                var value = input.value
                socket.send(value)
                input.value = ''
            })
            socket.addEventListener('message',function(e){
                var data = JSON.parse(e.data)
                var dv = document.createElement('div')
                dv.innerText = data.msg +'------'+data.time
                if(data.typy === TYPE_ENTER){
                    dv.style.color = 'green'
                }else if(data.typy === TYPE_LEAVE){
                    dv.style.color = 'red'
                }else{
                    dv.style.color = 'blue'
                }
                div.appendChild(dv)
            })
            socket.addEventListener('close',function(){
                div.innerHTML = '服务断开链接'
            })
        </script>

    </body>
</html>

demo展示:

在这里插入图片描述

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

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

相关文章

Android 使用okhttp监控网络数据

这里使用Okhttp写了一个demo来监听网络请求过程中的一系列数据&#xff0c;包括当前网络类型、请求体、响应体大小&#xff0c;url&#xff0c;请求方式&#xff0c;当然还有本次核心获取域名解析时长&#xff0c;建立连接时长&#xff0c;保持连接时长&#xff0c;请求总时长这…

《C++ Primer》--学习6

IO库 IO类 为了支持使用宽字符的语言&#xff0c;标准库定义了一组类型和对象来操纵 wchar_t 类型的数据。宽字符版本的类型和函数的名字以一个 w 开始。wcin wcout 和 wcerr 是分别对应 cin cout 和 cerr 的宽字符版本对象 IO类型之间的关系 类型 ifstream 和 istringstream…

Vuex 状态管理 —— 核心store

在上一篇当中讲到关于接口请求函数获取数据&#xff0c;拿到 response.data &#xff0c;简化调用&#xff0c;那么在拿到请求的响应数据之后呢&#xff1f;在前面讲到组件间的通信当中&#xff0c;如父子通信(父传子props,子传父$emit)以及组件与组件之前不能通过直接通信&…

【33】用 Docker 部署 Prometheus + Grafana 监控平台

一. Docker部署Prometheus 1.1 下载prom/prometheus镜像 docker pull prom/prometheus 1.2 启动prometheus容器 docker run -itd --nameprometheus -p 9090:9090 prom/prometheus 打开本地http://localhost:9090/ 说明启动成功 1.3 将容器的配置文件复制出来 docker cp pr…

深入理解深度学习——GPT(Generative Pre-Trained Transformer):在不同任务中使用GPT

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 GPT预训练语言模型作为一个标准的语言模型&#xff0c;其输入和输出是固定的&#xff0c;即输入一个词序列&#xff0c;输出该词序列的下一个词。《深入理解深度学习——GPT&#xff08;Generative Pre-Trained Transf…

GAMES101 笔记 Lecture06 Rasterization2(Antialiasing and Z-Buffering)

目录 Antialiasing(反走样)Sampling is Ubiquitous in Computer Graphics(采样在计算机图形学中无处不在)Sampling Artifacts(Errors or Mistakes or Inaccuracies) in Computer Graphics(在计算机图形学中采样的瑕疵)Jaggies(Staircase Pattern)锯齿Moire Pattern in Imaging(…

[进阶]TCP通信实现BS架构,网站开发的原理,线程池优化BS架构

代码演示如下&#xff1a; 服务端 public class Server {public static void main(String[] args) throws Exception{System.out.println("服务端开启&#xff01;");//1.创建ServerSocket的对象&#xff0c;同时为服务端注册端口。ServerSocket serverSocket new…

Wang tile(王浩瓷砖)算法解决贴图平铺重复问题

Wang tile(王浩瓷砖) 大家好&#xff0c;我是阿赵。这次来解决一个贴图重复的问题。 一、问题 做一篇很大面积的草地&#xff0c;一般思路是建立一个地面的面片&#xff0c;然后在材质球里面给他做一个Tiling平铺&#xff0c;增大重复次数。这样整个地面都可以被草地的贴图铺满…

Spring Boot 如何使用 @Validated 注解进行数据校验

Spring Boot 如何使用 Validated 注解进行数据校验 在开发应用程序时&#xff0c;数据校验通常是不可避免的。Spring Boot 提供了许多选项来验证应用程序中的数据&#xff0c;其中一个选项是使用 Validated 注解。本文将介绍如何使用 Validated 注解进行数据校验&#xff0c;并…

操作系统-操作系统结构

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

【计算机组成原理】Yy-z02硬布线模型机设计

目录 一、Yy-z02模型机的系统结构 二、Yy-z02模型机的数据通路 三、Yy-z02模型机的指令执行 四、Yy-z02模型机的硬布线控制器 一、Yy-z02模型机的系统结构 指令系统的实现 <--- 构造它的硬件系统 硬件系统构造过程&#xff1a; 分析指令格式和各指令的功能确定部件连…

《机器学习公式推导与代码实现》chapter16-集成学习对比与调参

《机器学习公式推导与代码实现》学习笔记&#xff0c;记录一下自己的学习过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 集成学习&#xff1a;对比与调参 虽然现在深度学习大行其道&#xff0c;但以XGBoost、LightGBM、CatBoost为代表的Boosting算法仍有其广泛的用武…

【Applied Algebra】有限状态机和模型检测初探

【Applied Algebra】有限状态机和模型检测初探 摘要:有限状态机(FSM)和模型检测有密切的联系。有限状态机提供了一种用状态转换图来表示系统行为的简单方法。而模型检测是一种针对形式化模型&#xff08;例如有限状态机&#xff09;的验证技术&#xff0c;旨在自动验证模型是否…

css基础(一)

目录 思维导图 ​一、css简介 1.1 css语法规范 1.2 css代码规格 1. 样式格式书写 2. 样式大小写 3. 空格规范 二、css选择器 2.1 CSS 选择器的作用 2.2 选择器分类 2.3 标签选择器 2.4 类选择器 2.4 类选择器-多类名 2.5 id 选择器 2.6 通配符选择器 2.7 基础选择器总结 三、CS…

D. Running Miles(公式转换)

Problem - D - Codeforces 有一条长为n的街道&#xff0c;其中第i个景点距离街道起点i英里。第i个景点的美丽值为bi。你想要在离街道起点l英里和r英里处开始和结束慢跑。当你跑步时&#xff0c;你会看到你经过的景点&#xff08;包括起点和终点处的景点&#xff09;。你对沿途慢…

Microsoft365有用吗?2023最新版office有哪些新功能?

office自97版到现在已有20多年&#xff0c;一直是作为行业标准&#xff0c;格式和兼容性好&#xff0c;比较正式&#xff0c;适合商务使用。包含多个组件&#xff0c;除了常用的word、excel、ppt外&#xff0c;还有收发邮件的outlook、管理数据库的access、排版桌面的publisher…

CENTOS上的网络安全工具(二十五)SPARK+NetSA Security Tools容器化部署(1)

一、第三代YAF YAF&#xff08;Yet Another Flowmeter&#xff09;是作为CERT NetSA安全工具套件的传感器部分存在的&#xff0c;支持输入实时数据流和PCAP文件&#xff0c;解析并输出流数据&#xff0c;或针对特定协议的深包检测元数据。目前&#xff0c;YAF在整个系统的作用如…

【js30天挑战】第三天:css变量

效果图&#xff1a; 学到的东西 HTML&CSS部分 css变量写法 //定义:root{ //:root 是 CSS 选择器&#xff0c;它匹配文档的根元素&#xff0c;也就是 html 元素。 --base:#FF0081;--spacing:10px;--blur:0px;} //使用img {filter: blur(var(--blur));}input: range类型…

Redis - 数据结构类型及使用场景详解(一)

一. 简介 Redis 是由 Salvatore Sanfilippo 编写的一个key-value存储系统&#xff0c;是跨平台的非关系型数据库。Redis是一个开源的&#xff0c;使用C语言编写的&#xff0c;遵守BSD协议&#xff0c;支持网络&#xff0c;可基于内存&#xff0c;分布式&#xff0c;可选持久性的…

EMC学习笔记(八)阻抗控制(二)

阻抗控制&#xff08;二&#xff09; 1.差分阻抗控制1.1 当介质厚度为5mil时的差分阻抗随差分线间距的变化趋势1.2 当介质厚度为13mil时的差分阻抗随差分线间距的变化趋势1.3 当介质厚度为25mil时的差分阻抗随差分线间距的变化趋势 2.屏蔽地线对阻抗的影响2.1 地线与信号线之间…