使用Socket.IO协议连接
Created By RV, and licensed with Creative Commons "CC BY-NC-ND 4.0"
目的与场景
在这一章,讲解两个NodeJS节点如何通过Socket.IO协议互联,实现双向RPC调用。
一. 概念
1. Socket.IO协议
Socket.IO是一个基于WebSocket构建的实时通信库,并内置多传输回退机制:
- 优先使用WebSocket,连接失败时自动回退到HTTP长轮询(Long Polling)
- 提供房间(Room)、事件广播等高级模型
- 自带重连、心跳、二进制分帧等能力,连接管理开箱即用
- 浏览器兼容性极好,是浏览器与服务端实时通信的常用选择
与裸WebSocket相比,Socket.IO牺牲部分性能换取更高的连接可靠性和广播能力。
2. Socket.IO在Kree4X中的角色
Socket.IO是第三方库,代码体积较大,不适合内建于kree4n。
kree4n不内置Socket.IO的Provider,需要独立安装:
npm install @kree4js/socketio-listen @kree4js/socketio-attach
- 服务端由
@kree4js/socketio-listen提供,客户端由@kree4js/socketio-attach提供 - 需要手动注册:listen/attach两侧都要注册对应的Connection Provider
- Socket.IO URL使用
io://协议,与服务端的监听地址一一对应
二. 示例代码
在下边的示例中,我们将:
- nodeA作为Socket.IO服务器,监听端口8030,注册calc服务
- nodeB作为Socket.IO客户端,连接nodeA,注册str服务
- nodeB调用nodeA的calc服务
- nodeA调用nodeB的str服务(双向互调)
import Kree4n from '@kree4js/kree4n'
import { SocketioListenConnectionProvider } from '@kree4js/socketio-listen'
import { SocketioAttachConnectionProvider } from '@kree4js/socketio-attach'
// ── Node A(Socket.IO服务器,注册calc服务) ─────────────
const nodeA = Kree4n.create('node-a', 'Socket.IO RPC server')
// SocketioListenConnectionProvider需手动注册后才能识别io:// 协议
nodeA.useConnectionProvider(new SocketioListenConnectionProvider())
nodeA.register('calc', {
add (a, b) { return a + b },
multiply (a, b) { return a * b }
})
nodeA.listen('io://127.0.0.1:8030')
// ── Node B(Socket.IO客户端,注册str服务) ─────────────
const nodeB = Kree4n.create('node-b', 'Socket.IO RPC client')
// SocketioAttachConnectionProvider需手动注册后才能识别io:// 协议
nodeB.useConnectionProvider(new SocketioAttachConnectionProvider())
nodeB.register('str', {
echo (msg) { return `Echo: ${msg}` },
greet (name) { return `Hello, ${name}! (via Socket.IO)` }
})
nodeB.attach('io://127.0.0.1:8030')
await nodeA.start()
await nodeB.start()
// node-b调用node-a的calc服务
const calc = nodeB.service('calc')
const addResult = await calc.add(10, 20) // 30
const mulResult = await calc.multiply(6, 7) // 42
// node-a调用node-b的str服务(双向)
const str = nodeA.service('str')
const echoResult = await str.echo('Socket.IO works!') // "Echo: Socket.IO works!"
const greetResult = await str.greet('World') // "Hello, World! (via Socket.IO)"
三. 须强调的细节
1. 需要手动安装并注册
Socket.IO是第三方库,体积较大,kree4n不内置。使用前需要:
- 安装独立包:
npm install @kree4js/socketio-listen @kree4js/socketio-attach - 服务端注册
SocketioListenConnectionProvider,客户端注册SocketioAttachConnectionProvider:
import { SocketioListenConnectionProvider } from '@kree4js/socketio-listen'
import { SocketioAttachConnectionProvider } from '@kree4js/socketio-attach'
nodeA.useConnectionProvider(new SocketioListenConnectionProvider())
nodeB.useConnectionProvider(new SocketioAttachConnectionProvider())
不注册对应组件,io:// 协议将无法被识别,listen/attach会直接失败。
2. 传输回退
Socket.IO默认优先WebSocket,不可用时回退到HTTP长轮询。在网络中WebSocket被防火墙拦截的环境下,这一机制能保证连接依然可用。
四. 涉及到的API:
1. Socket.IO监听
/**
* 监听传入的Socket.IO连接。
*
* 使用前需安装 @kree4js/socketio-listen并注册SocketioListenConnectionProvider:
* node.useConnectionProvider(new SocketioListenConnectionProvider())
*
* @param {string} url - 要监听的URL,例如 "io://127.0.0.1:8030"。
* @returns {this} 当前实例,用于链式调用。
*/
node.listen(url: string): this
2. Socket.IO连接
/**
* 通过Socket.IO协议连接到远端节点。
*
* 使用前需安装 @kree4js/socketio-attach并注册SocketioAttachConnectionProvider:
* node.useConnectionProvider(new SocketioAttachConnectionProvider())
*
* @param {string} url - 要连接的URL,例如 "io://127.0.0.1:8030"。
* @returns {this} 当前实例,用于链式调用。
*/
node.attach(url: string): this
五. 可运行代码
完整示例代码,参见:12-socketio-protocol.mjs