HTML5(十二)——一文读懂 WebSocket 原理

Status Code: 101 Switching Protocols

Connection: Upgrade

sec-websocket-Accept: HBMDBbZMiS59r3aAITpGtJ64Mfc=

Upgrade: websocket

2.3、数据通讯

WebSocket 握手连接成功之后。可以使用 send 进行发送数据,onmessage 接收数据,如下发送“你好”:

let ws= new WebSocket(‘ws://localhost:8888’)

ws.onopen = function(){

console.log(“连接成功”)

ws.send(“你好”)

}

ws.onmessage = function(res){

console.log(‘接收到的消息’,res)

}

服务器打印接收到的数据,如:<Buffer 81 86 af 87 53 b4 4b 3a f3 51 0a 3a>。

websocket 在发送数据时,被组织为一串数据帧,然后进行发送。传送的帧包含两部分:数据帧和控制帧。数据帧可以携带文本数据或者二进制数据,控制帧包含关闭帧和 Ping/Pong 帧。

HTML5(十二)——一文读懂 WebSocket 原理

  • FIN :1bit ,表示是消息的最后一帧,如果消息只有一帧那么第一帧也就是最后一帧。

  • RSV1,RSV2,RSV3:每个1bit,必须是0,除非扩展定义为非零。如果接受到的是非零值但是扩展没有定义,则需要关闭连接。

  • Opcode:4bit,解释Payload数据,规定有以下不同的状态,如果是未知的,接收方必须马上关闭连接。状态如下:0x0(附加数据帧) 0x1(文本数据帧) 0x2(二进制数据帧) 0x3-7(保留为之后非控制帧使用) 0xB-F(保留为后面的控制帧使用) 0x8(关闭连接帧) 0x9(ping) 0xA(pong)

  • Mask:1bit,掩码,定义payload数据是否进行了掩码处理,如果是1表示进行了掩码处理。Masking-key域的数据即是掩码密钥,用于解码PayloadData。客户端发出的数据帧需要进行掩码处理,所以此位是1。

  • Payload length:7位,7 + 16位,7+64位,payload数据的长度,如果是0-125,就是真实的payload长度,如果是126,那么接着后面的2个字节对应的16位无符号整数就是payload数据长度;如果是127,那么接着后面的8个字节对应的64位无符号整数就是payload数据的长度。

  • Masking-key:0到4字节,如果MASK位设为1则有4个字节的掩码解密密钥,否则就没有。

  • Payload data:任意长度数据。包含有扩展定义数据和应用数据,如果没有定义扩展则没有此项,仅含有应用数据。

把接收到的buffer十六进制数据转成二进制数据,控制帧与上述各个类型帧进行对比解析其意义。

2.4、关闭连接

任何一端可以关闭连接。客户端关闭连接如下:

ws.close()

然后发送关闭帧给对方,通常会带有关闭连接的状态码,常见的状态码如下:

  • 1000 连接正常关闭

  • 1001 端点离线,例如服务器down,或者浏览器已经离开此页面

  • 1002 端点因为协议错误而中断连接

  • 1003 端点因为受到不能接受的数据类型而中断连接

  • 1004 保留

  • 1005 保留, 用于提示应用未收到连接关闭的状态码

  • 1006 端点异常关闭

  • 1007 端点收到的数据帧类型不一致而导致连接关闭

  • 1008 数据违例而关闭连接

  • 1009 收到的消息数据太大而关闭连接

  • 1010 客户端因为服务器未协商扩展而关闭

  • 1011 服务器因为遭遇异常而关闭连接

  • 1015 TLS握手失败关闭连接

三、websocket 实例

==============

3.1、客户端创建websocket对象,并建立连接之后发送数据。其中 ws 地址根据后台服务端口对应。

Document

3.2、使用 node.js 创建一个 websocket 服务,如创建一个serve.js文件,代码如下:

const http = require(“http”)

const net = require(“net”) //原生的websocket

const crypto = require(‘crypto’) // 安全性校验

let serve = net.createServer(sock=>{

//只握手一次

sock.once(‘data’,(data)=>{

console.log(“hand shake start”) // 开始握手

let str = data.toString();

let lines = str.split(‘\r\n’)

//舍弃第一行和最后两行

lines = lines.slice(1,lines.length-2)

let headers = {}

lines.forEach(line=>{

let [key,val] = line.split(': ')

headers[key.toLowerCase()] = val

})

if( headers[‘upgrade’]!= ‘websocket’ ){

console.log(“其他协议”)

sock.end()

}else if(headers[‘sec-websocket-version’]!=13){

console.log(“版本不对”)

sock.end()

}else{

let key = headers[‘sec-websocket-key’]

let mask = ‘258EAFA5-E914-47DA-95CA-C5AB0DC85B11’

//sha1(key+mask) -> base64 =>client

let hash = crypto.createHash(‘sha1’)

hash.update(key+mask)

let key2 = hash.digest(‘base64’)

sock.write(HTTP/1.1 101 Switching Protocols\r\nUpgrade:websocket\r\nConnection:Upgrade\r\nsec-websocket-Accept:${key2}\r\n\r\n )

console.log(“hand shake end”) // 握手结束

//真正的数据

sock.on(‘data’,res=>{

console.log(“真正接收数据”,res)

//数据解析

let FIN = res[0]&0x001;

let opcode = data[0]&0x0F0;

let msak = data[1]&0x001;

let payload = data[1]&0x0FE;

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值