• HTML学习笔记(九) Web Socket


    WebSocket 是一个建立在 TCP 之上进行全双工通讯的应用层协议

    我们知道,HTTP 协议采用的是请求/响应模式,服务端是不能主动向客户端推送数据的

    若要实现推送功能,一般都是采用 Ajax 轮询,但这样频繁的请求会给服务端带来极大的压力

    WebSocket 协议就是为了解决这种类似的场景而出现的,它允许服务端可以主动向客户端推送数据

    浏览器和服务器通过一次握手,就能在两者之间创建持续性的连接,进行双向数据传输,直至任意一方将其关闭

    目前,基于 SHA 加密方式的握手协议是使用最为广泛的,具体的过程如下:

    • 浏览器向服务器发起一个 HTTP 请求,但是这个请求与普通的请求不同,它会附加一些头部信息

    • 服务器解析头部信息,返回一个响应,这样就能建立起 WebSocket 连接

    一个典型的客户端请求如下:

    GET ws://localhost:5000 HTTP/1.1
    Host: localhost
    Origin: http://localhost:5000
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: 随机字符串
    Sec-WebSocket-Version: 13
    
    • Connection:必须设置为 Upgrade,表示客户端希望升级协议
    • Upgrade:必须设置为 websocket,表示希望将协议升级为 Websocket
    • Sec-WebSocket-Key:随机字符串,与响应中 Sec-WebSocket-Accept 的值做对比验证

    一个典型的服务端响应如下:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: 根据 Sec-WebSocket-Key 计算得到
    Sec-WebSocket-Location: ws://localhost:5000
    
    • Connection:如果值为 Upgrade,表示服务端同意升级协议

    • Upgrade:如果值为 websocket,表示同意将协议升级为 Websocket

    • Sec-WebSocket-Accept:经过服务器确认并加密的 Sec-WebSocket-Key

      Sec-WebSocket-Key 的值拼上一段特殊的字符串 258EAFA5-E914-47DA-95CA-C5AB0DC85B11

      然后使用 SHA1 对这个字符串做哈希,再进行 Base64 编码后,才能得到 Sec-WebSocket-Accept 的值

    在理解了原理之后,我们下面再来看一下具体要怎么使用 WebSocket

    在客户端浏览器中,可以通过构造函数 WebSocket() 创建一个对象,该对象能提供使用 WebSocket 的相关 API

    其中,参数 url 用于指定连接地址,参数 protocol 用于指定可接受的子协议

    WebSocket(url, [protocol])
    

    构造函数返回一个 WebSocket 对象,该对象常用的属性和方法如下:

    • readyState:只读属性,表示连接状态

      0 表示连接尚未建立,1 表示连接已经建立,可以进行通信

      2 表示连接正在关闭,3 表示连接已经关闭,或者不能打开

    • bufferedAmount:只读属性,在缓存中等待传输的字节数

    • onopen:指定 open 事件的监听函数,在连接建立时触发

    • onmessage:指定 message 事件的监听函数,在收到数据时触发

    • onerror:指定 error 事件的监听函数,在发生错误时触发

    • onclose:指定 close 事件的监听函数,在连接关闭时触发

    • send():发送数据

    • close():关闭连接

    var ws = new WebSocket('ws://localhost:5000')
    
    ws.onopen = function(event) { 
        console.log('open')
    }
    
    ws.onmessage = function(event) {
        console.log('message', event.data)
        ws.send('Goodbye')
        ws.close()
    }
    
    ws.onclose = function(event) {
    	console.log('close')
    }; 
    
    ws.onerror = function(event) {
    	console.log('error')
    }
    

    而对于服务器而言,WebSocket 只是一种协议而已,不同的语言和不同的框架会有不同的实现

    下面我们以 Node.js 为例,写一个简单的 Demo

    var express = require('express')
    var expressWs = require('express-ws')
    
    var app = express()
    
    expressWs(app)
    
    app.ws('/', function (ws, req){
        // ws:  WebSocket 实例
        // req:Request 实例
        ws.send('Hello')
        ws.on('message', function (msg) {
            console.log(msg)
        })
    })
    
    var server = app.listen(5000, '127.0.0.1', function() {
        console.log('server running at http://127.0.0.1:5000')
    })
    

    【 阅读更多 HTML 系列文章,请看 HTML学习笔记

  • 相关阅读:
    AS星尘(stardust)粒子系统 学习 3
    AS星尘粒子系统 初识2
    Flex程序启动时initialize、creationComplete、applicationComplete的区分
    翻译:Autofac.Module 介绍(Orchard)
    Notepad Tutorial(1)
    UNC path转载http://www.uwplatt.edu/oit/terms/uncpath.html
    org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy 中一个方法
    工作记录5月9日开始(不断更新中)
    EMF的一些总结(1)——关于Packages and Factories
    转载~final, static和 nested class 总结 原文~http://yulin10.bokee.com/2544792.html
  • 原文地址:https://www.cnblogs.com/wsmrzx/p/12489626.html
Copyright © 2020-2023  润新知