WebSocket的总结

最近做的几个项目都用到了HTML5的WebSocket技术,并且在一些公司的面试中该内容也会被问到,为此有必要将WebSocket方面的知识整理一下。

WebSocket概述

HTTP协议是一种无状态的协议,要实现有状态的会话必须借助一些外部机制如session和cookie,这或多或少会带来一些不便,尤其是服务端和客户端需要实时交换数据的时候(监控,聊天),这个问题更加明显。WebSocket就是在这种大环境下应运而生。
WebSocket允许服务器和客户端进行全双工通信,传统的HTTP是单双工通信,它只能允许客户端向服务器发出请求,服务端被动返回数据,而不能主动向客户端传递数据。
WebSocket可以完全取代Ajax,用来向服务器传递字符串,二进制等多种类型的数据,而且还不存在跨域问题。
WebSocket不使用HTTP协议,而是使用自己的协议。浏览器发出的WebSocket请求类似下面这种:

websocket-request.png

下面我们来分析一下这个请求头部

  • Accept-Encoding:浏览器可以接受的数据的压缩类型。
  • Accept-Language:浏览器可以接受的语言类型。
  • Cache-Control:no-cache不使用强缓存。
  • Connection:Upgrade 通知服务器通信协议提升。
  • Host:主机名。
  • Origin:用于验证浏览器域名是否在服务器许可范围内。
  • Pragma:no-cache HTTP/1.0定义的不使用本地缓存。
  • Upgrade:websocket 使用websocket协议进行传输数据,而不使用HTTP/1.1。
  • User-Agent:用户代理字符串。
  • Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
  • Sec-WebSocket-Key:lb69kw8CsB4CrSk9tKa3+g== 握手协议密钥,base64编码的16字节的随机字符串。
  • Sec-WebSocket-Version:13 版本号。

服务器接收到客户端的请求并返回如下:

websocket-response.png

我们来分析一下服务器返回的头部信息:

  • Connection:Upgrade 通信协议提升。
  • Upgrade: websocket 传输协议升级为websocket。
  • Sec-WebSocket-Extensions:permessage-deflate
  • Sec-WebSocket-Accept:q9g5u1WfIWaAjNgMmjlTQTqkS/k= 将Sec-WebSocket-Key的值进行一定的运算和该值进行比较来判断是否是目标服务器响应了WebSocket请求。

WebSocket协议用ws表示,此外还有wss表示加密的WebSocket协议,类似https。
现在大部分浏览器都支持WebSocket(包括IE10+),服务器端(node)需要安装模块,目前比较流行的是socket.io和ws,我个人喜欢用ws。

客户端该怎么用WebSocket

这里我所指的客户端通常是指浏览器,而且都支持WebSocket API。你也可以通过window.WebSocket来判断你的浏览器是否支持WebSocket。废话不多说,我们先来一段代码,然后通过代码来学习如何在客户端使用WebSocket。

let ws  = new WebSocket('ws://10.11.10.66:3000');
ws.addEventListener('open', event => {
        console.log(ws.readyState);
        ws.addEventListener('message', (event, flags) => {
          console.log(event.data);
              ws.send('ssss');
    });
    ws.addEventListener('close', event => {
            console.log('client notified websocket has closed', event.data);
    });
});
ws.addEventListener('error', event => {
        console.log('error', event.data);
});

接下来我们重点说一下怎么使用浏览器WebSocketAPI。首先我们要创建一个WebSocket的实例即new WebSocket(url); 然后我们需要绑定四个事件open,message,error,close看他们的
的名字我们就知道他们表示什么意思了。发送数据使用send方法,该方法除了可以发送字符串以外还可以发送blob和二进制数据,具体怎么使用,等到大家想用的时候再去找。哦,还有一个我们创建好的ws对象有一个readyState属性,它的取值有0,1,2,3分别表示正在连接,连接成功,正在关闭,连接关闭。

服务器端该怎么使用WebSocket

服务器端使用WebSocket需引入相关的模块,目前比较流行的是socket.io和ws。由于本人在项目中都是使用的ws模块,下面只给出ws模块的使用方法,socket.io模块的使用方法大家可以去网上找。

var express = require('express');
var http = require('http');
var WebSocket = require('ws');

var app = express();
app.get('/', function(req, res, next){
        res.sendFile(__dirname + '/index.html');
});
var server = http.createServer(app);
var wss = new WebSocket.Server({ server });
wss.on('connection', function(ws){
        ws.on('message', function(message, flag){
                if (ws.readyState === WebSocket.OPEN){
                        //你的操作
                }
        });
        ws.send('something');
});
server.listen(3000, function(){
        console.log('listening on port:3000');
});

下面简单说明一下,搭配上述服务器我还引入了express模块,其实ws模块是可以单独工作的,只不过我的项目都是建立在express开发框架上的,express怎么使用网上教程也蛮多的,大家想知道具体用法可自行百度。上面的代码可以称作模板式的代码,以后大家想搭建一个WebSocket服务的话,只需复制一下,然后修改对应的参数即可,相信有一定开发经验的同学都看得懂其中的含义。

WebSocket和Socket的区别

WebSocket和Socket有什么区别或者联系?说到这个我不得不用这句话来回答你:就像Java和JavaScript的关系一样,两者没有丝毫的联系。


Java和JavaScript

首先说一下Socket,这个东西我在大学时上java 课网络编程的时候就接触过,套接字,它是为了方便我们开发人员使用TCP/IP或者UDP来构建服务而抽象出来的一个概念,它也有自己的一套API,说实话它是和网络中的运输层打交道的,如果你的项目是基于HTTP来构建服务的话可以不用理会它。
WebSocket则是一种新的通信协议,是为了解决实时传递数据而开发的一种全双工的通信协议,它也有自己的一套编程接口,作为开发人员我们知道这些就足够了,毕竟我们不是搞科学研究的,点到为止。

WebSocket和HTTP的比较

相同点:

  • 都属于应用层的协议。
  • 都使用Request/Response模型进行连接的建立。
  • 都可以在网络中传输数据。

不同点:

  • ws使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用。
  • ws连接建立之后,通信双方都可以在任何时刻向另一方发送数据。
  • ws连接建立之后,数据的传输使用帧来传递,不再需要Request消息。
  • ws的数据帧有序。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容