尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Sails 实时请求进阶:掌握 `io.socket.get()` 虚拟 GET 请求的用法与底层原理

Sails 实时请求进阶:掌握 `io.socket.get()` 虚拟 GET 请求的用法与底层原理 后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载io.socket.get()是 Sails 官方浏览器端 Socket 客户端sails.io.js提供的最基础、最常用的实时请求方法它在浏览器里通过 WebSocket/Socket.IO 通道向 Sails 后端发起一次虚拟 GET 请求并复用应用里已有的 HTTP 路由、控制器与蓝图逻辑。读完本文你将掌握io.socket.get()的完整签名、参数与回调语义、与服务端虚拟请求解释器的配合原理并能结合io.socket.request()与io.sails全局配置实现带自定义头、跨域等高级用法。方法签名一览io.socket.get()通过 Socket.IO 向 Sails 服务器发送一个 socket 请求即虚拟 GET 请求其基本调用形式如下io.socket.get(url, data, function (resData, jwres){ // ... });在浏览器中引入 sails.io.js 客户端 后io.socket会作为全局变量存在即可直接调用该方法。它同样适用于 Node.js 环境通过require(sails.io.js)(require(socket.io-client))初始化后自动创建的 socket 挂在初始化变量的socket属性上。参数详解参数类型说明1url((string))目标 URL 路径例如/checkout。必填。2_data_((json?))可选的请求数据。如果提供会被 URL 编码并追加到url之后url中已有的 query string 参数会被保留。3_callback_((function?))可选回调。提供后会在服务器响应时被调用。其中url是唯一必填参数data与callback均可省略。因此你既可以直接写io.socket.get(/users/9, cb)也可以带上查询数据io.socket.get(/users, { limit: 15 }, cb)。关于data的编码细节根据文档说明data若提供会被 URL 编码并追加到url末尾作为查询字符串如果url中本身已带 query 参数它们会被保留。例如io.socket.get(/users?activetrue, { limit: 15 }); // 实际发出的虚拟请求路径约为/users?activetruelimit15这一点与浏览器原生的fetch/ jQuery 的$.get语义相似GET 语义下请求数据以查询字符串承载而非请求体。回调参数参数类型说明1resData((json))Sails 服务器响应中携带的数据如果有。它与jwres.body完全等价。2jwres((dictionary))一个 JSON WebSocket Response虚拟 HTTP 响应对象包含headers一个 ((dictionary))、body((json))和statusCode((number))。也就是说jwres提供了完整的响应元信息HTTP 状态码、响应头而resData只是响应体的快捷别名。实践中常用jwres.statusCode判断请求结果用resData直接取业务数据。完整示例以下示例在浏览器端通过 socket 请求获取id为9的用户记录script io.socket.get(/users/9, function (resData) { // resData {id:9, name: Timmy Mendez} }); /script在 Sails 中GET /users/9会命中 RESTful 蓝图路由 或你在 config/routes.js 中自定义的路由并进入对应控制器动作。因为这是虚拟请求Sails 的服务端会把 Socket.IO 消息解释为一次普通的 HTTP 请求因此你可以用 socket 请求访问任意已注册的路由包括自定义动作、策略保护的资源等而不必为实时功能单独写一套接口。典型应用场景实时聊天应用中用io.socket.get(/messages, { room: general }, cb)拉取历史消息配合 resourceful pubsub 订阅模型实例更新服务端 findOne 蓝图动作 在检测到req.isSocket为真时会自动将请求对应的 socket 订阅到该记录的实例房间轮询式面板、通知列表等场景中用虚拟 GET 替代传统 HTTP 轮询享受 WebSocket 长连接的效率优势。与服务端虚拟请求解释器的配合原理io.socket.get()之所以能用 Socket.IO 模拟出与 HTTP GET 完全一致的请求语义关键在于 Sails 服务端的虚拟请求解释器virtual request interpreter。在 lib/router/index.js 中Router.prototype.route()的注释明确说明Socket.IO 需要借助该方法即router:request事件来模拟一个 connect 风格的路由器因为 socket 无法预先绑定动态路由。整个解释流水线如下虚拟 querystring 解析解析url中的查询字符串对应本文data参数被编码追加后的结果Cookie 解析解析握手阶段携带的 cookie 头Session 加载如果相关为虚拟请求加载会话这也是 socket 请求能共享浏览器登录态的原因默认通过初始握手时的cookie头关联会话虚拟 body 解析运行 body parser解析虚拟请求体私有路由器路由使用 Sails 内置的_privateRouter将请求路由到对应的策略、控制器等兜底处理未匹配到路由时触发router:request:404出错时触发router:request:500。这意味着io.socket.get(/users/9)与浏览器直接发起GET /users/9的 HTTP 请求在 Sails 内部最终会被路由到完全相同的代码路径——这正是 socket 客户端文档 所述复用同一套后端路由的实现基础。仓库中的 虚拟请求解释器测试 与 socket 解释器集成测试 即是对该链路的回归验证。蓝图自动订阅socket 请求的特殊待遇一个值得注意的差异是当请求来自 socket 时蓝图动作会额外执行自动订阅。例如在 findOne 蓝图动作 中if (req._sails.hooks.pubsub req.isSocket) { Model.subscribe(req, [matchingRecord[Model.primaryKey]]); actionUtil.subscribeDeep(req, matchingRecord); }也就是说用io.socket.get(/users/9)查询记录后当前 socket 会自动订阅该记录对应的实例房间此后当该记录发生 update/destroy 时pubsub 钩子 会向房间广播事件浏览器端可通过io.socket.on(user, ...)实时收到消息——这正是一次 GET、持续实时的经典组合。需要自定义请求头升级到io.socket.request()io.socket.get()是对请求做了大量简化约定的高层方法。如果你需要在单个请求中自定义请求头、指定其他 HTTP 方法或精细控制请求体请使用稍低层的io.socket.request()。文档给出的类比很形象二者关系就像 jQuery 的$.get与$.ajax。io.socket.request({ method: get, url: /user/3/friends, data: { limit: 15 }, headers: { x-csrf-token: ji4brixbiub3 } }, function (resData, jwres) { if (jwres.error) { console.log(jwres.statusCode); // 例如 403 return; } console.log(jwres.statusCode); // 例如 200 });io.socket.request()支持method、url、dataJSON 编码为虚拟 HTTP 请求体与headers四个选项适合携带 CSRF token、鉴权头等场景。为所有请求设置默认头io.sails.headers如果希望所有从该 socket 发出的请求包括io.socket.get()都自动携带某些自定义头不需要逐个请求配置而是设置全局配置io.sails.headers。例如在引入脚本后立即配置 CSRF 头script src/js/dependencies/sails.io.js/script script typetext/javascript io.sails.headers { x-csrf-token: % _csrf % }; /scriptsails.io.js在加载后会等待一个事件循环周期再自动连接 socket即io.sails.autoConnect默认开启这正是为了留出时间让你在连接建立前修改io.sails上的全局配置。需要注意如果使用默认的 Grunt 资产管线自动注入 script 标签应把sails.io.js从pipeline.js中排除改为手写script标签引入确保你的内联配置脚本在eager socket开始连接之前执行。除headers外io.sails上还有url默认连接当前脚本所在服务器可改为跨域 Sails 服务器、transports传输方式数组如[polling, websocket]应按序尝试并支持升级且应与服务端sails.config.sockets.transports保持一致、autoConnect是否自动创建并连接io.socket、environmentdevelopment输出完整日志 /production最小日志、reconnection非预期断线时是否自动重连默认false等属性。这些配置也可以在script标签上以 HTML 属性或data-前缀属性方式声明复合值如headers需以 JSON 编码并用单引号包裹。注意事项任意路由皆可通信只要是在 Sails 应用中注册过的路由含蓝图路由、自定义动作都可以通过 socket 请求访问无需额外配置。可调用时机io.socket.get()这类请求方法在 socket 尚未连接时也可以调用调用会被排队待连接建立后按顺序执行见 SailsSocket 方法文档。跨域场景如需让io.socket连接其他服务器可在连接前设置io.sails.url如https://myapp.com并注意服务端 CORS/socket 配置。会话关联默认情况下socket 连接通过初始握手的cookie头关联当前浏览器会话若希望某个 socket 不关联会话可在连接前设置io.sails.query nosessiontrue。小结io.socket.get()是 Sails 实时能力的最小可用入口参数简单、回调语义与 HTTP 一致、可复用全部后端路由还能借助蓝图自动订阅直接接入资源级 pubsub。理解它背后的虚拟请求解释器lib/router/index.js、蓝图自动订阅findOne 动作与全局配置io.sails你就能在真实项目中熟练组合查询 订阅 实时推送的完整链路。进阶需求自定义头、任意方法则平滑升级到io.socket.request()即可。赞分享后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载相关推荐Sails 请求超时控制深入解析 req.setTimeout() 的用法与底层原理Sails 请求超时控制深入解析 req.setTimeout 的用法与底层原理 req.setTimeout 是 Sails基于 Express / No后端Sails 框架 sails.request() 虚拟请求完全指南无端口测试与进程内请求调用Sails 框架 sails.request 虚拟请求完全指南无端口测试与进程内请求调用 导读 sails.request 是 Sails 应用实例提供的一个后端Sails 实时通信使用 io.socket.patch() 通过 WebSocket 发送虚拟 PATCH 请求Sails 实时通信使用 io.socket.patch 通过 WebSocket 发送虚拟 PATCH 请求 io.socket.patch 是 Sails后端上一篇别让级联删除坑了你EF Core 9.0外键更新行为重大变更全解析下一篇SOLAR-10.7b-ko-Y24_v1.0-openmind性能优化指南NPU环境下推理速度提升300%的秘诀创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表