websocket

摘自论道《HTML5》

WebSocket不是标准Socket协议,它在OSI七层模型中处于上层,基于HTTPHTTP协议是TCP协议的一部分。

  • 特性:有状态、速度、双向通信、长轮询。

  • 工作原理: 浏览器或客户端通过80或者443端口与服务器进行请求握手,服务器根据HTTP首部识别是不是WebSocket请求,如果是,则将请求升级为一个WebSocket连接,握手成功后就进入双向长连接的数据传输阶段。客户端通过WebSocket与服务端进行通信时,只有第一次握手时交互的信息比较复杂,在握手成功之后便进入双向长连接的数据传输阶段,此时传输的几乎只是纯数据,性能很高。

    • XMLHttpRequest 。使用它可以在不重新加载页面的情况下更新网页,在页面加载后在客户端向服务器请求数据,在页面加载后在服务器端接受数据,在后台向客户端发送数据。 XMLHttpRequest 对象提供了对 HTTP协议的完全访问,包括做出posthead 请求以及普通的get请求的能力XMLHttpRequest可以同步或异步返回Web服务器的响应,并且能以文本或者 DOM 文档的形式返回内容。'

    • OSIOpen System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义,一个规范,它把网络从逻辑上分为了7层。这7层分别是:物理层(physical layer)、数据链路层(datalinklayer)、网络层(network layer)、传输层(transport layer)、会话层(session layer)、表示层(presentation layer)、应用层(application layer)。每一层都有相关、相对应的物理设备,比如路由器、交换机。OSI七层模型是一种框架性的设计方法,建立七层模型的主要目的是解决异种网络互连时所遇到的兼容性问题,其最主要的功能就是帮助不同类型的主机实现数据传输。它的最大优点是将服务接口协议这3个概念明确地区分开来,通过7个层次化的结构使不同的系统、不同的网络之间实现可靠的通信。

请求和响应的消息首部

下面给出WebSocket请求和响应的消息首部。客户端到服务端的请求代码如下:

From client to server:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
Origin: HTTP://example.com
[8-byte security key]

服务端到客户端的响应代码如下:

From server to client:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: HTTP://example.com
WebSocket-Location: ws://example.com/demo
WebSocket-Protocol: sample
[16-byte hash response]
WebSocket 检测浏览器支持代码
<html>
<div id=support></div>
<script type="text/javascript">
if(window.WebSocket){
    document.getElementById("support").innerHTML = "您的浏览器支持HTML5的WebSocket协议";
}
else{
    document.getElementById("support").innerHTML = "您的浏览器不支持HTML5的WebSocket协议";
}
</script>
</html>

WebSocket API 的内容

属性

WebSocket有两个属性,分别是 readyStatebufferedAmount,其中bufferedAmount是作为连接缓冲用的,而WebSocket服务的 readyState 一共有以下4种状态。

  • 0:CONNECTING,表示正在连接,尚未连接成功,这里有一个网络通信的握手过程。
  • 1: OPEN ,表示连接已经成功,可以通信了。这里的连接是长连接、持久连接。
  • 2:CLOSING,表示连接准备被断开,握手将被取消。
  • 3:CLOSED,表示连接已经断开,可以从服务器端断开,也可以从客户端断开。

任何一个连接开始的时候,其状态都必须是CONNECTING=0 。如果 ready-State一直是CONNECTING状态,就会报出 INVALID_STATE_ERR异常。

URL

URL属性都是一样的,哪怕是访问同源网站(这里的URL地址必须是绝对地址)。

var Socket = new WebSocket('ws://www.test.com/');

以下三种形式都是错误的:

var Socket = new WebSocket('/');
var Socket = new WebSocket('C:\www.test.com');
var Socket = new WebSocket('http://www.test.com');

以下两种形式都是允许的、正确的:

var Socket = new WebSocket('ws://www.test.com/updates');
var Socket = new WebSocket('ws://www.test.com/updates:8080');
事件

其中 send()方法基于成功的连接传送数据,其参数必须是字符串
string)格式。

事件句柄 事件类型 解 释
onopen open 连接打开
onmessage message 用于接受从服务器传来的信息
onerror error 当出现连接中的各种错误时,用于容错处理和排查
onclose close 连接关闭或断开
send send 基于成功的连接传送数据

在下面这个简单的例子中,bufferedAmount属性用于确保能够保持在每50ms一次更新的频率(如果网络能保持这个速率),如果这个速率太快,那么采用其他能够有保证的速率也可以。

var Socket = new WebSocket('ws://www.test.com:12010/updates');
Socket.onopen = function(){
    setInterval(function(){
        if(Socket.bufferedAmount == 0)
            Socket.send(getUpdateData());
  }, 50);
};
客户端样例程序
<script type="text/javascript">
  //创建一个ws实例
  var ws= new WebSocket('ws://www.xiuyetang.com:25000');
  //打开WebSocket
  ws.onopen = function(event){
    //发送一个初始化消息
    ws.send('向服务器发送一个消息');
    //监听消息
    ws.onmessage = function(event){
      console.log('客户端收到消息,内容如下:'+event.data);
    };
    //监听ws的关闭
    ws.onclose = function(event){
      console.log('连接已经关闭');
    };
    //关闭ws连接
    socket.close();
  };
</script>
服务器端样例程序
  var sys = require("sys");
  var ws = require("websocket"); //此处是WebSocket服务器被调用
  var server = ws.createServer(); //创建WebSocket服务器
  server.addListener("connection", function(conn){ //当有客户端接入时
    conn.send("Connection: "+conn.id); //向接入的客户端发送信息
    conn.addListener("message", function(message){
      //当收到客户端发送的信息时
      server.broadcast("<"+conn.id+">"+message);
      //向所有客户端发送信息
    });
  });
  server.addListener("close", function(conn){ //当有客户端断开连接时
    server.broadcast("Disconnected:"+conn.id); //向所有客户端发送信息
  });
  server.listen(25000); //启动服务,监听25000端口
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354