WebSocket 协议简介

2023-11-10

一、什么是WebSocket

WebSocket是一种在单个TCP连接上进行全双工通讯的协议。
WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。所有浏览器都已经支持了。

二、为什么需要WebSocket

相对于HTTP协议,只能由客户端发起,WebSocket协议允许服务器主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种,使得客户端和服务器之间的数据交换变得更加简单。
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。

在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

三、http和WebSocket 关系

http和WebSocket都是建立在TCP协议之上的。
WebSocket是基于Http协议的,或者说借用了Http协议来完成一部分握手,在握手阶段与Http是相同的。
这里写图片描述
实例:
一个典型的Websocket握手请求如下:

客户端请求

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

服务器回应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/

字段说明

Connection必须设置Upgrade,表示客户端希望连接升级。
Upgrade字段必须设置Websocket,表示希望升级到Websocket协议。即告诉Apache、Nginx等服务器,发起的是Websocket协议
Sec-WebSocket-Key是随机的字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1摘要,之后进行BASE-64编码,将结果做为“Sec-WebSocket-Accept”头的值,返回给客户端。如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。
Sec-WebSocket-Version
表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当弃用。
Origin字段是可选的,通常用来表示在浏览器中发起此Websocket连接所在的页面,类似于Referer。但是,与Referer不同的是,Origin只包含了协议和主机名称。
其他一些定义在HTTP协议中的字段,如Cookie等,也可以在Websocket中使用。
在以前 HTTP 协议中所谓的 keep-alive connection 是指在一次 TCP 连接中完成多个 HTTP 请求,但是对每个请求仍然要单独发 header;它们建立的“长连接”都是伪.长连接,只不过好处是不需要对现有的 HTTP server 和浏览器架构做修改就能实现。
WebSocket 解决的第一个问题是,通过第一个 HTTP request 建立了 TCP 连接之后,之后的交换数据都不需要再发 HTTP request了,使得这个长连接变成了一个真.长连接。但是不需要发送 HTTP header就能交换数据显然和原有的 HTTP 协议是有区别的,所以它需要对服务器和客户端都进行升级才能实现。

四、WebSocket 用法

以PHP为例:
比较简单的实现方式,安装SWOOLE扩展。借用官网(https://wiki.swoole.com/wiki/page/397.html),
服务端代码
websocket.php

$server = new swoole_websocket_server("0.0.0.0", 9501);

$server->on('open', function (swoole_websocket_server $server, $request) {
    echo "server: handshake success with fd{$request->fd}\n";
});

$server->on('message', function (swoole_websocket_server $server, $frame) {
    echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
    $server->push($frame->fd, "this is server");
});

$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});

$server->start();

启动

 php websocket.php  start

客户端代码:
https://www.kancloud.cn/yujc/swoole_note/383915

<html>
<head>
  <title></title>
  <meta charset="UTF-8">
  <script type="text/javascript">
  socket = new WebSocket('ws://服务器IP:9501/'); 
socket.onopen = function(evt) { 
    // 发送一个初始化消息
    socket.send('I am the client and I\'m listening!'); 
}; 

// 监听消息
socket.onmessage = function(event) { 
    console.log('Client received a message', event); 
}; 

// 监听Socket的关闭
socket.onclose = function(event) { 
    console.log('Client notified socket has closed',event); 
}; 

socket.onerror = function(evt) { 
    console.log('Client onerror',event); 
}; 

  </script>
</head>
<body>
<button  onclick="socket.send('我发信了')">发送</button>
</body>
</html>

点击“发送”,查看服务器信息,出现以下信息表示成功
这里写图片描述

参考文献
http://www.ruanyifeng.com/blog/2017/05/websocket.html
https://zh.wikipedia.org/wiki/WebSocket
https://wiki.swoole.com/wiki/page/479.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebSocket 协议简介 的相关文章

