# 3.8 服务器推送
## 3.8 服务器推送
服务器推送(Server Push)是一种由服务器发起的消息推送技术,用于把服务器端产生的消息*即时地*推送给客户端,典型的应用场景如Web聊天、微博消息等。
服务器推送与通常的HTTP请求不同——后者都是由客户端发起的,但实际上在WebSocket出现以前,Web原生的服务器推送技术都是用普通的HTTP来模拟的,如果不借助于Flash或者Applet这样的第三方工具的话。下面让我们来了解一些主要的推送技术,并重点了解一下WebSocket。
### 轮询(polling)
这是一种最简单的模拟推送技术:客户端以一定时间间隔定期向服务器发起HTTP请求。
这种技术简单、实用,但如果间隔时间太长(如几分钟)则即时性不高,间隔太短(如几秒钟)则对服务器的压力较大(考虑到同时有N个用户的话)。所以对它的应用要考虑具体场景。
### 长轮询(long polling)
这也是一种模拟推送技术,其基本方式是:
1. 客户端发起一个HTTP请求;
2. 如果服务器有更新则返回更新,否则阻塞;
3. 客户端在收到更新后立即发起一个新的HTTP请求,如此循环往复
长轮询可以通过Ajax实现。它是一种在WebSocket出现之前或当后者不可用时的一种有效的服务器推送技术,属于Comet技术的一种。但这种技术,包括Comet的其他技术,在实现上比较复杂,参考这里了解更多:
- [https://en.wikipedia.org/wiki/Comet\_(programming)](https://en.wikipedia.org/wiki/Comet_(programming))
- <https://www.ibm.com/developerworks/cn/web/wa-lo-comet/>
### WebSocket
WebSocket作为HTML5的一部分在2008年被提出,如今已经被主要的浏览器实现。它可以让Web服务器和Web客户端通过一个全双工(full-duplex)的TCP连接进行通讯。TCP即传输控制协议(Transmission Control Protocol),它提供一种稳定的端到端传输。TCP连接就象一个管道,任何一端都可以向其中读/写数据。
一个简单的例子如下[1](#fn_1):
```
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "ws://echo.websocket.org/";
var output;
function init()
{
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
function onMessage(evt)
{
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
websocket.close();
}
function onError(evt)
{
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
```
你可以把以上代码保存在一个文件中,用浏览器打开就能看到效果。
在上面的代码中:
```
var wsUri = "ws://echo.websocket.org/";
```
定义了一个WebSocket服务器的URI,以`ws://`开头。另外还有一种以`wss://`开头的URI,代表一个SSL加密的WebSocket URI。
```
websocket = new WebSocket(wsUri);
```
这行代码创建了一个WebSocket对象。该对象具有`onopen`、`onclose`和`onmessage`事件,以及`send`和`close`方法,使用起来十分简单。
WebSocket还需要服务器端的实现,即WebSocket服务器,它可以由HTTP服务器同时提供,参考这里了解更多: [https://developer.mozilla.org/en-US/docs/Web/API/WebSockets\_API/Writing\_WebSocket\_servers](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers)一般来说各主要编程语言都有自己的实现,我们只要选择合适的即可。
更多关于WebSocket可参考:<https://en.wikipedia.org/wiki/WebSocket>
> 1. 来自于 <https://www.websocket.org/echo.html>[↩](#reffn_1 "Jump back to footnote [1] in the text.")
- 前言
- 1 Web概述
- 1.1 什么是Web
- 1.2 超文本和超链接
- 1.3 URL
- 1.4 DNS
- 1.5 HTTP
- 1.5.1 客户端请求
- 1.5.2 服务器应答
- 1.5.3 进一步了解HTTP
- 1.6 HTTPS
- 2 Web浏览器
- 2.1 HTML
- 2.1.1 文档类型声明
- 2.1.2 标签和属性
- 2.1.3 文档结构
- 2.1.4 DOM
- 2.1.5 进一步了解HTML
- 2.2 CSS
- 2.2.1 样式与样式表
- 2.2.2 样式表语法
- 2.2.3 级联样式表
- 2.2.4 进一步了解CSS
- 2.3 JavaScript
- 2.3.1 script标签
- 2.3.2 操纵DOM
- 2.3.3 jQuery
- 2.3.4 进一步了解JavaScript
- 2.4 Ajax
- 2.5 移动设备与响应式Web设计
- 3 Web服务器
- 3.1 方法与资源
- 3.2 状态代码
- 3.3 静态内容与动态内容
- 3.4 编程语言与技术
- 3.4.1 CGI
- 3.4.2 PHP
- 3.4.3 Java
- 3.4.4 Python
- 3.4.5 Ruby
- 3.4.6 Node.js
- 3.5 RESTful Web API
- 3.6 服务器架构
- 3.7 Web缓存
- 3.8 服务器推送
- 4 数据库
- 4.1 关系型数据库
- 4.2 NoSQL数据库
- 5 Web服务器的其他组件
- 5.1 Cron
- 5.2 消息队列
- 5.3 邮件服务器
- 6 开发工具与技术
- 6.1 Git
- 6.1.1 Git基础操作
- 6.1.2 Git基本原理
- 6.1.3 进一步了解Git
- 6.2 敏捷开发