http请求方式

在web引用中,http通信主要是通过请求-应答的方式,即客户端发出请求,浏览器做出应答。

比如说我们浏览百度,当我们输入网址并回车,客户端就向服务器发起请求。我们看到的内容就是服务器做出的相应应答。

file

问题背景

在进行扫码登录时,如何判断用户扫码并登录了?

方法1:轮询

只要客户端定期请求服务器,拉取扫码登录结果即可。

那么问题来了,到底轮询的频率是多少呢?轮询频率过高会给服务器造成压力,轮询频率过低会让用户感觉扫码登录响应过慢。

方法2:长轮询

在轮询的基础上,服务器收到请求消息后,保持连接直到返回扫码登录成功的结果。

使用长轮询,返回消息时序性无法保证;同时,不管是轮询还是长轮询,都逃不开请求-响应的模式。

比如说,扫码登录会返回两个结果:扫码成功通知和确认登录通知。

但是由于长轮询不保证时序性,客户端先收到确认登录通知,后收到扫码成功通知。

所以,对时序性有要求的web服务,如果不能保证时序性,最好不要使用轮询方法。

方法3:websocket

如何让服务器主动推送消息呢?如何保证接受消息的时序性呢?可以使用websocket实现。

websocket

websocket是基于tcp的一种全双工应用层通信协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准。

因为是基于tcp的通信协议,故只需一次请求响应操作即可建立连接。

websocket握手过程

通常是在http通信中请求转换到websocket协议。这里以聊天室为例,讲http创建过程。

如果没有了解http,建议先了解http再看本文后面的内容,传送门:小林coding-HTTP基本概念

客户端请求

客户端首先发起一次http请求,格式如下:

file

必要字段解析:

字段 解释
请求方法和HTTP版本 请求方法必须为GET,http版本必须为HTTP1.1及以上
Status Code:101 状态码101 表示协议转换,这里指将协议转换到websocket
Upgrade: websocket 必要字段,表示通信协议更新到websocket
Sec-WebSocket-Key 为一串16字节随机字符串base64加密后的值
Sec-WebSocket-Version: 13 必须为13

服务端响应

file

必要字段解析:

字段 解释
Connection: Upgrade 必须为Upgrade
Sec-WebSocket-Accept 根据客户端传入的Sec-WebSocket-Key的值,计算获得结果
Sec-WebSocket-Version: 13 必须为13
Upgrade: websocket 必要字段,表示通信协议更新到websocket
Sec-WebSocket-Accept计算过程

拿到Sec-WebSocket-Key的值后,在后面加入字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11得到新的字符串,再将该字符串进行sha-1编码,最后进行base64编码,即Sec-WebSocket-Accept的值。

计算过程php代码实例
<?php
$input = readline(input:);
echo base64_encode(sha1($input . 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, true));

验证结果:

file

计算结果和Sec-WebSocket-Accept的值一致。

客户端最后操作

客户端收到应答后,要校验Sec-WebSocket-Key的值,如果该值和计算结果不符,或者不符合上面过程任一要求,则拒绝创建websocket连接。

如果客户端校验无误,websocket就握手完成了。

既然有TCP了,为什么还要用websocket呢?

背过八股文学过计网的同学都知道,tcp是面向连接的、可靠的、基于字节流的传输层协议,同时tcp也是一个全双工通信协议。那么有了tcp,为什么还要用websocket呢?

个人理解是:tcp是传输层协议,而websocket是应用层协议。tcp只保证报文传输的可靠性、全双工等特性,但tcp是基于字节流形式,如何解决沾包问题交给了应用层,其次,业务相关的其他需求也应该由应用层解决。

参考资料

WebSocket协议(一)- 简介以及连接建立过程

小林coding:图解网络

Categories:

Tags:

还没发表评论,快来发表第一个评论吧~

发表回复