WebSocket小叙

概述

刚看到WeSocket的时候,我以为是HTTP相关,但是在前两天搭了一个简单的Client之后, 我发现这不就是TCP长连接么? 建立连接->通信->断开连接. 直到今天, 我在调试的时候, 发现发出了HTTP请求, 我想, 事情可能不是我想的那样.

先来简单描述一下当时的情况

我用Python代码简单打了一个WebSocket 客户端, 想着试一试, 代码很简单, 就是这:

import websocket
import threading
import timeclass Status:INIT = 'init'OPENED = 'opened'CLOSED = 'closed'class WSTest:def __init__(self):self.thread = Noneself.ping_thread = Noneself.ws = Noneself.status = Status.INITdef send_message(self, message) -> bool:if self.status != Status.OPENED:return Falseself.ws.send(message)return Truedef close(self):self.ws.close()# 等待关闭for i in range(200):time.sleep(0.02)if self.status == Status.CLOSED:breakif self.status != Status.CLOSED:returnif self.ping_thread and self.ping_thread.is_alive():self.ping_thread.join()def run(self):def on_message(ws, message):print(message)def on_error(ws, error):print(error)def on_close(ws):print('关闭连接')self.status = Status.CLOSEDdef on_open(ws):self.status = Status.OPENEDself.ws = websocket.WebSocketApp("ws://echo.websocket.org",on_open=on_open,on_message=on_message,on_close=on_close,on_error=on_error)self.ping_thread = threading.Thread(target=self.ws.run_forever, args=(None, None, 2, 5))self.ping_thread.start()if __name__ == "__main__":ws = WSTest()ws.run()while True:s = input()if s == 'close':breakws.send_message(s)ws.close()

上面的ws://echo.websocket.org 是一个测试用的域名,你发送什么过去,他就会返回什么. 到这里我简单运行了一下,还可以.本来我想简单搭一个,能调通就得了呗,但是,手贱的我打开了wireshark. 我想看一下它的网络连接.

wireshark抓包查看

首先,找到域名的IP

找到IP后就可以直接对IP进行过滤,找到接收和发送的数据包.直接过滤所有DNS解析请求,查找指定域名.

在这里插入图片描述

然后,针对地址对请求进行过滤

在这里插入图片描述

来来来,看到了什么?前面三个TCP请求是三次握手的请求,在三次握手之后的第一个请求是什么,HTTP???

看一下它的请求内容:

在这里插入图片描述

看到第一个Upgrade之后,我仿佛懂了.这个字段的含义是要将协议升级.后面跟着的就是websocket了,再看一下服务器的response.(后面那个TCP请求可以跳过,就是服务器告诉你它收到了).

在这里插入图片描述

响应内容虽然有不明白的地方,但是大概看来,是同意升级协议的意思了.再然后才是websocket通信内容,以及最后的挥手告别.

也就是说,websocket虽然能够实现双向通信,但是它的连接建立是从HTTP开始,然后升级协议来的??

所以websocket的通信流程是:

  1. 三次握手建立TCP通信
  2. 发起HTTP请求,升级为websokcet协议
  3. 开始websocket通信
  4. 断开连接

如果把中间的websocket去掉,那就完全是HTTP协议了. 没想到websocketHTTP是兄弟俩.

思考

既然WebSocket是基于HTTP协议建立的, 那么他的出现就一定是在HTTP之后, 这就说明它一定是为了解决HTTP的某些问题而出现的. 很显然: HTTP的单向通信限制, 服务器不能主动联系客户端

HTTP协议本身就是基于TCP的, 而TCP本身就是全双工通信的. 这感觉就像是他们借用了一下HTTP, 然后说咱们接下来就都用WebSocket吧.

那么问题来了, 既然要实现这种长连接, 为什么还要借助HTTP之手, 直接TCP建立连接不行么? 查了一下, 发现是为了兼容. 因为WebSocket就是为了解决HTTP协议问题, 也就是说主要运行在之前HTTP的场景中, 而为了兼容现有浏览器的握手规范, 所以借助了HTTP协议来完成握手.

WebSocket协议是: wswss. 其区别与 httphttps 相同. wss 就是在 ws 的通信过程中再套一层TLS/SSL 协议.

那么WebSocket有哪些应用场景呢?

