金沙国际官网_金沙国际平台登录

因为这个金沙国际官网_金沙国际平台登录网站与很多的大型澳门赌场都有合作,金沙国际官网_金沙国际平台登录尽职尽责,高效执行,保持好奇心,不断学习,追求卓越,点击进入金沙国际官网_金沙国际平台登录马上体验吧,所以现在也正式地开始了营业。

您的位置:金沙国际官网 > web前端 > 刨根问底HTTP和WebSocket协议,的性能优化

刨根问底HTTP和WebSocket协议,的性能优化

发布时间:2019-10-25 15:33编辑:web前端浏览(150)

    XCel 项目总结:Electron 与 Vue 的性能优化

    2017/03/01 · 基础技术 · Javascript, 算法

    本文作者: 伯乐在线 - 刘健超-J.c 。未经作者许可,禁止转载!
    欢迎加入伯乐在线 专栏作者。

    XCEL 是由京东用户体验设计部凹凸实验室推出的一个 Excel 数据清洗工具,其通过可视化的方式让用户轻松地对 Excel 数据进行筛选。

    XCEL 基于 Electron 和 Vue 2.x,它不仅跨平台(windows 7+、Mac 和 Linux),而且充分利用 Electron 多进程任务处理等功能,使其性能优异。

    落地页: ✨✨✨
    项目地址: ✨✨✨

    别人家的面试题:一个整数是否是“4”的N次幂

    2016/05/30 · 基础技术 · 2 评论 · 算法

    本文作者: 伯乐在线 - 十年踪迹 。未经作者许可,禁止转载!
    欢迎加入伯乐在线 专栏作者。

    这是 leetcode.com 的第二篇。与上一篇一样,我们讨论一道相对简单的问题,因为学习总讲究循序渐进。而且,就算是简单的问题,追求算法的极致的话,其中也是有大学问的。

    刨根问底HTTP和WebSocket协议

    2016/08/17 · 基础技术 · 1 评论 · HTTP, websocket

    原文出处: TheAlchemist   

    图片 1

    那天和boss聊天,不经意间提到了Meteor,然后聊到了WebSocket,然后就有了以下对话,不得不说,看问题的方式不同,看到的东西也会大不相同。
    A:Meteor是一个很新的开发框架,我觉得它设计得十分巧妙。
    B:怎么个巧妙之处?
    A:它的前后端全部使用JS,做到了真正的前后端统一;前端浏览器里存有一份后台开放出来的数据库的拷贝,快;使用WebSocket协议来做数据传输协议,来同步前后端的数据库,实现了真正的实时同步。
    B:哦?WebSocket是什么东西?真实时?那底层是不是还是轮训?和HTTP的长连接有什么不同?
    A:(开始心虚)它是一个新的基于TCP的应用层协议,只需要一次连接,以后的数据不需要重新建立连接,可以直接发送,它是基于TCP的,属于和HTTP相同的地位(呃,开始胡诌了),底层不是轮训,和长连接的区别……这个就不清楚了。
    B:它的传输过程大致是什么样子的呢?
    A:首先握手连接(又是胡诌),好像可以基于HTTP建立连接(之前用过Socket.io,即兴胡诌),建立了连接之后就可以传输数据了,还包括断掉之后重连等机制。
    B:看起来和HTTP长连接做的事情差不多嘛,好像就是一种基于HTTP和Socket的协议啊。
    A:呃……(我还是回去看看书吧)

    有时候看事情确实太流于表面,了解到了每个事物的大致轮廓,但不求甚解,和朋友聊天说出来也鲜有人会刨根问底,导致了很多基础知识并不牢靠,于是回来大致把HTTP和WebSocket协议的RFC文档(RFC2616 和 RFC6455),刚好对HTTP的传输过程一直有点模糊,这里把两个协议的异同总结一下。

    项目背景

    用户研究的定量研究和轻量级数据处理中,均需对数据进行清洗处理,以剔除异常数据,保证数据结果的信度和效度。目前因调研数据和轻量级数据的多变性,对轻量级数据清洗往往采取人工清洗,缺少统一、标准的清洗流程,但对于调研和轻量级的数据往往是需要保证数据稳定性的,因此,在对数据进行清洗时最好有标准化的清洗方式。

    “4”的整数次幂

    给定一个32位有符号整数(32 bit signed integer),写一个函数,检查这个整数是否是“4”的N次幂,这里的N是非负整数。

    例如:

    • 给定 num = 16,返回 true,因为 16 = 42
    • 给定 num = 5,返回 flase

    附加条件: 你能够不用循环和递归吗?

    协议基础

    仔细去看这两个协议,其实都非常简单,但任何一个事情想做到完美都会慢慢地变得异常复杂,各种细节。这里只会简单地描述两个协议的结构,并不会深入到很深的细节之处,对于理解http已经足够了。

    特性一览

    • 基于 Electron 研发并打包成为原生应用,用户体验良好;
    • 可视化操作 Excel 数据,支持文件的导入导出;
    • 拥有单列运算逻辑、多列运算逻辑和双列范围逻辑三种筛选方式,并且可通过“且”、“或”和“编组”的方式任意组合。

    解题思路

    如果忽略“附加条件”,这题还挺简单的对吧?简直是信手拈来:

    版本1

    JavaScript

    function isPowerOfFour(num){ while(!(num % 4)){ num /= 4; } return num === 1; }

    1
    2
    3
    4
    5
    6
    function isPowerOfFour(num){
        while(!(num % 4)){
            num /= 4;
        }
        return num === 1;
    }

    版本1 好像很简单、很强大的样子,它的时间复杂度是 log4N。有同学说,还可以做一些微小的改动:

    版本1.1

    JavaScript

    function isPowerOfFour(num){ while(!(num % 4)){ num >>>= 2; } return num === 1; }

    1
    2
    3
    4
    5
    6
    function isPowerOfFour(num){
        while(!(num % 4)){
          num >>>= 2;
        }
        return num === 1;
    }

    上面的代码用位移替代除法,在其他语言中更快,鉴于 JS 通常情况下非常坑的位运算操作,不一定速度能变快。

    好了,最关键的是,不管是 版本1 还是 版本1.1 似乎都不满足我们前面提到的“附加条件”,即不使用循环和递归,或者说,我们需要寻找 O(1) 的解法。

    按照惯例,大家先思考10秒钟,然后往下看 ——


    HTTP

    HTTP的地址格式如下:

    JavaScript

    http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] 协议和host不分大小写

    1
    2
    http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
    协议和host不分大小写

    思路与实现

    基于用研组的需求,利用 Electron 和 Vue 的特性对该工具进行开发。

    不用循环和递归

    其实这道题真心有好多种思路,计算指数之类的对数学系学霸们完全不是问题嘛:

    版本2

    JavaScript

    const log4 = Math.log(4); function isPowerOfFour(num){ var n = Math.log(num) / log4; return n === (0|n); }

    1
    2
    3
    4
    5
    const log4 = Math.log(4);
    function isPowerOfFour(num){
        var n = Math.log(num) / log4;
        return n === (0|n);
    }

    嗯,通过对数公式 logm(n) = log(n) / log(m) 求出指数,然后判断指数是不是一个整数,这样就可以不用循环和递归解决问题。而且,还要注意细节,可以将 log4 当做常量抽取出来,这样不用每次都重复计算,果然是学霸范儿。

    不过呢,利用 Math.log 方法也算是某种意义上的犯规吧,有没有不用数学函数,用原生方法来解决呢?

    当然有了!而且还不止一种,大家可以继续想30秒,要至少想出一种哦 ——


    HTTP消息

    一个HTTP消息可能是request或者response消息,两种类型的消息都是由开始行(start-line),零个或多个header域,一个表示header域结束的空行(也就是,一个以CRLF为前缀的空行),一个可能为空的消息主体(message-body)。一个合格的HTTP客户端不应该在消息头或者尾添加多余的CRLF,服务端也会忽略这些字符。

    header的值不包括任何前导或后续的LWS(线性空白),线性空白可能会出现在域值(filed-value)的第一个非空白字符之前或最后一个非空白字符之后。前导或后续的LWS可能会被移除而不会改变域值的语意。任何出现在filed-content之间的LWS可能会被一个SP(空格)代替。header域的顺序不重要,但建议把常用的header放在前边(协议里这么说的)。

    技术选型

    • Electron:桌面端跨平台框架,为 Web 提供了原生接口的权限。打包后的程序兼容 Windows 7 及以上、Mac、Linux 的 32 / 64 位系统。详情>>
    • Vue 全家桶:Vue 拥有数据驱动视图的特性,适合重数据交互的应用。详情>>
    • js-xlsx:兼容各种电子表格格式的解析器和生成器。纯 JavaScript 实现,适用于 Node.js 和 Web 前端。详情>>

    不用内置函数

    这个问题的关键思路和上一道题类似,先考虑“4”的幂的二进制表示:

    • 40 = 1B
    • 41 = 100B
    • 42 = 10000B
    • 43 = 1000000B
    • ……

    也就是每个数比上一个数的二进制后面多两个零嘛。最重要的是,“4”的幂的二进制数只有 1 个“1”。如果仔细阅读过上一篇,你就会知道,判断一个二进制数只有 1 个“1”,只需要:

    JavaScript

    (num & num - 1) === 0

    1
    (num & num - 1) === 0

    但是,二进制数只有 1 个“1”只是“4”的幂的必要非充分条件,因为“2”的奇数次幂也只有 1 个“1”。所以,我们还需要附加的判断:

    JavaScript

    (num & num - 1) === 0 && (num & 0xAAAAAAAA) === 0

    1
    (num & num - 1) === 0 && (num & 0xAAAAAAAA) === 0

    为什么是 num & 0xAAAAAAAA === 0? 因为这个确保 num 的二进制的那个 “1” 出现在“奇数位”上,也就确保了这个数确实是“4”的幂,而不仅仅只是“2”的幂。

    最后,我们得到完整的版本:

    版本3

    JavaScript

    function isPowerOfFour(num) { return num > 0 && (num & (num-1)) === 0 && (num & 0xAAAAAAAA) === 0; };

    1
    2
    3
    4
    function isPowerOfFour(num) {
        return num > 0 && (num & (num-1)) === 0
                       && (num & 0xAAAAAAAA) === 0;
    };

    上面的代码需要加上 num > 0,是因为 0 要排除在外,否则 (0 & -1) === 0 也是 true


    Request消息

    RFC2616中这样定义HTTP Request 消息:

    JavaScript

    Request = Request-Line *(( general-header | request-header(跟本次请求相关的一些header) | entity-header ) CRLF)(跟本次请求相关的一些header) CRLF [ message-body ]

    1
    2
    3
    4
    5
    6
    Request = Request-Line
              *(( general-header
                | request-header(跟本次请求相关的一些header)
                | entity-header ) CRLF)(跟本次请求相关的一些header)
              CRLF
              [ message-body ]

    一个HTTP的request消息以一个请求行开始,从第二行开始是header,接下来是一个空行,表示header结束,最后是消息体。

    请求行的定义如下:

    JavaScript

    //请求行的定义 Request-Line = Method SP Request-URL SP HTTP-Version CRLF //方法的定义 Method = "OPTIONS" | "GET" | "HEAD" |"POST" |"PUT" |"DELETE" |"TRACE" |"CONNECT" | extension-method //资源地址的定义 Request-URI ="*" | absoluteURI | abs_path | authotity(CONNECT)

    1
    2
    3
    4
    5
    6
    7
    8
    //请求行的定义
    Request-Line = Method SP Request-URL SP HTTP-Version CRLF
     
    //方法的定义
    Method = "OPTIONS" | "GET" | "HEAD"  |"POST" |"PUT" |"DELETE" |"TRACE" |"CONNECT"  | extension-method
     
    //资源地址的定义
    Request-URI   ="*" | absoluteURI | abs_path | authotity(CONNECT)

    Request消息中使用的header可以是general-header或者request-header,request-header(后边会讲解)。其中有一个比较特殊的就是Host,Host会与reuqest Uri一起来作为Request消息的接收者判断请求资源的条件,方法如下:

    1. 如果Request-URI是绝对地址(absoluteURI),这时请求里的主机存在于Request-URI里。任何出现在请求里Host头域值应当被忽略。
    2. 假如Request-URI不是绝对地址(absoluteURI),并且请求包括一个Host头域,则主机由该Host头域值决定。
    3. 假如由规则1或规则2定义的主机是一个无效的主机,则应当以一个400(错误请求)错误消息返回。

    实现思路

    1. 通过 js-xlsx 将 Excel 文件解析为 JSON 数据
    2. 根据筛选条件对 JSON 数据进行筛选过滤
    3. 将过滤后的 JSON 数据转换成 js-xlsx 指定的数据结构
    4. 利用 js-xlsx 对转换后的数据生成 Excel 文件

    纸上得来终觉浅,绝知此事要躬行

    其他版本

    上面的版本已经符合了我们的需求,时间复杂度是 O(1),不用循环和递归。

    此外,我们还可以有其他的版本,它们严格来说有的还是“犯规”,但是我们还是可以学习一下这些思路:

    版本4:用 Math.sqrt

    JavaScript

    function isPowerOfFour(num) { num = Math.sqrt(num); return num > 0 && num === (0|num) && (num & (num-1)) === 0; };

    1
    2
    3
    4
    function isPowerOfFour(num) {
        num = Math.sqrt(num);
        return num > 0 && num === (0|num) && (num & (num-1)) === 0;
    };

    版本5:用正则表达式

    JavaScript

    function isPowerOfFour(num) { return /^1(00)*$/g.test(num.toString(2)); };

    1
    2
    3
    function isPowerOfFour(num) {
        return /^1(00)*$/g.test(num.toString(2));
    };

    以上就是所有的内容,这道题有非常多种思路,相当有趣,也比较考验基本功。如果你有自己的思路,可以留言参与讨论。

    下一期我们讨论另外一道题,这道题比这两道题要难一些,但也更有趣:给定一个正整数 n,将它拆成至少两个正整数之和,对拆出的正整数求乘积,返回能够得到的乘积最大的结果

    想一想你的解法是什么?你能够尽可能减少算法的时间复杂度吗?期待你的答案~~

    打赏支持我写出更多好文章,谢谢!

    打赏作者

    Response消息

    响应消息跟请求消息几乎一模一样,定义如下:

    JavaScript

    Response = Status-Line *(( general-header | response-header | entity-header ) CRLF) CRLF [ message-body ]

    1
    2
    3
    4
    5
    6
       Response      = Status-Line              
                       *(( general-header        
                        | response-header      
                        | entity-header ) CRLF)  
                       CRLF
                       [ message-body ]

    可以看到,除了header不使用request-header之外,只有第一行不同,响应消息的第一行是状态行,其中就包含大名鼎鼎的返回码

    Status-Line的内容首先是协议的版本号,然后跟着返回码,最后是解释的内容,它们之间各有一个空格分隔,行的末尾以一个回车换行符作为结束。定义如下:

    JavaScript

    Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

    1
       Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

    相关技术

    如果对某项技术比较熟悉,则可略读/跳过。

    打赏支持我写出更多好文章,谢谢!

    任选一种支付方式

    图片 2 图片 3

    1 赞 7 收藏 2 评论

    返回码

    返回码是一个3位数,第一位定义的返回码的类别,总共有5个类别,它们是:

    JavaScript

    - 1xx: Informational - Request received, continuing process - 2xx: Success - The action was successfully received, understood, and accepted

    • 3xx: Redirection - Further action must be taken in order to complete the request - 4xx: Client Error - The request contains bad syntax or cannot be fulfilled - 5xx: Server Error - The server failed to fulfill an apparently valid request
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      - 1xx: Informational - Request received, continuing process
     
      - 2xx: Success - The action was successfully received,
        understood, and accepted
     
      - 3xx: Redirection - Further action must be taken in order to
        complete the request
     
      - 4xx: Client Error - The request contains bad syntax or cannot
        be fulfilled
     
      - 5xx: Server Error - The server failed to fulfill an apparently
        valid request

    RFC2616中接着又给出了一系列返回码的扩展,这些都是我们平时会用到的,但是那些只是示例,HTTP1.1不强制通信各方遵守这些扩展的返回码,通信各方在返回码的实现上只需要遵守以上边定义的这5种类别的定义,意思就是,返回码的第一位要严格按照文档中所述的来,其他的随便定义。

    任何人接收到一个不认识的返回码xyz,都可以把它当做x00来对待。对于不认识的返回码的响应消息,不可以缓存。

    Electron

    关于作者:十年踪迹

    图片 4

    月影,奇舞团团长,热爱前端开发,JavaScript 程序猿一枚,能写代码也能打杂卖萌说段子。 个人主页 · 我的文章 · 14 ·     

    图片 5

    Header

    RFC2616中定义了4种header类型,在通信各方都认可的情况下,请求头可以被扩展的(可信的扩展只能等到协议的版本更新),如果接收者收到了一个不认识的请求头,这个头将会被当做实体头。4种头类型如下:

    1. 通用头(General Header Fields):可用于request,也可用于response的头,但不可作为实体头,只能作为消息的头。
    JavaScript
    
    general-header = Cache-Control ; Section 14.9 | Connection ; Section
    14.10 | Date ; Section 14.18 | Pragma ; Section 14.32 | Trailer ;
    Section 14.40 | Transfer-Encoding ; Section 14.41 | Upgrade ;
    Section 14.42 | Via ; Section 14.45 | Warning ; Section 14.46
    
    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f4736f14ed955473721-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14ed955473721-2">
    2
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14ed955473721-3">
    3
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14ed955473721-4">
    4
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14ed955473721-5">
    5
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14ed955473721-6">
    6
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14ed955473721-7">
    7
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14ed955473721-8">
    8
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14ed955473721-9">
    9
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f4736f14ed955473721-1" class="crayon-line">
    general-header = Cache-Control            ; Section 14.9
    </div>
    <div id="crayon-5b8f4736f14ed955473721-2" class="crayon-line crayon-striped-line">
                  | Connection               ; Section 14.10
    </div>
    <div id="crayon-5b8f4736f14ed955473721-3" class="crayon-line">
                  | Date                     ; Section 14.18
    </div>
    <div id="crayon-5b8f4736f14ed955473721-4" class="crayon-line crayon-striped-line">
                  | Pragma                   ; Section 14.32
    </div>
    <div id="crayon-5b8f4736f14ed955473721-5" class="crayon-line">
                  | Trailer                  ; Section 14.40
    </div>
    <div id="crayon-5b8f4736f14ed955473721-6" class="crayon-line crayon-striped-line">
                  | Transfer-Encoding        ; Section 14.41
    </div>
    <div id="crayon-5b8f4736f14ed955473721-7" class="crayon-line">
                  | Upgrade                  ; Section 14.42
    </div>
    <div id="crayon-5b8f4736f14ed955473721-8" class="crayon-line crayon-striped-line">
                  | Via                      ; Section 14.45
    </div>
    <div id="crayon-5b8f4736f14ed955473721-9" class="crayon-line">
                  | Warning                  ; Section 14.46
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>
    
    1. 请求头(Request Header Fields):被请求发起端用来改变请求行为的头。
    JavaScript
    
    request-header = Accept ; Section 14.1 | Accept-Charset ; Section
    14.2 | Accept-Encoding ; Section 14.3 | Accept-Language ; Section
    14.4 | Authorization ; Section 14.8 | Expect ; Section 14.20 | From
    ; Section 14.22 | Host ; Section 14.23 | If-Match ; Section 14.24 |
    If-Modified-Since ; Section 14.25 | If-None-Match ; Section 14.26 |
    If-Range ; Section 14.27 | If-Unmodified-Since ; Section 14.28 |
    Max-Forwards ; Section 14.31 | Proxy-Authorization ; Section 14.34 |
    Range ; Section 14.35 | Referer ; Section 14.36 | TE ; Section 14.39
    | User-Agent ; Section 14.43
    
    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-2">
    2
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-3">
    3
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-4">
    4
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-5">
    5
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-6">
    6
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-7">
    7
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-8">
    8
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-9">
    9
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-10">
    10
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-11">
    11
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-12">
    12
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-13">
    13
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-14">
    14
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-15">
    15
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-16">
    16
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-17">
    17
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f0425423013-18">
    18
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f0425423013-19">
    19
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f4736f14f0425423013-1" class="crayon-line">
    request-header = Accept                   ; Section 14.1
    </div>
    <div id="crayon-5b8f4736f14f0425423013-2" class="crayon-line crayon-striped-line">
                   | Accept-Charset           ; Section 14.2
    </div>
    <div id="crayon-5b8f4736f14f0425423013-3" class="crayon-line">
                   | Accept-Encoding          ; Section 14.3
    </div>
    <div id="crayon-5b8f4736f14f0425423013-4" class="crayon-line crayon-striped-line">
                   | Accept-Language          ; Section 14.4
    </div>
    <div id="crayon-5b8f4736f14f0425423013-5" class="crayon-line">
                   | Authorization            ; Section 14.8
    </div>
    <div id="crayon-5b8f4736f14f0425423013-6" class="crayon-line crayon-striped-line">
                   | Expect                   ; Section 14.20
    </div>
    <div id="crayon-5b8f4736f14f0425423013-7" class="crayon-line">
                   | From                     ; Section 14.22
    </div>
    <div id="crayon-5b8f4736f14f0425423013-8" class="crayon-line crayon-striped-line">
                   | Host                     ; Section 14.23
    </div>
    <div id="crayon-5b8f4736f14f0425423013-9" class="crayon-line">
                   | If-Match                 ; Section 14.24
    </div>
    <div id="crayon-5b8f4736f14f0425423013-10" class="crayon-line crayon-striped-line">
                   | If-Modified-Since        ; Section 14.25
    </div>
    <div id="crayon-5b8f4736f14f0425423013-11" class="crayon-line">
                   | If-None-Match            ; Section 14.26
    </div>
    <div id="crayon-5b8f4736f14f0425423013-12" class="crayon-line crayon-striped-line">
                   | If-Range                 ; Section 14.27
    </div>
    <div id="crayon-5b8f4736f14f0425423013-13" class="crayon-line">
                   | If-Unmodified-Since      ; Section 14.28
    </div>
    <div id="crayon-5b8f4736f14f0425423013-14" class="crayon-line crayon-striped-line">
                   | Max-Forwards             ; Section 14.31
    </div>
    <div id="crayon-5b8f4736f14f0425423013-15" class="crayon-line">
                   | Proxy-Authorization      ; Section 14.34
    </div>
    <div id="crayon-5b8f4736f14f0425423013-16" class="crayon-line crayon-striped-line">
                   | Range                    ; Section 14.35
    </div>
    <div id="crayon-5b8f4736f14f0425423013-17" class="crayon-line">
                   | Referer                  ; Section 14.36
    </div>
    <div id="crayon-5b8f4736f14f0425423013-18" class="crayon-line crayon-striped-line">
                   | TE                       ; Section 14.39
    </div>
    <div id="crayon-5b8f4736f14f0425423013-19" class="crayon-line">
                   | User-Agent               ; Section 14.43
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>
    
    1. 响应头(Response Header Fields):被服务器用来对资源进行进一步的说明。
    JavaScript
    
    response-header = Accept-Ranges ; Section 14.5 | Age ; Section 14.6
    | ETag ; Section 14.19 | Location ; Section 14.30 |
    Proxy-Authenticate ; Section 14.33 | Retry-After ; Section 14.37 |
    Server ; Section 14.38 | Vary ; Section 14.44 | WWW-Authenticate ;
    Section 14.47
    
    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f4736f14f4393113224-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f4393113224-2">
    2
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f4393113224-3">
    3
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f4393113224-4">
    4
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f4393113224-5">
    5
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f4393113224-6">
    6
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f4393113224-7">
    7
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f4393113224-8">
    8
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f4393113224-9">
    9
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f4736f14f4393113224-1" class="crayon-line">
    response-header = Accept-Ranges           ; Section 14.5
    </div>
    <div id="crayon-5b8f4736f14f4393113224-2" class="crayon-line crayon-striped-line">
                    | Age                     ; Section 14.6
    </div>
    <div id="crayon-5b8f4736f14f4393113224-3" class="crayon-line">
                    | ETag                    ; Section 14.19
    </div>
    <div id="crayon-5b8f4736f14f4393113224-4" class="crayon-line crayon-striped-line">
                    | Location                ; Section 14.30
    </div>
    <div id="crayon-5b8f4736f14f4393113224-5" class="crayon-line">
                    | Proxy-Authenticate      ; Section 14.33
    </div>
    <div id="crayon-5b8f4736f14f4393113224-6" class="crayon-line crayon-striped-line">
                    | Retry-After             ; Section 14.37
    </div>
    <div id="crayon-5b8f4736f14f4393113224-7" class="crayon-line">
                    | Server                  ; Section 14.38
    </div>
    <div id="crayon-5b8f4736f14f4393113224-8" class="crayon-line crayon-striped-line">
                    | Vary                    ; Section 14.44
    </div>
    <div id="crayon-5b8f4736f14f4393113224-9" class="crayon-line">
                    | WWW-Authenticate        ; Section 14.47
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>
    
    1. 实体头(Entity Header Fields):如果消息带有消息体,实体头用来作为元信息;如果没有消息体,就是为了描述请求的资源的信息。
    JavaScript
    
    entity-header = Allow ; Section 14.7 | Content-Encoding ; Section
    14.11 | Content-Language ; Section 14.12 | Content-Length ; Section
    14.13 | Content-Location ; Section 14.14 | Content-MD5 ; Section
    14.15 | Content-Range ; Section 14.16 | Content-Type ; Section 14.17
    | Expires ; Section 14.21 | Last-Modified ; Section 14.29 |
    extension-header
    
    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f4736f14f7627741631-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f7627741631-2">
    2
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f7627741631-3">
    3
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f7627741631-4">
    4
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f7627741631-5">
    5
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f7627741631-6">
    6
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f7627741631-7">
    7
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f7627741631-8">
    8
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f7627741631-9">
    9
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4736f14f7627741631-10">
    10
    </div>
    <div class="crayon-num" data-line="crayon-5b8f4736f14f7627741631-11">
    11
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f4736f14f7627741631-1" class="crayon-line">
    entity-header  = Allow                    ; Section 14.7
    </div>
    <div id="crayon-5b8f4736f14f7627741631-2" class="crayon-line crayon-striped-line">
                   | Content-Encoding         ; Section 14.11
    </div>
    <div id="crayon-5b8f4736f14f7627741631-3" class="crayon-line">
                   | Content-Language         ; Section 14.12
    </div>
    <div id="crayon-5b8f4736f14f7627741631-4" class="crayon-line crayon-striped-line">
                   | Content-Length           ; Section 14.13
    </div>
    <div id="crayon-5b8f4736f14f7627741631-5" class="crayon-line">
                   | Content-Location         ; Section 14.14
    </div>
    <div id="crayon-5b8f4736f14f7627741631-6" class="crayon-line crayon-striped-line">
                   | Content-MD5              ; Section 14.15
    </div>
    <div id="crayon-5b8f4736f14f7627741631-7" class="crayon-line">
                   | Content-Range            ; Section 14.16
    </div>
    <div id="crayon-5b8f4736f14f7627741631-8" class="crayon-line crayon-striped-line">
                   | Content-Type             ; Section 14.17
    </div>
    <div id="crayon-5b8f4736f14f7627741631-9" class="crayon-line">
                   | Expires                  ; Section 14.21
    </div>
    <div id="crayon-5b8f4736f14f7627741631-10" class="crayon-line crayon-striped-line">
                   | Last-Modified            ; Section 14.29
    </div>
    <div id="crayon-5b8f4736f14f7627741631-11" class="crayon-line">
                   | extension-header
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>
    

    Electron 是什么?

    Electron 是一个可以用 JavaScript、HTML 和 CSS 构建桌面应用程序的。这些应用程序能打包到 Mac、Windows 和 Linux 系统上运行,也能上架到 Mac 和 Windows 的 App Store。

    • JavaScript、HTML 和 CSS 都是 Web 语言,它们是组成网站的一部分,浏览器(如 Chrome)懂得如何将这些代码转为可视化图像。
    • Electron 是一个库:Electron 对底层代码进行抽象和封装,让开发者能在此之上构建项目。
    消息体(Message Body)和实体主体(Entity Body)

    如果有Transfer-Encoding头,那么消息体解码完了就是实体主体,如果没有Transfer-Encoding头,消息体就是实体主体。

    JavaScript

    message-body = entity-body | <entity-body encoded as per Transfer-Encoding>

    1
    2
       message-body = entity-body
                    | <entity-body encoded as per Transfer-Encoding>

    在request消息中,消息头中含有Content-Length或者Transfer-Encoding,标识会有一个消息体跟在后边。如果请求的方法不应该含有消息体(如OPTION),那么request消息一定不能含有消息体,即使客户端发送过去,服务器也不会读取消息体。

    在response消息中,是否存在消息体由请求方法和返回码来共同决定。像1xx,204,304不会带有消息体。

    为什么它如此重要?

    通常来说,每个操作系统的桌面应用都由各自的原生语言进行编写,这意味着需要 3 个团队分别为该应用编写相应版本。而 Electron 则允许你用 Web 语言编写一次即可。

    • 原生(操作系统)语言:用于开发主流操作系统应用的原生语言的对应关系(大多数情况下):Mac 对应 Objective C、Linux 对应 C、Windows 对应 C++。
    消息体的长度

    消息体长度的确定有一下几个规则,它们顺序执行:

    1. 所有不应该返回内容的Response消息都不应该带有任何的消息体,消息会在第一个空行就被认为是终止了。
    2. 如果消息头含有Transfer-Encoding,且它的值不是identity,那么消息体的长度会使用chunked方式解码来确定,直到连接终止。
    3. 如果消息头中有Content-Length,那么它就代表了entity-lengthtransfer-length。如果同时含有Transfer-Encoding,则entity-lengthtransfer-length可能不会相等,那么Content-Length会被忽略。
    4. 如果消息的媒体类型是multipart/byteranges,并且transfer-length也没有指定,那么传输长度由这个媒体自己定义。通常是收发双发定义好了格式, HTTP1.1客户端请求里如果出现Range头域并且带有多个字节范围(byte-range)指示符,这就意味着客户端能解析multipart/byteranges响应。
    5. 如果是Response消息,也可以由服务器来断开连接,作为消息体结束。

    从消息体中得到实体主体,它的类型由两个header来定义,Content-TypeContent-Encoding(通常用来做压缩)。如果有实体主体,则必须有Content-Type,如果没有,接收方就需要猜测,猜不出来就是用application/octet-stream

    它由什么组成?

    Electron 结合了 ChromiumNode.js 和用于调用操作系统本地功能的 API(如打开文件窗口、通知、图标等)。

    • Chromium:Google 创造的一个开源库,并用于 Google 的浏览器 Chrome。
    • Node.js(Node):一个在服务器运行 JavaScript 的运行时(runtime),它拥有访问文件系统和网络权限(你的电脑也可以是一台服务器!)。

    图片 6

    HTTP连接

    HTTP1.1的连接默认使用持续连接(persistent connection),持续连接指的是,有时是客户端会需要在短时间内向服务端请求大量的相关的资源,如果不是持续连接,那么每个资源都要建立一个新的连接,HTTP底层使用的是TCP,那么每次都要使用三次握手建立TCP连接,将造成极大的资源浪费。

    持续连接可以带来很多的好处:

    1. 使用更少的TCP连接,对通信各方的压力更小。
    2. 可以使用管道(pipeline)来传输信息,这样请求方不需要等待结果就可以发送下一条信息,对于单个的TCP的使用更充分。
    3. 流量更小
    4. 顺序请求的延时更小。
    5. 不需要重新建立TCP连接就可以传送error,关闭连接等信息。

    HTTP1.1的服务器使用TCP的流量控制来控制HTTP的流量,HTTP1.1的客户端在收到服务器连接中发过来的error信息,就要马上关闭此链接。关于HTTP连接还有很多细节,之后再详述。

    开发体验如何?

    基于 Electron 的开发就像在开发网页,而且能够无缝地 使用 Node。或者说:在构建一个 Node 应用的同时,通过 HTML 和 CSS 构建界面。另外,你只需为一个浏览器(最新的 Chrome)进行设计(即无需考虑兼容性等)。

    • 使用 Node:这还不是全部!除了完整的 Node API,你还可以使用托管在 npm 上超过 350,000 个的模块。
    • 一个浏览器:并非所有浏览器都提供一致的样式,Web 设计师和开发者经常因此而不得不花费更多的精力,让网站在不同浏览器上表现一致。
    • 最新的 Chrome:可使用超过 90% 的 ES2015 特性和其它很酷的特性(如 CSS 变量)。

    WebSocket

    只从RFC发布的时间看来,WebSocket要晚近很多,HTTP 1.1是1999年,WebSocket则是12年之后了。WebSocket协议的开篇就说,本协议的目的是为了解决基于浏览器的程序需要拉取资源时必须发起多个HTTP请求和长时间的轮训的问题……而创建的。

    两个进程(重点)

    Electron 有两种进程:『主进程』和『渲染进程』。部分模块只能在两者之一上运行,而有些则无限制。主进程更多地充当幕后角色,而渲染进程则是应用程序的各个窗口。

    注:可通过任务管理器(PC)/活动监视器(Mac)查看进程的相关信息。

    • 模块:Electron 的 API 是根据它们的用途进行分组。例如:dialog 模块拥有所有原生 dialog 的 API,如打开文件、保存文件和警告等弹窗。

    待续

    本来是打算在一篇文章里把HTTP和WebSocket两个协议的大致细节理出来,然后进行对比。可是写着写着就发现篇幅可能会比较长,读起来就不那么友好了,那么刚好就再写第二篇吧。第二篇里会将WebSocket的大致情况描述一下,然后和HTTP适用的场景进行对比。

     

    2 赞 15 收藏 1 评论

    图片 7

    主进程

    主进程,通常是一个命名为 main.js 的文件,该文件是每个 Electron 应用的入口。它控制了应用的生命周期(从打开到关闭)。它既能调用原生元素,也能创建新的(多个)渲染进程。另外,Node API 是内置其中的。

    • 调用原生元素:打开 diglog 和其它操作系统的交互均是资源密集型操作(注:出于安全考虑,渲染进程是不能直接访问本地资源的),因此都需要在主进程完成。

    图片 8

    本文由金沙国际官网发布于web前端,转载请注明出处:刨根问底HTTP和WebSocket协议,的性能优化

    关键词: