WebScoket

#WebSocket 是 html5 新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如 Chrome,Safrie,Firefox,Opera,IE 等等。

WebSocket API

首先看一段简单的 javascript 代码,该代码调用了 WebSockets 的 API。

var ws = new WebSocket(“ws://echo.websocket.org”);
ws.onopen = function(){ws.send(“Test!); };
ws.onmessage = function(evt){console.log(evt.data);ws.close();};
ws.onclose = function(evt){console.log(“WebSocketClosed!);};
ws.onerror = function(evt){console.log(“WebSocketError!);};

这份代码总共只有 5 行,现在简单概述一下这 5 行代码的意义。

第一行代码是在申请一个 WebSocket 对象,参数是需要连接的服务器端的地址,同 http 协议使用http://开头一样,WebSocket 协议的 URL 使用ws://开头,另外安全的 WebSocket 协议使用wss://开头。

第二行到第五行为 WebSocket 对象注册消息的处理函数,WebSocket 对象一共支持四个消息 onopen, onmessage, oncloseonerror

当 Browser 和 WebSocketServer 连接成功后,会触发 onopen 消息;

如果连接失败,发送、接收数据 失败或者处理数据出现错误,browser 会触发 onerror 消息;

当 Browser 接收到 WebSocketServer 发送过来的数据时,就会触发 onmessage 消息,参数 evt 中包含 server 传输过来的数据;

当 Browser 接收到 WebSocketServer 端发送的关闭连接请求时, 就会触发 onclose 消息。

我们可以看出 所有的操作都是采用消息的方式触发的,这样就不会阻塞 UI,使得 UI 有更快的响应时间,得到更好的用户体验

WebSocket 协议

WebSocket 协议是一种双向通信协议,它建立在 TCP 之上,同 http 一样通过 TCP 来传输数据,但是它和 http 最大的不同有两点:

  1. WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/UA 都能主动的向对方发送或接收数据,就像 Socket 一样,不同的是 WebSocket 是一种建立在 Web 基础上的一种简单模拟 Socket 的协议。

  2. WebSocket 需要通过握手连接,类似于 TCP 它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。

下面是一个简单的建立握手的时序图:

这里简单说明一下 WebSocket 握手的过程。

当 Web 应用程序调用 new WebSocket(url) 接口时,Browser 就开始了与地址为 url 的 WebServer 建立握手连接的过程。

  1. Browser 与 WebSocket 服务器通过 TCP 三次握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web 应用程序将收到错误消息通知。

  2. 在 TCP 建立连接成功后,Browser/UA 通过 http 协议传送 WebSocket 支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。

例如:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat,superchat
Sec-WebSocket-Version: 13
  1. WebSocket 服务器收到 Browser/UA 发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用 http 协议传输。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
  1. Browser 收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表 示本次连接成功,触发 onopen 消息,此时 Web 开发者就可以在此时通过 send 接口想服务器发送数据。

否则,握手连接失败,Web 应用程序会收到 onerror 消息,并且能知道连接失败的原因。

websocket 与 TCP,HTTP 的关系

WebSocket 与 http 协议一样都是基于 TCP 的,所以他们都是可靠的协议,Web 开发者调用的 WebSocket 的 send 函数在 browser 的实现中最终都是通过 TCP 的系统接口进行传输的。

WebSocket 和 Http 协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?
答案是肯定 的,WebSocket 在建立握手连接时,数据是通过 http 协议传输的,正如我们上一节所看到的“GET/chat HTTP/1.1”,这里面用到的只是 http 协议一些简单的字段。但是在建立连接之后,真正的数据传输阶段是不需要 http 协议参与的。

websocket server

如果要搭建一个 Web 服务器,我们会有很多选择,市场上也有很多成熟的产品供我们应用,比如开源的 Apache,安装后只需简单的配置(或者默认配置)就可 以工作了。

但是如果想搭建一个 WebSocket 服务器就没有那么轻松了,因为 WebSocket 是一种新的通信协议,目前还是草案,没有成为标准,市场 上也没有成熟的 WebSocket 服务器或者 Library 实现 WebSocket 协议,我们就必须自己动手写代码去解析和组装 WebSocket 的数据 包。

要这样完成一个 WebSocket 服务器,估计所有的人都想放弃,幸好的是市场上有几款比较好的开源库供我们使用,比如 PyWebSocket,WebSocket-Node, LibWebSockets 等等,这些库文件已经实现了 WebSocket 数据包的封装和解析,我们可以调用这些接口,这在很大程度上减少了我们的工作量。如

github

websocket 是可以和 http 共用监听端口的,也就是它可以公用端口完成 socket 任务

关于 Socket 与 WebScoket

Socket 其实并不是一个协议。

它工作在 OSI 模型会话层(第 5 层),是为了方便大家直接使用更底层协议(一般是 TCP 或 UDP )而存在的一个抽象层。

最早的一套 Socket API 是 Berkeley sockets ,采用 C 语言实现。它是 Socket 的事实标准,POSIX sockets 是基于它构建的,多种编程语言都遵循这套 API,在 JAVA、Python 中都能看到这套 API 的影子。

Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。

在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Socket 接口后面,对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议。

主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定。

这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。

而 WebSocket 则不同,它是一个完整的 应用层协议,包含一套标准的 API 。

所以,从使用上来说,WebSocket 更易用,而 Socket 更灵活。

再简单来说, Socket 是一个应用程序接口,是抽象的,WebSocket 和 HTTP 是具体实现,

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式 对于信息变化不频繁的Web应用来说造成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应 用。在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,经常会使用折衷的解决方法:轮询(polling)和Comet技术。其实后者本质上也是一种轮询,只不过有所改进。 轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动。明显地,这种方法会导致过多不必要的请求,浪费流量和服务器资源。 Comet技术又可以分为长轮询和流技术。长轮询改进了上述的轮询技术,减小了无用的请求。它会为某些数据设定过期时间,当数据过期后才会向服务端发送请求;这种机制适合数据的改动不是特别频繁的情况。流技术通常是指客户端使用一个隐藏的窗口与服务端建立一个HTTP长连接,服务端会不断更新连接状态以保持HTTP长连接存活;这样的话,服务端就可以通过这条长连接主动将数据发送给客户端;流技术在大并发环境下,可能会考验到服务端的性能。 这两种技术都是基于请求-应答模式,都不算是真正意义上的实时技术;它们的每一次请求、应答,都浪费了一定流量在相同的头部信息上,并且开发复杂度也较大。 伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,使B/S模式具备了C/S模式的实时通信能力。WebSocket的工作流程是这 样的:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过 TCP连接传输数据。因为WebSocket连接本质上是TCP连接,不需要每次传输都带上重复的头部数据,所以它的数据传输量比轮询和Comet技术小 了很多。本文不详细地介绍WebSocket规范,主要介绍下WebSocket在Java Web中的实现。 环境:jdk1.8.0_111,apache-tomcat-8.0.51
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值