[{"data":1,"prerenderedAt":366},["ShallowReactive",2],{"doc-\u002Fdocs\u002Fwebsocket-basics":3,"docs-all":262},{"id":4,"title":5,"body":6,"category":246,"date":247,"description":248,"draft":249,"extension":250,"meta":251,"navigation":252,"path":253,"seo":254,"source":255,"stem":256,"tags":257,"__hash__":261},"docs\u002Fdocs\u002Fwebsocket-basics.md","WebSocket 基础",{"type":7,"value":8,"toc":239},"minimark",[9,14,18,21,24,27,30,33,39,42,54,97,102,170,174,206,210,213,216,220,223,226,229,232,235],[10,11,13],"h1",{"id":12},"websocket","WebSocket",[15,16,17],"p",{},"WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。",[15,19,20],{},"WebSocket 是在 http的协议上只实现了 Socket 协议的长链接。",[15,22,23],{},"WebSocket 使得客户端和服务器之间的数据交换变得更加简单，允许服务端主动向客户端推送数据。在 WebSocket API 中，浏览器和服务器只需要完成一次握手，两者之间就直接可以创建持久性的连接，并进行双向数据传输。",[15,25,26],{},"在 WebSocket API 中，浏览器和服务器只需要做一个握手的动作，然后，浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。",[15,28,29],{},"很多网站为了实现推送技术，所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔（如每1秒），由浏览器对服务器发出HTTP请求，然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点，即浏览器需要不断的向服务器发出请求，然而HTTP请求可能包含较长的头部，其中真正有效的数据可能只是很小的一部分，显然这样会浪费很多的带宽等资源。",[15,31,32],{},"HTML5 定义的 WebSocket 协议，能更好的节省服务器资源和带宽，并且能够更实时地进行通讯。",[34,35,36],"blockquote",{},[15,37,38],{},"⚠️ 此处原有本地截图，路径已失效，待补。",[15,40,41],{},"浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求，连接建立以后，客户端和服务器端就可以通过 TCP 连接直接交换数据。",[15,43,44,45,49,50,53],{},"当你获取 Web Socket 连接后，你可以通过 ",[46,47,48],"strong",{},"send()"," 方法来向服务器发送数据，并通过 ",[46,51,52],{},"onmessage"," 事件来接收服务器返回的数据。",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-JavaScript shiki shiki-themes github-light github-dark","    var Socket = new WebSocket(url, [protocol] );\n    \u002F\u002F 第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的，指定了可接受的子协议。\n","JavaScript","",[62,63,64,90],"code",{"__ignoreMap":60},[65,66,69,73,77,80,83,87],"span",{"class":67,"line":68},"line",1,[65,70,72],{"class":71},"szBVR","    var",[65,74,76],{"class":75},"sVt8B"," Socket ",[65,78,79],{"class":71},"=",[65,81,82],{"class":71}," new",[65,84,86],{"class":85},"sScJk"," WebSocket",[65,88,89],{"class":75},"(url, [protocol] );\n",[65,91,93],{"class":67,"line":92},2,[65,94,96],{"class":95},"sJ8bj","    \u002F\u002F 第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的，指定了可接受的子协议。\n",[98,99,101],"h2",{"id":100},"websocket-事件","WebSocket 事件",[103,104,105,122],"table",{},[106,107,108],"thead",{},[109,110,111,116,119],"tr",{},[112,113,115],"th",{"align":114},"left","事件",[112,117,118],{"align":114},"事件处理程序",[112,120,121],{"align":114},"描述",[123,124,125,137,148,159],"tbody",{},[109,126,127,131,134],{},[128,129,130],"td",{"align":114},"open",[128,132,133],{"align":114},"Socket.onopen",[128,135,136],{"align":114},"连接建立时触发",[109,138,139,142,145],{},[128,140,141],{"align":114},"message",[128,143,144],{"align":114},"Socket.onmessage",[128,146,147],{"align":114},"客户端接收服务端数据时触发",[109,149,150,153,156],{},[128,151,152],{"align":114},"error",[128,154,155],{"align":114},"Socket.onerror",[128,157,158],{"align":114},"通信发生错误时触发",[109,160,161,164,167],{},[128,162,163],{"align":114},"close",[128,165,166],{"align":114},"Socket.onclose",[128,168,169],{"align":114},"连接关闭时触发",[98,171,173],{"id":172},"websocket-方法","WebSocket 方法",[55,175,177],{"className":57,"code":176,"language":59,"meta":60,"style":60},"Socket.send()           \u002F\u002F 使用连接发送数据\nSocket.clsoe()      \u002F\u002F 关闭连接\n",[62,178,179,193],{"__ignoreMap":60},[65,180,181,184,187,190],{"class":67,"line":68},[65,182,183],{"class":75},"Socket.",[65,185,186],{"class":85},"send",[65,188,189],{"class":75},"()           ",[65,191,192],{"class":95},"\u002F\u002F 使用连接发送数据\n",[65,194,195,197,200,203],{"class":67,"line":92},[65,196,183],{"class":75},[65,198,199],{"class":85},"clsoe",[65,201,202],{"class":75},"()      ",[65,204,205],{"class":95},"\u002F\u002F 关闭连接\n",[98,207,209],{"id":208},"websocket-实例","WebSocket 实例",[15,211,212],{},"WebSocket 协议本质上是一个基于 TCP 的协议。",[15,214,215],{},"为了建立一个 WebSocket 连接，客户端浏览器首先要向服务器发起一个 HTTP 请求，这个请求和通常的 HTTP 请求不同，包含了一些附加头信息，其中附加头信息\"Upgrade: WebSocket\"表明这是一个申请协议升级的 HTTP 请求，服务器端解析这些附加的头信息然后产生应答信息返回给客户端，客户端和服务器端的 WebSocket 连接就建立起来了，双方就可以通过这个连接通道自由的传递信息，并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。",[98,217,219],{"id":218},"websocket-相关api","WebSocket 相关API",[15,221,222],{},"创建 WS 对象： var ws = new WebSocket(url)",[15,224,225],{},"监听连接通信(事件)：ws.onopen = function(){}",[15,227,228],{},"监听服务端消息(事件)：ws.onmessage = function(){}",[15,230,231],{},"发送消息(方法)：ws.send()",[15,233,234],{},"监听通道关闭(事件)：ws.onclose = function(){}",[236,237,238],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":60,"searchDepth":240,"depth":240,"links":241},3,[242,243,244,245],{"id":100,"depth":92,"text":101},{"id":172,"depth":92,"text":173},{"id":208,"depth":92,"text":209},{"id":218,"depth":92,"text":219},"fundamentals","2024-11-03","WebSocket 全双工通信协议的事件、方法与基本用法整理。",false,"md",{},true,"\u002Fdocs\u002Fwebsocket-basics",{"title":5,"description":248},null,"docs\u002Fwebsocket-basics",[12,258,259,260],"network","javascript","notes","HtPSzjQ2myxAPj8xO5ySTcaw_AZ7RwRk5aFxA7EvE98",[263,275,284,290,300,306,314,319,327,332,338,340,347,354,360],{"path":264,"title":265,"description":266,"date":267,"category":268,"tags":269},"\u002Fdocs\u002Ffrontend-coding-standards","前端团队编码规范","HTML \u002F CSS \u002F JavaScript 三端统一的团队编码约定，含缩进、命名、语法与禁用项，可直接作为 Code Review 依据。","2025-12-17","standards",[270,271,259,272,273,274],"html","css","es6","best-practice","guide",{"path":276,"title":277,"description":278,"date":279,"category":280,"tags":281},"\u002Fdocs\u002Fwindows-mklink","Windows mklink 符号链接用法","mklink 各参数区别与实用场景：目录联接、符号链接与硬链接的选择。","2024-12-18","toolchain",[282,283],"windows","cheatsheet",{"path":285,"title":286,"description":287,"date":288,"category":280,"tags":289},"\u002Fdocs\u002Frandom-color-utils","JS 随机颜色生成方法","几种生成随机 RGB \u002F HEX 颜色的实现方式与各自适用场景。","2024-12-11",[259,283],{"path":291,"title":292,"description":293,"date":294,"category":295,"tags":296},"\u002Fdocs\u002Fcanvas-vs-svg","Canvas 与 SVG 绘图方案选型","对比 Canvas 与 SVG 两种绘图方案的优缺点与适用场景，给出选型判断依据。","2024-12-09","visualization",[297,298,299,273],"canvas","svg","performance",{"path":301,"title":302,"description":303,"date":247,"category":280,"tags":304},"\u002Fdocs\u002Ffree-commercial-fonts","免费可商用字体整理","整理思源黑体、思源宋体等可商用中文字体，规避字体版权风险。",[305,271,260],"font",{"path":307,"title":308,"description":309,"date":247,"category":310,"tags":311},"\u002Fdocs\u002Finterview-browser-network","浏览器与网络考点","从输入 URL 到页面呈现的完整链路，涵盖渲染流程、回流重绘、HTTP 报文与状态码、跨域同源策略与常见攻击方式。","interview",[312,313,258,299,260],"browser","http",{"path":315,"title":316,"description":317,"date":247,"category":310,"tags":318},"\u002Fdocs\u002Finterview-css-layout","CSS 与布局考点","em 与 rem 的区别、移动端三种适配方案对比、viewport 标准设置与 REM 布局的媒体查询实现。",[271,270,273,260],{"path":320,"title":321,"description":322,"date":247,"category":310,"tags":323},"\u002Fdocs\u002Finterview-framework-tooling","框架与工程化考点","React diff 与 setState 机制、Redux 核心组成、Vue 常考清单，以及 Webpack、Vite、Git 的面试要点。",[324,259,325,326,260],"vue","webpack","vite",{"path":328,"title":329,"description":330,"date":247,"category":310,"tags":331},"\u002Fdocs\u002Finterview-javascript-core","JavaScript 核心考点","数据类型、this 绑定、闭包、原型链、异步与数组方法，前端面试中 JS 部分的高频考点与代码示例。",[259,272,260],{"path":333,"title":334,"description":335,"date":247,"category":246,"tags":336},"\u002Fdocs\u002Fjs-module-systems","JavaScript 模块化方案","梳理 CommonJS、AMD、ES Module 等模块化方案的差异与使用方式。",[259,337,272,260],"module-system",{"path":253,"title":5,"description":248,"date":247,"category":246,"tags":339},[12,258,259,260],{"path":341,"title":342,"description":343,"date":344,"category":295,"tags":345},"\u002Fdocs\u002Fgojs-getting-started","GoJS 入门实战","从引入方式、画布初始化到节点模板与数据绑定，一份可直接上手的 GoJS 流程图开发笔记。","2024-08-22",[346,259,260],"gojs",{"path":348,"title":349,"description":350,"date":351,"category":295,"tags":352},"\u002Fdocs\u002Fecharts-options-notes","ECharts 配置项速查","整理 ECharts 常用 option 配置：数据格式、坐标轴、图例与交互项的实际用法。","2024-08-09",[353,259,283],"echarts",{"path":355,"title":356,"description":357,"date":358,"category":246,"tags":359},"\u002Fdocs\u002Fhttp-status-codes","HTTP 响应状态码详解","按 1xx 到 5xx 分类梳理 HTTP 状态码的含义与典型使用场景。","2024-06-27",[313,258,283],{"path":361,"title":362,"description":363,"date":364,"category":246,"tags":365},"\u002Fdocs\u002Fhtml-basics","HTML 基础笔记","HTML 语法规范、常用标签、表格与表单元素速查。","2022-06-10",[270,260,283],1788337378702]