HTTP
HTTP 是基于请求响应式的,即通信只能由客户端发起,服务端做出响应,无状态,无连接。
无状态:每次连接只处理一个请求,请求结束后断开连接。
无连接:对于事务处理没有记忆能力,服务器不知道客户端是什么状态。
短链接: 短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。
以往实现即时通讯的手段:
轮询:客户端定时向服务器发送 Ajax 请求,服务器接到请求后马上返回响应信息并关闭连接。
长轮询:客户端向服务器发送 Ajax 请求,服务器接到请求后 hold 住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
长连接:在页面里嵌入一个隐蔵 iframe,将这个隐蔵 iframe 的 src 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
HTTP1.1的连接默认使用长连接(persistent connection)
长链接是在一定的期限内保持链接。保持TCP连接不断开。客户端与服务器通信,必须要有客户端发起然后服务器返回结果。客户端是主动的,服务器是被动的。
在一个TCP连接上可以传输多个Request/Response消息对,所以本质上还是Request/Response消息对,仍然会造成资源的浪费、实时性不强等问题。
如果不是持续连接,即短连接,那么每个资源都要建立一个新的连接,HTTP底层使用的是TCP,那么每次都要使用三次握手建立TCP连接,即每一个request对应一个response,将造成极大的资源浪费。
Flash Socket:在页面中内嵌入一个使用了 Socket 类的 Flash 程序 JavaScript 通过调用此 Flash 程序提供的 Socket 接口与服务器端的 Socket 接口进行通信,JavaScript 在收到服务器端传送的信息后控制页面的显示。
HTTP长连接的概念,以及HTTP与TCP的关系,简单概括一下就是:
1.HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
2.每个HTTP连接完成后,其对应的TCP连接并不是每次都会关闭。从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这个头部字段:Connection:keep-alive
3.在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache,Nginx,Nginx中这个默认时间是 75s)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
4.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。
HTTP消息信息是用ASCII编码的,每个HTTP请求消息均包含HTTP协议版本(HTTP/1.1,HTTP/2),HTTP方法(GET/POST等),HTTP标头(Content-Type,Content-Length),主机信息等。以及包含要传输到服务器的实际消息的正文(请求主体)。HTTP标头的大小从200字节到2KB不等,HTTP标头的常见大小是700-800字节。当Web应用程序在客户端使用更多cookie和其他工具扩展代理的存储功能时,它将减少HTTP标头的荷载。
http的协议决定了它只能是一问一答的方式。 如果不问,服务器就不会答。就算http一直连着不断开,服务器也不会主动告知浏览器信息,否则就违反协议了:当初咱商量好的一问一答,结果我没问你什么,你就送我一条数据,我要这条数据来干嘛我自己也不知道…
http长连也是可以的。
浏:喂,在吗?
服:我在。(建立连接成功)
浏:我要一份页面。 -等下别挂
服:给你。
浏:我再要一张图片。 -等下别挂
服:给你。
浏: 我再要一个js。 -等下别挂
服:给你。
浏:(默不作声)
服:(等你3秒钟,快说话!3,2,1,再见)
http长连接使用 connection:keep-alive开启。但是和ws有很大的不同。http长连接需要浏览器不断的发问才能保持住,一旦浏览器不说话(好像最长就几十秒的样子默认75秒这边),服务器就会认为浏览器已经不需要传输了,然后主动断开。
ws:没事不说话,有事才说话,但是电话一直都是畅通的。双方谁都可以先说,想说就说。你一直说,我就听听不说话,也行。
http:浏览器先说一句,服务器再回复一句。浏览器永远在询问,服务器永远在回答
QA:
1.在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response 。
按我的理解,这个keep-alive是客户端(浏览器)第一次发出应用层的HTTP请求到服务器后,建立的运输层TCP连接不会立即在HTTP响应结束后断开,之后客户端像同一个服务器发送HTTP请求时,不会建立新的TCP连接,而是使用第一次建立的那个。只有当客户端长时间不在向服务器发送HTTP请求的情况下,服务器才会断开第一次建立的那个TCP连接。所以,你这里说在一个HTTP连接中,可以发送多个Request,接收多个Response 是不太正确的,有歧义,实际上一个HTTP只有一对Request和Response。一个TCP连接中可能会有多对Request和Response(即多个HTTP请求)
2.但我还是不清楚底层实现。http是基于tcp连接的,因为连接到对方需要IP和端口号,所以只要客户端才能主动发起链接而服务器响应,因为只要服务器才有域名可以映射到服务器端的主机IP和端口嘛,所以大家才能找到。很多轮询解决方案无非就是不断请求信息,只是请求次数的嘛量变以达到更新客户端的目的。那么问题来了,你说websocket是非轮询的,也是非阻塞连接来轮询的,那么是怎么给客户端推送消息的,服务器有没有和客户端一直保持连接,如果保持了,那和上面提到的阻塞等待服务器消息有啥区别,还有如果客户端关掉了,还能推送消息吗,比如手机APP,是怎么推送的,难道服务器记住了客户端的IP和程序端口吗,但是IP和port是动态的呀,求楼主解答疑惑?
答主:websocket是保持长连接的,但是传统的http必须等待client的request才能response,这是个阻塞模型,所以一般都会并发打开许多http链接(也就是许多tcp链接)来减少阻塞造成的延迟。但是websocket是双向的,他可以想本地的客户端软件一样与服务器通信,所以一条tcp链接就够,不用搞平行链接。
1: 和阻塞等待消息的到来的区别,答主有说
就是websocket有nginx这个占线员,不是每次都阻塞handler。(我不知道是怎么实现的,也准备看),传统的阻塞那种需要阻塞一个handler。((我感觉这个也能像websocket一样给他一个占线员?我也半桶水)
2,关掉app后还可以提醒,是通过第三方服务或者官方服务做的,可以看看极光推送和iphone的notification?
webSocket
WebSocket是双向的通信,在客户端-服务器通信的场景中使用的全双工协议,与HTTP不同,
它以ws://或wss://开头。它是一个有状态协议,这意味着客户端和服务器之间的连接将保持活动状态可以同时发送信息,直到被任何一方(客户端或服务器)终止。在通过客户端和服务器中的任何一方关闭连接之后,连接将从两端终止。
为什么需要webSocket?
HTTP 协议有一个缺陷:通信只能由客户端发起。
举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。
轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。
WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
websocket的持久连接
只需建立一次Request/Response消息对,之后都是TCP连接,避免了需要多次建立Request/Response消息对而产生的冗余头部信息。
其他特点包括:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
Websocket使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。
WebSocket与HTTP的关系
相同点:
都是一样基于TCP的,都是可靠性传输协议。
都是应用层协议。
不同点:
WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。
WebSocket是需要握手进行建立连接的。
联系
WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。
websocket请求头讲解
其中请求头中重要的字段:
Connection:Upgrade
Upgrade:websocket
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:mg8LvEqrB2vLpyCNnCJV3Q==
Sec-WebSocket-Version:13
1. Connection和Upgrade字段告诉服务器,客户端发起的是WebSocket协议请求
2.Upgrade: Websocket 要升级协议到 websocket 协议。
3. Sec-WebSocket-Extensions表示客户端想要表达的协议级的扩展(如消息压缩插件)
4. Sec-WebSocket-Key是一个Base64编码值,由浏览器随机生成。主要用于WebSocket协议的校验,对应服务端响应头的 Sec-WebSocket-Accept
5. Sec-WebSocket-Version表明客户端所使用的协议版。本如果服务端不支持该版本,需要返回一个Sec-WebSocket-Versionheader,里面包含服务端支持的版本号。
而得到的响应头中重要的字段:
Connection:Upgrade
Upgrade:websocket
Sec-WebSocket-Accept:AYtwtwampsFjE0lu3kFQrmOCzLQ=
1. Connection和Upgrade字段与请求头中的作用相同
2. Sec-WebSocket-Accept表明服务器接受了客户端的请求
Status Code:101 Switching Protocols
并且http请求完成后响应的状态码为101,表示切换了协议,说明WebSocket协议通过http协议来建立运输层的TCP连接,之后便与http协议无关了。
WebSocket协议具体内容请参考:https://github.com/zhangkaitao/websocket-protocol
WebSocket 使用场景数据流状态:
1.比如说上传下载文件,文件进度,文件是否上传成功。
2.协同编辑文档: 同一份文档,编辑状态得同步到所有参与的用户界面上。
3.多玩家游戏: 很多游戏都是协同作战的,玩家的操作和状态肯定需要及时同步到所有玩家。
4.多人聊天: 很多场景下都需要多人参与讨论聊天,用户发送的消息得第一时间同步到所有用户。
5.社交订阅: 有时候我们需要及时收到订阅消息,比如说开奖通知,比如说在线邀请,支付结果等。
6.股票虚拟货币价格: 股票和虚拟货币的价格都是实时波动的,价格跟用户的操作息息相关,及时推送对用户跟盘有很大的帮助。
NodeJS的简单实现;
服务端
// 安装ws模块// npm install ws// 新建index.js文件// -----
// 导入ws模块const WebSocket = require('ws')
// 新建一个WebSocketServerconst wss = new WebSocket.Server({ port: 3000 })
// 服务器监听连接事件
wss.on('connection', ws => {
// 服务器监听消息事件
ws.on('message', msg => {
console.log('服务器收到:', msg)
})
// 服务器向客户端发送消息
ws.send('这是服务器发送的信息')
})
客户端
Document
运行结果
Socket
Socket 是操作系统提供的对于传输层(TCP / UDP)抽象的接口,是一个编程概念,而 Websocket 与 HTTP 一样是一个成文的互联网协议。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。
webService
WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
跨编程语言和跨操作平台:就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然!
跨操作系统平台:则是指服务端程序和客户端程序可以在不同的操作系统上运行。
远程调用:就是一台计算机a上的一个程序可以调用到另外一台计算机b上的一个对象的方法,譬如,银联提供给商场的pos刷卡系统,商场的POS机转账调用的转账方法的代码其实是跑在银行服务器上。再比如,amazon,天气预报系统,淘宝网,校内网,百度等把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能,这样扩展了自己系统的市场占有率,往大的概念上吹,就是所谓的SOA应用。
从表面上看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。
WebService平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,WebService平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。Web service平台必须提供一种标准来描述Web service,让客户可以得到足够的信息来调用这个Web service。最后,我们还必须有一种方法来对这个Web service进行远程调用,这种方法实际是一种远程过程调用协议(RPC)。为了达到互操作性,这种RPC协议还必须与平台和编程语言无关。
WebService平台技术
XML+XSD,SOAP和WSDL就是构成WebService平台的三大技术。
XML:
WebService采用HTTP协议传输数据,采用XML格式封装数据(即XML中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的返回结果是什么)。XML是WebService平台中表示数据的格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。
XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,64位?这些细节对实现互操作性很重要。XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。WebService平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合WebService标准,所有你使用的数据类型都必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换,但你很可能会根据你的需要修改一下转换过程。
SOAP(Simple Object Access Protocol简单对象访问协议):
WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议。SOAP提供了标准的RPC方法来调用Web Service。
SOAP协议 = HTTP协议 + XML数据格式
SOAP协议定义了SOAP消息的格式,SOAP协议是基于HTTP协议的,SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。打个比喻:HTTP就是普通公路,XML就是中间的绿色隔离带和两边的防护栏,SOAP就是普通公路经过加隔离带和防护栏改造过的高速公路。
WSDL:
好比我们去商店买东西,首先要知道商店里有什么东西可买,然后再来购买,商家的做法就是张贴广告海报。 WebService也一样,WebService客户端要调用一个WebService服务,首先要有知道这个服务的地址在哪,以及这个服务里有什么方法可以调用,所以,WebService务器端首先要通过一个WSDL文件来说明自己家里有啥服务可以对外调用,服务是什么(服务中有哪些方法,方法接受的参数是什么,返回值是什么),服务的网络地址用哪个url地址表示,服务通过什么方式来调用。
WSDL(Web Services Description Language)就是这样一个基于XML的语言,用于描述Web Service及其函数、参数和返回值。它是WebService客户端和服务器端都能理解的标准格式。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应WebService的代理类代码。
WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。