可以这么说, 在原来使用HTTP协议进行轮训的场景, 都可以使用WebSocket替换.

  • 在线聊天
  • 直播
  • 在线多人游戏
  • 等等…

最后, 记一下建立连接的HTTP请求的头信息

request

  • connection: Upgrade 升级协议
  • Upgrade: websocket 指定升级为WebSocket协议
  • Sec-WebSocket-Key: 用于判断客户端是否有权升级协议
  • Sec-WebSocket-Version:指定WebSocket 版本

response

  • Upgrade: websocket 成功升级协议
  • Sec-WebSocket-Accept: 通过Sec-WebSocket-Key计算得来

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

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

相关文章

PHP实现RPC(简版)

概述 RPC这个东西是什么? 第一次听说他, 还要在它的前边加个G, 当时我以为GRPC是一项技术, 后来才知道, 并不是这样. GRPC只是RPC的谷歌实现. 谷歌搜了一下, RPC就是一种: 远程函数调用, 看到这里, 我已经等不及了, 不往下看了, 先自己实现一个. 如果只给你这样一个概念, 如…

GC算法-复制算法

概述 复制算法就是将内存空间二等分, 每次只使用其中一块. 当执行GC时, 讲A部分的所有活动对象集体移到B中, 就可以讲A全部释放. 画个图就是: ​ 在执行GC前, 内存长这样: ​ 当执行GC后, 内存就变成这样了: 还记得标记清除算法的问题是什么吗? 内存碎片化严重. 现在好了, …

GC算法-标记压缩算法

概述 还记得标记清除和复制算法的问题么? 堆使用效率低和碎片化问题. 那么有没有能够利用整个堆, 有没有内存碎片化问题的算法呢? 这就是标记压缩算法了. 简单来说, 标记压缩算法就是将堆中的所有活动对象整体向左移, 将对象间的空隙消除. 在GC执行前的内存: GC执行后的内…

PHP usort 函数底层排序

