WebSocket 由来已久, 常用于 "服务器推" 场景。最近开始学习 WebSocket (从 tomcat examples 开始), 本文的主要目的是做学习笔记, 同时记录一份开发指南。

    本文示例代码见: https://github.com/hanyong/exercise/tree/websocket

HTTP 协议简述

我们先来看看 HTTP。

一次 HTTP 请求过程如下:

客户端服务器
1.客户端建立到服务器的 TCP 连接
2.客户端发送请求
3.客户端等待响应
4.服务器收到请求
5.服务器发送响应
6.客户端收到响应
7.请求结束

TCP 连接是支持双向同时读写的全双工协议, 但是我们看传统的 HTTP 协议有几个问题:

  1. 请求过程是串行的, 客户端与服务器互相等待.
  2. 请求是单向的, 总是必须客户端先发起请求.

也就是说, 传统的 HTTP 1.0/1.1 协议没有充分利用 TCP 连接的能力.

  1. HTTP 协议是无状态的, 两个请求是从同一个 TCP 连接发过来, 还是从不同的 TCP 连接发过来, 对服务器来说应该是等价的.

    HTTP 协议这样的设计主要是简化了编程模型, 想一想传统的 CGI 脚本, 一个脚本只要能够接受输入, 产生输出, 就可以提供 web 服务。HTTP 协议缺少 ISO 7 层网络模型中的会话层, 动态 web 应用使用 cookie 来保存会话信息。HTTP/1.1 默认开启长连接来优化性能, 但 HTTP 连接和请求依然是无状态的。对传统提供静态内容服务, 或返回信息相对确定的 web 应用而言, 这样的设计并没有问题, 或者说虽然有一些不足, 但尚能忍受。无状态的设计也简化了 HTTP 测试, 日志回放也成为重要的 HTTP 服务测试手段之一。

websocket 协议简述

    直到 "服务器推" 场景的出现。服务器端信息随时可能变化, 我们希望将变化后最新的信息立即通知给客户端。传统的解决方案是客户端不断轮询服务器, 如每秒 1 次。这种轮询将产生许多额外的代价, 包括移动端流量收费, 并且编程模型也相对复杂。因此, 是时候开放 TCP 双向通信的能力了。我们可以重新写一个 TCP 服务器, 使用新的协议来通信。但也许是为了复用 HTTP 的 80 端口, 依附现有 HTTP 生态圈, 让 web 应用平滑升级, websocket 基于 HTTP 协议设计, 顾名思义就是基于 web HTTP 协议, 释放原生 TCP socket 的能力。所以 websocket 一开始还是按 HTTP 协议通信, 随后才转换成 websocket。

一个 websocket 连接的建立过程如下:

客户端服务器
1.客户端建立到服务器的 TCP 连接
2.客户端请求将当前 TCP 连接用作 websocket
3.服务器收到请求, 同意并确认将此 TCP 连接用作 websocket
4.客户端收到确认, HTTP 协议通信结束
5.双方使用 websocket 协议自由双向通信

websocket 可基于 HTTP 建立, 即 ws 协议, 也可基于 HTTPS 建立, 即 wss 协议, 果然是复用了 HTTP 的基础设施。

HTTP 与 websocket 客户端

HTTP 客户端发送完请求后才会监听响应, 收到一次响应后即结束。常见的 HTTP 客户端有:

  1. curl, 如 curl localhost:8080/http.
  2. 浏览器 js 客户端, 如 angularjs 的 $http 服务.

    $http.get("/http").then(function(resp) {
        vm.msg = resp.data;
    }); 
  3. 直接在浏览器输入 URL.

    回顾 "服务器推" 场景, websocket 与 HTTP 协议最大的不同在于服务器不必等待请求, 也不再使用 "请求", "响应" 这样的术语, 而改称为消息, 双方都可以随时互发消息。HTTP 客户端不会一直监听消息, 所以显然不能作为 websocket 客户端 (且不说协议是否兼容)。要使用 websocket, 客户端和服务器都需要改造。常见的 websocket 客户端有:

  1. 浏览器 js 客户端。感谢浏览器厂商, 现在的主流浏览器都支持 websocket 。


阅读全文直接点击:http://click.aliyun.com/m/9971/
11-10 21:05