刨根问底HTTP和WebSocket协议(三)

上篇文章发出来后,有人留言说到HTTP新版的RFC的问题,WebSocket和Socket的区别。本文将先回答这两个问题,然后继续展开WebSocket。在这篇文章将看到:

  1. 关于新的HTTP规范
  2. WebSocket和Socket的区别
  3. WebSocket中数据帧的格式
  4. WebSocket的实现:socket.IO
  5. 使用socket.IO实现一个在线直播系统

关于新的HTTP规范

HTTP 1.1在2014年(15年后)被更新为6个单独的「协议说明」,如果去读这6个文档,又是很大的工作量,庆幸有很多文章总结了它们相对于RFC2616的不同之处,RFC7230中也列举了这些feature,所以只是大致把这个看了看。对于这个系列有影响的可能有这两点:

  1. Upgrade头域功能的扩展
    Upgrade是HTTP中用来进行协议升级的头域,在扩展的协议内容中,客户端发起的协议转换的方式更多,同时服务器也可以选择不接受客户端的协议升级请求;服务端也可以发起协议升级。

  2. Uri的格式
    #fragment的引入,现在越来越多的人愿意使用fragment来标识网站中的位置了。

完整的变化列表可以在这里找到。这次变化可以算是一个补丁版,把原来漏掉的小东西补上,版本号无变化。

WebSocket和Socket的关系

关于这两者的区别,我写了一篇专门的文章来讨论,可以在WebSocket和Socket的区别看到,简短的答案也放在这里,如果你不想去看另一篇的话。

  • 命名方面,Socket是一个深入人心的概念,WebSocket借用了这一概念;
  • 使用方面,完全两个东西。

可以把WebSocket想象成HTTP,想一想HTTP和Socket什么关系,WebSocket和Socket就是什么关系。

WebSocket中数据帧的格式

本文是此系列的最后一篇了,可能是因为懒,很多想写的东西最终都放弃了。关于WebSocket的帧传输这里就不做详细的讲解了,之前的文章试图把很多细节都展开,但发现那样最后只是变成了规则的罗列,如果有兴趣,可以去这里看文档。

WebSocket的实现:socket.IO

socket.IO是一个基于node的实时通信引擎(FEATURING THE FASTEST AND MOST RELIABLE REAL-TIME ENGINE),第一次看到这个框架时,就想到它的底层应该就是WebSocket吧,实时全双工通信,不就是WebSocket的设计目标吗?于是开始对WebSocket底层的实现进行简单的探索。

socket.IO主页

socket.IO的底层引擎是engine.io,engine.io的实现中使用了HTTP和WebSocket两种方式来构建自己的服务端,如果客户端不支持WebSocket协议,则使用轮询的方式来实现实时传输,如果客户端支持WebSocket协议,则使用另一个模块ws,ws是一个优秀的WebSocket的JS实现,在ws的README中他们自称为「可能是node平台上最快的WebSocket实现」。

对于普通产品的开发,我们可能不可避免的要照顾到那些从不支持WebSocket的客户端(一般情况下是浏览器)发出的请求,或者有的服务器中不支持部署WebSocket协议的服务端,所以socket.IO这种妥协的方法不失为一个向下兼容的好办法。


WebSocket连接无法正常建立

如果可以正常建立连接,则会停掉轮询的方式,使用WebSocket进行接下来的连接。

WebSocket连接正常建立

ws

socket.IO在JS领域算是大名鼎鼎了,截止到今天socket.IO在github上的star数量是27543,而作为socket.IO的核心模块,ws在github上的star数量却只有4005。

一件有趣的小事

ws的源码中可以搜到hixie这个单词,在上一篇关于WebSocket名字由来的文章中介绍过,这个人是WebSocket的命名者。

使用socket.IO实现一个在线直播系统

前段时间当时的老板要求做一个「简单的微信上的文字直播程序」,一接到这个需求,我想到的就是koa + WebSocket + mongoDB,不得不说,基于node的服务端开发极大的拉低了开发一个服务的门槛,尤其是ES6之后,感觉JS这个以前看起来很随意的语言变得愈加性感起来了 。语法越来越现代化,性能越来越好,而随着npm上的模块越来越多,开发一个业务系统变得空前的简单。

书归正传,经过分析之后,一个「简单的微信上的文字直播程序」大约有3个功能:

  • 鉴权
    发布消息的人需要登录之后才能进行操作。
  • 发布消息
    直播的播主进行直播,播主的客户端与服务器建立WebSocket连接,在发送消息的同时也作为一个接收消息的客户端。
  • 接收消息
    所有打开直播页面的客户端都与服务器建立一个WebSocket连接,第一次进入时拉取部分历史消息,之后每条播主的消息都会同步推送到客户端。
直播系统时序图

由于时间仓促,并没有严格保证代码质量,所以就不在这里贴太多的代码了,在这次实现中并没有直接使用socket.IO,而是使用了一个加壳的版本koa-socket,这个库已经很久没有更新了,它接受的函数并不是generator,所以在操作数据库时遇到了一些问题。其中处理发布消息的函数如下:

    controllers/socket.js
    exports.postedHandler = ( ctx, data ) => {
        const createdAt = new Date();
        let newPost = {content: data.content, createdAt: createdAt};
        if (data.image) {
            newPost.image = data.image;
        }
        newPost.date = moment(createdAt).format("HH:mm");
        Posts.insert(newPost);
        if (!app) {
            app = require('../app')
        }
        app.io.broadcast('posts', [newPost] )
    }
    
    app.js
    const IO = require( 'koa-socket' )
    ...
    /**some other code**/
    ...
    const io = new IO()
    io.attach( app )
    io.on('post', socket.postedHandler)

后记

最近由于各种各样的原因,原定的计划严重delay了。关于帧传输的一节本来设计了很多,可是写出来就变得索然无味了;关于在线直播系统的介绍,本以为可以写很多,但是写时才发现除了代码并没有什么好共享的。无论如何都算是给这个系列结了个尾,就像那句歌词,every new beginning comes from some other beginning's end.

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

推荐阅读更多精彩内容