随机推荐

  • JavaScript reduce()方法详解与实现

    使用方法详解 reduce 方法在数组的每个元素上依次执行传入的 reducer 回调函数 并传入上一次计算的返回值 第一次运行回调函数的时候没有 上一次计算的返回值 调用reduce 方法的时候可以传一个初始值来代替 否则 数组的第一个元
  • MNIST数据集转换为图片数据集的样例程序

    一 编写背景 因为需要对接一个官方的编程API 本人需要自己按其要求搭建一个神经网络 以尝试调用某模块的工作 我参考了Tensorflow的参考书了解了MNIST数据集 然后我准备把MNIST数据集转换为图片格式 以适应API的要求 同样
  • 单片机笔记八:华大单片机报错(未定义__WEAKDEF)

    最近开始用华大的单片机 按照官方的例程做了一个工程模板 结果直接编译不过 而且一口气有30个错误 提示内容如下 WEAK void I2c0 IRQHandler void mcu common interrupts hc32l13x c
  • JavaSE——StringBuffer与StringBuilder拼接字符串详细解释

    目录 一 基本了解 1 1使用字符串频繁拼接会出现什么问题 1 2 了解StringBuffer 1 3 了解StringBuilder 1 4 StringBuffer与StringBuilder的区别 二 StringBuffer的使用
  • 额外函数_强化学习奖励函数塑形简介(The reward shaping of RL)

    RL背景 强化学习解决定义在马尔科夫过程 Makov Decision Processing MDP 下的连续决策问题 其中经典算法Q learning使用如下方程更新 值 策略 在状态s下采取行为a后的累计回报数学期望 Cumulated
  • C/C++使用libcurl库发送http请求(get和post可以用于请求html信息,也可以请求xml和json等串)

    C C 使用libcurl库发送http请求 get和post可以用于请求html信息 也可以请求xml和json等串 C 要实现http网络连接 需要借助第三方库 libcurl使用起来还是很方便的 环境 win32 vs2015 如果要
  • python基础(1)--对象、类、方法、库、函数

    几个概念的简单辨析 对象与类 一个独立的事物称为一个对象 对象具有一定的属性和功能 对象 属性 特征 方法 行为 类是对象的抽样化 类是对象的实例化 方法与函数 函数 通过 函数名 的方式进行调用 内置函数 匿名函数 递归函数 自定义函数等
  • R语言的排列组合函数:排列函数(permutations)和组合函数(combinations)

    R语言的排列组合函数 排列函数 permutations 和组合函数 combinations 排列函数 permutations 和组合函数 combinations 是R语言中用于处理排列和组合问题的常用函数 它们可以帮助我们生成和计算
  • 微信小程序开发(九):使用扩展组件库

    前端开发中离不开各种组件库 我最先接触的组件库还是Bootstrap 后来工作中又陆续使用了inoic ng zorro等各种不同的库 在微信小程序开发中也有多种组件库 这里记录其中几种不同组件库的使用方法 WeUI 这是微信官方推出的一款
  • 2023版golang面试题100道(合集)

    我已经从事后端开发很多年 近期花了大量时间整理了一份 golang面试题100道 涵盖了go开发需要掌握的基础知识 核心要点 题目的答案尽量做到简洁 条理性 golang面试题100道 最新完整合集目录 欢迎关注 回复 面试 即可随时阅读
  • MATLAB 判断字符串中是否含有特定的字符

    这个程序的目的是 逐行读取file txt文件中的字符串 并判断字符串中是否含有特定的字符 如果含有 再对字符串进行处理 然后写入到新的TXT文档中new file txt fid fopen D new file txt wt phns
  • 【好文鉴赏】初创公司到底值不值得去?从以下几点考虑

    关键词 初创公司 职业发展 就业 原文链接 https tech sina cn csj 2018 09 10 doc ihiixyeu5565677 d html https www zhihu com question 31272586
  • Unlit Shader下的Texture切换

    今天要实现一个贴图切换过渡的一个效果 Unlit的性能比较好 所以参考了网上一些Texture的shader之后 写了一下 具体内容 MixValue 来完成渐变效果 MixValue 1时为下面的Texture MixValue 0时为上
  • 巧用replit搭建免费的个人云服务器

    初识replit 被它的免费托管和域名服务所吸引 replit是个啥 在经过一番尝试后 发现这玩意儿挺有意思 佩服老外的想象力和创新力真强 竟还能搭建个人的云服务器 连域名都有了 这可真香 对个人开发者来说连云服务器都省了 想搭建个人网站或
  • 2021年PHP会被淘汰吗

    首先我可以确定的是 PHP肯定不会被淘汰 但是市场占有率肯定回不去以前的状态 以前PHP可以做网页的任何事 包括前端和接口 但是近几年前端的发展非常迅猛 angular vue和react三大前端框架的相继出现 使得前后端已经彻底分离了 所
  • 名人博客VS 博客名人

    不知从什么时候开始 似乎人人都成了blogger 有用的 没用的 快乐的 悲伤的 都会在自己的博客上贴出来 而那些曾经让我们感觉遥不可及的明星们也开始通过博客传递最新动态甚至爆料隐情 由此便催生了一系列跟博客相关的网络词汇 celeblog
  • Python :删除链表中重复的节点

    牛客网上的剑指 offer的在线编程 题目描述 在一个排序的链表中 存在重复的结点 请删除该链表中重复的结点 重复的结点不保留 返回链表头指针 例如 链表1 gt 2 gt 3 gt 3 gt 4 gt 4 gt 5 处理后为 1 gt 2
  • 前端搭建砸地鼠游戏(内附源码)

    The sand accumulates to form a pagoda 写在前面 功能介绍 页面搭建 样式设置 逻辑部分 完整代码 写在前面 上周我们实通过前端基础实现了打字通 当然很多伙伴再评论区提出了想法 后续我们会考虑实现的 今天
  • Vue+ElementUI中表格嵌套的使用方法

    需求 在开发中会遇到很多表格嵌套表格的使用 一个父级表格通过展开行要打开子级的表格 如果利用官网中的展开行的方式去实现其实是有点困难的 首先实现行展开 这个是用到了elementUI中的一个属性通过设置 type expand 和 Scop
  • WebSocket 协议简介

    一 什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通讯的协议 WebSocket通信协议于2011年被IETF定为标准RFC 6455 并由RFC7936补充规范 WebSocket API也被W3C定为标准