Android WebSocket原理及实战(一)

近来封装了一个基于WebSocket服务的库,过程中对WebSocket进行了总结,分几个章节进行讲解,看完后,应该能够对以下内容有个简单的了解

1、WebSocket原理

2、WebSocket与Http的区别

3、为什么要使用WebSocket

4、WebSocket的优缺点

5、Android端WebSocket实战

下面开始

WebSocket伴随HTML5协议横空出世,这里的HTML5指的是一系列新规范,新技术,那么在HTML5之前,为什么没有WebSocket,而现在WebSocket的加入,又是为了解决什么问题呢?

总所周知,WebSocket的功能是实现长连接,进行客户端与服务端之间的双向通信,而HTML5协议推出之前,是怎么实现客户端与服务端的“长连接”和双向通信的呢?

这就要说到 ajax轮询 和 long poll 了,这两个就是没有WebSocket之前的替代方案

所谓的ajax轮询,其原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息

举例:

客户端:有没有新信息(Request)

服务端:没有(Response)

客户端:有没有新信息(Request)

服务端:有,给你(Response)

客户端:有没有新信息(Request)(复读N次)

服务端:没有×N(Response)

这种方式又叫心跳,就是每隔一段时间进行一次HTTP请求,根据返回值来达到双向通信的目的

而 long poll与ajax轮询类似,不同点是采取的是阻塞模型,客户端发起请求后,如果服务端没有新的信息,中间层会不断向服务端发起请求,直到收到返回数据,才会返回给客户端,返回完之后,客户端再次建立连接,周而复始

举例:

客户端:有没有新信息(Request)

中间层:有没有新信息(Request)(转述客户端的话)

服务端:没有(Response)(给中间层)

中间层:有没有新信息(Request)(转述客户端的话)

服务端:没有(Response)(给中间层)

中间层:有没有新信息(Request)(转述客户端的话)

服务端:有了(Response)(给中间层)

中间层:有了(Response)(给客户端)

客户端:有没有新信息(Request)

从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点:被动性

何为被动性呢,其实就是,服务端不能主动联系客户端只能由客户端发起

这样会导致什么问题呢?其实看到客户端频繁的网络请求,我们也能猜出个大概

ajax轮询 需要服务器有很快的处理速度和资源

long poll 需要有很高的并发,也就是说同时接待客户的能力

总结下就是,两种方式需要很多的资源

那么为什么WebSocket的出现就解决了“服务端不能主动联系客户端”“需要很多的资源”的问题呢?

那就要说说WebSocket和Http的区别了,HTTP是一个无状态协议,就是说服务端非常健忘,每次请求都需要你再把你的信息告诉它一次,而WebSocket是基于回调的设计,只需要进行一次HTTP握手,服务端会一直持有你的信息直到断开,之后的请求不需要再询问你的信息,同时握手成功后,服务端会主动通知客户端消息,客户端不需要一直询问服务端是否有消息返回,避免了资源浪费

上面说到了WebSocket握手使用了HTTP协议,但和传统的HTTP协议有部分区别,他的协议内容如下

 这段请求与HTTP协议的握手请求相似,但也有决定性的差别

这两段主要是告诉Apache、Nginx等服务器,这次发起的协议是WebSocket协议,而不是HTTP协议 

 

 而这部分主要是用于握手的验证,Sec-WebSocket-Key 是一个Base64 encode的值,由浏览器随机生成,Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议,Sec-WebSocket-Version 是告诉服务器所使用的Websocket Draft(协议版本)

然后服务器会返回下列东西,表示已经接受到请求,并建立了WebSocket长连接

 这两段告诉客户端即将升级的是Websocket协议

Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key

Sec-WebSocket-Protocol 则是表示最终使用的协议

至此,HTTP已经完成了它所有的任务,接下来将会完全按照WebSocket的协议运行

所以WebSocket可以看作是HTTP 协议为了支持长连接所打的补丁,它在握手阶段使用了HTTP协议,他们是交集关系

说了这么多,WebSocket出来后,ajax轮询 和 long poll是不是就成了时代的眼泪了呢?WebSocket就完美无缺了吗?

当然不是,WebSocket也是有缺点的,缺点不在它本身,而在于原有网络世界的一些缺陷性设计

比如说,坑爹的中间节点——中间的网络链路。一个 HTTP/WebSocket 连接往往要经过无数的路由,防火墙可能会认为一份连接在一段时间内没有数据发送就等于失效,它们会自作主张的切断这些连接。在这种情况下,不论服务器还是客户端都不会收到任何提示,它们只会一厢情愿的以为彼此间的红线还在,徒劳地一边又一边地发送抵达不了彼岸的信息,WebSocket 长连接,就可能在毫不知情的情况下进入了半死不活状态

这就涉及到了WebSocket的断线重连,而解决方案,WebSocket 的设计者们也早已想过。就是让服务器和客户端能够发送 Ping/Pong Frame。这种 Frame 是一种特殊的数据包,它只包含一些元数据而不需要真正的 Data Payload,可以在不影响 Application 的情况下维持住中间网络的连接状态,这就让我们想到了ajax轮询 和 long poll,所以他们并没有消失,而是以另一种形式,守护着长连接和双向通信

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要写一个android websocket框架,可以遵循以下步骤: 1. 引入 OkHttp 库:OkHttp 是一个强大的 HTTP/HTTPS 客户端,也支持 WebSocket 协议。在项目的 build.gradle 文件中添加如下依赖: ``` implementation 'com.squareup.okhttp3:okhttp:4.9.1' ``` 2. 创建 WebSocket 连接:使用 OkHttp 的 WebSocket 类创建 WebSocket 连接。可以通过下面的代码创建连接: ``` Request request = new Request.Builder() .url("ws://localhost:8080/ws") .build(); OkHttpClient client = new OkHttpClient(); WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { // WebSocket 连接已经打开 } @Override public void onMessage(WebSocket webSocket, String text) { // 收到了文本消息 } @Override public void onMessage(WebSocket webSocket, ByteString bytes) { // 收到了二进制消息 } @Override public void onClosing(WebSocket webSocket, int code, String reason) { // WebSocket 连接正在关闭 } @Override public void onClosed(WebSocket webSocket, int code, String reason) { // WebSocket 连接已经关闭 } @Override public void onFailure(WebSocket webSocket, Throwable t, Response response) { // WebSocket 连接失败 } }); ``` 3. 发送消息:使用 WebSocket.send() 方法发送消息。可以发送 String 类型的文本消息或者 ByteString 类型的二进制消息。例如: ``` webSocket.send("Hello, WebSocket!"); ``` 4. 关闭连接:使用 WebSocket.close() 方法关闭连接。可以指定关闭码和关闭原因。例如: ``` webSocket.close(1000, "Goodbye, WebSocket!"); ``` 5. 销毁连接:在不需要使用 WebSocket 连接的时候,应该及时销毁连接以释放资源。可以使用 WebSocket.cancel() 方法取消连接。例如: ``` webSocket.cancel(); ``` 综上所述,可以使用 OkHttp 库轻松地创建一个 WebSocket 框架。需要注意的是,在使用 WebSocket 连接的时候,应该遵循 WebSocket 协议的规范,以确保连接的稳定和可靠。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值