引出 最近在一个项目中, 需要对一个数组的顺序进行调整, 允许手动将某一个元素提到数组的开头位置. 在这里, 使用了PHP中的usort函数进行了数组的排序, 代码大致如下: usort($arr, function ($a, $b){// 这里添加了 order 字段, 默认为0, 将order大的提到前边return $b[order…

密钥交换算法: 迪菲-赫尔曼算法

概述 迪菲-赫尔曼算法用于通信双方交换密钥. 还记得之前介绍HTTPS协议的时候, 提到需要先通过对方公钥来进行密钥的交换, 然后再通过密钥对通信内容进行加密. 迪菲-赫尔曼算法就是用于交换密钥的. . 此算法与非对称加密算法不同哦. OK, 一起来看看吧. 引入 在正式介绍迪菲-…

纠错码简介

纠错码是个什么东西 引出 网络中的通信基于TCP和UDP两个通信协议, 这大家都知道的, 什么TCP的三次握手等等, 面试经常被问到. 三次握手是为了保证连接的正确建立. 但是, 在通信的时候, 你如何保证你的消息正确送达了呢? 有人说了, 有收到请求的响应包. 但我说的不是这个, 比…

计算机全加器简单实现

概述 用了这么久计算机, 都知道计算机有一个核心部件叫 CPU, 而 CPU中有一个小部件叫做全加器. 它是用来做什么的呢? 看名字就知道了, 做加法运算用的. 那么如何实现一个全加器呢? 你以为这又是一篇计算机内部原理的文章? 不, 放开那个女孩, 和我一起走进中学物理的课堂. …

TCP 三次握手的意义

概述 在网络的传输层协议中, 存在着两大悍将: TCP 和 UDP . 从前, 我傻傻的以为自己对他们虽谈不上精通, 但还是知道的, 但是, 我错了, 我被自己问住了, 我傻了. 啥也不是. UDP (这里为了介绍简单, 就不提数据在传输过程中的失真(纠错码)等情况了. 简单介绍一下, TCP才是今天…

GO 文档笔记

前言 最开始写 GO 的时候, 发现方法的注释并不支持param, return等参数, 搞得我都不知道该如何给自己的方法写文档说明了. 而且网上搜了搜也没有搜到教程, 甚是郁闷. 今天找到了GO内置的文档工具: godoc. (我用的1.14.3版本貌似不是自带工具了, 需要安装(配置代理): go get g…

有了 elseif 为什么还要 switch case

引出 你有没有想过既然有了if elseif, 为什么还要设计一个switch case的语法出来呢? 按理说, 一个语言的设计角度来说, 关键词越少越好吧, 而且多出来一种选择分支也没有看出太大用处. 以下几种switch case均可以写成if else的形式(java 代码): // 形式一 switch(a){case 1:…

计算矩阵中全1子矩阵的个数

前言 最近被我大哥安利了一道算法题, 这道题说难, 还不至于我做不出来, 说简单吧, 我还想不到最优解, 等把最优解告诉我之后, 我还正好能理解. 我甚至曾经怯怯的认为, 这题就是我哥专门给我找的, 嘿嘿, 心中说不出的小欢喜. 题来了, 此题出自力扣, 原题链接: https://leetco…

搭建本地 HTTPS 环境

前言 之前写自己的网站时, 申请过免费的https证书. 最近想在自己本地搭一个, 结果忘了当初证书是怎么来的了. 本来想着去申请个免费的证书, 但想了想, 我只需要在自己本地能使用就行了, 我自己的环境, 那当然是我说了算了. 只要能够将证书构造出来, 安装到本地就可以识别了. 搜…

nginx 端口转发

概述 这两天在写 go 项目, 一个 HTTP 服务器. 之前写的是 php 项目, nginx 监听80端口, 根据域名将请求分配给不同项目. 现在换了 go, 自然也想延续这个操作, 毕竟都是跑在同一台服务器上. 那么问题来了, 我的nginx 监听80端口的同时, go 服务器是无法同样监听80端口的. 这该如…

beego 优雅重启

前言 最近在写 go 的项目, http 用的 beego 框架. 因为 go 不想 php, 每次代码改动都需要重启服务, 所以代码发上线之后, 如何重启服务就成了一个问题. 如果强行重启的话, 不光在重启期间的所有访问都被拒绝了, 而且在杀掉进程的时候处理中的请求也挂了. 对于一个向用户正常提…

由 go orm 引发的探索

前言 今天遇到了一个 bug, 是 golang 的orm导致的. 使用了gorm框架. 通过实现Scan与Value可以将数据库中的 json 内容解析出来, 免除了 字符串再解码的步骤. 当时报错的代码大概是这样的: type TestContent struct {Id intContent Content // 数据库中的 json 结构 }type Con…

码云 Pages 搭建

因为一直在写博客, 就向着搭个 GithubPages 来展示, 一直都听说别人用它来搭建个人博客, 但一直停留在听说的阶段. 最近想着没事搞一搞, 也看看它到底是个什么东东. 不过咱一个写中文博客的, 就想着在码云上搭一个, 顺便还能被百度收录, 嘿嘿. 说干就干, 开搞. (Pages 服务只能…

golang chan 探究

前言 之前在看golang多线程通信的时候, 看到了go 的管道. 当时就觉得这玩意很神奇, 因为之前接触过的不管是php, java, Python, js, c等等, 都没有这玩意, 第一次见面, 难免勾起我的好奇心. 所以就想着看一看它具体是什么东西. 很明显, 管道是go实现在语言层面的功能, 所以我以…

计算机网络-信道复用技术

还记得计算机网络中的信道复用技术么? 来来来, 一起复习一下. why 问: 什么是信道复用. 在回答这个问题之前先看这样一个场景: 其中u1 u2是两个用户, 如果这两个用户之间连通的信道在他们使用过程中, 被他们完全占用了, 其他人就只能等着了. 那有人说了, 那就多架设信道不就…

IP 数据报首部分析

来来来, 爷们. 不是一直说纸上得来终觉浅么. 今咱就抓个数据报具体看一看真实网络中的 IP 报首部. 操作方法很简单, 使用wireshark进行抓包. 抓包后随便找个包看一下就行, 毕竟所有通信的包都需要经过网络层.(同时, wireshark会对协议的相关信息给出标识, 更方便我们查看) 其中…

git 子模块在项目中的使用

在公司的项目中, 经常会遇到一些公共的内容, 多个项目中间通用的, 不可能每次都将整个代码复制一遍, 遇到这种情况有很多不同的解决方案, 一般来说, 项目是通过 git 来管理的, 巧了, git 也同样支持子模块. 创建子模块 git submodule add gitgitee.com:hujingnb/submodule_so…