在现代应用开发中,网络通信 是几乎绕不开的话题。无论是后端服务之间的调用,还是浏览器与服务器的交互,都离不开底层的网络机制。
随着 AI 应用 和 MCP-Server 的兴起,传统的 HTTP 请求-响应模型 已经无法满足所有需求,流式协议如 SSE(Server-Sent Events) 和 Streamable HTTP 开始被广泛应用。
本文将带你从 Socket 的底层通信方式开始,逐步走向 HTTP 协议 ,并扩展到 SSE 与 Streamable HTTP,构建一个全景式的理解。
🔍 Socket 基础知识
1. 什么是 Socket?
Socket 可以理解为通信的端点。在操作系统层面,它抽象了「进程与进程之间通信」的能力。 常见的两类 Socket:
- TCP Socket:跨主机通信,基于 IP + 端口
- Unix Domain Socket (UDS):本地进程间通信,基于文件路径
2. TCP Socket
TCP Socket 是最常见的网络通信方式,支持跨网络连接,保证数据的 有序性和可靠性。
📌 Node.js 示例:
javascript
const net = require('net');
const server = net.createServer((socket) => {
console.log('客户端已连接');
socket.write('欢迎!');
socket.on('data', (data) => {
console.log('收到数据:', data.toString());
});
});
server.listen(3000, '127.0.0.1', () => {
console.log('服务器监听在 127.0.0.1:3000');
});
3. Unix Domain Socket (UDS)
Unix Domain Socket (简称 UDS)是一种高效的本地通信机制。与 TCP 不同,它使用 文件路径 (如 /tmp/demo.sock
)来标识通信端点,常用于数据库、代理服务器或容器内部通信。
📌 Node.js 示例:
javascript
const net = require('net');
const fs = require('fs');
const socketPath = '/tmp/demo.sock';
if (fs.existsSync(socketPath)) fs.unlinkSync(socketPath);
const server = net.createServer((socket) => {
socket.on('data', (data) => {
console.log('收到数据:', data.toString());
socket.write(`回显: ${data}`);
});
});
server.listen(socketPath, () => {
console.log(`服务器监听在 ${socketPath}`);
});
4. TCP vs Unix Domain Socket
👉 总结:TCP 更通用,UDS 更高效,具体取决于应用场景。
🚀 Node.js 中的 Socket API
Node.js 提供了 net
模块来进行底层网络编程,常用的有两个方法:
1. net.createConnection
javascript
// TCP 连接
net.createConnection(3000, 'localhost');
// Unix Domain Socket 连接
net.createConnection('/tmp/socket.sock');
2. socket.connect
javascript
const socket = new net.Socket();
// TCP
socket.connect(3000, 'localhost');
// Unix Domain Socket
socket.connect('/tmp/socket.sock');
📌 区别:
net.createConnection
是便捷方法socket.connect
提供更细粒度的控制
3. API 调用层次
🌐 HTTP 协议与 Node.js
1. HTTP 协议的核心思想
HTTP(HyperText Transfer Protocol)是 应用层协议 ,基于 TCP(或 TLS+TCP = HTTPS)。
它的核心是 请求-响应模型:
- 客户端发起请求
- 服务器返回响应
2. Node.js 内置 HTTP 模块
📌 最简单的 HTTP 服务器:
javascript
const http = require('http');
const server = http.createServer((req, res) => {
console.log(`收到请求: ${req.method} ${req.url}`);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, HTTP!');
});
server.listen(8080, () => {
console.log('HTTP 服务器监听在 8080 端口');
});
3. HTTP 与 Socket 的关系
-
HTTP 运行在 TCP 之上
-
请求过程本质上是:
- 建立 TCP 连接
- 发送 HTTP 请求报文
- 服务端解析并返回响应
👉 可以理解为:HTTP 是对 Socket 的协议化封装。
🖼️ 图解网络模型
HTTP / HTTPS] --> B[传输层
TCP / UDP] B --> C[网络层
IP] C --> D[链路层
以太网 / Wi-Fi] subgraph "Node.js API" A1[http.createServer()] --> A A2[net.createServer()] --> B A3[dgram.createSocket()] --> B end
🔮 新兴协议在 AI 场景中的应用
随着 AI 应用 和 MCP-Server 的兴起,传统的 HTTP 请求-响应模型在很多场景下显得不够灵活。
1. SSE(Server-Sent Events)
- 单向通信:服务端 → 客户端
- 基于
text/event-stream
- 浏览器原生支持
📌 示例:
javascript
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
res.write(`data: 消息 1\n\n`);
2. Streamable HTTP
- 基于 HTTP 分块传输(chunked transfer encoding)
- 请求和响应均可流式化
- 适合 大模型逐 token 输出 、MCP-Server 交互
📌 示例:
javascript
res.write(JSON.stringify({ step: 1, msg: "开始处理" }) + "\n");
res.write(JSON.stringify({ step: 2, msg: "处理中..." }) + "\n");
res.end(JSON.stringify({ step: 3, msg: "完成" }));
3. SSE vs Streamable HTTP
特性 | SSE | Streamable HTTP |
---|---|---|
通信方向 | 单向(服务端 → 客户端) | 双向(请求/响应均可流式) |
协议层 | HTTP 长连接 | HTTP 分块传输 |
使用复杂度 | 简单,浏览器支持 | 较高,需客户端解析分块 |
应用场景 | 聊天消息流、实时推送 | AI 推理、MCP 协议实现 |
🖼️ Node.js 网络协议全景图
(单向推送)] B --> C2[Streamable HTTP
(双向流式)] subgraph Node.js API A1[net / dgram 模块] --> A B1[http 模块] --> B end style A fill:#f6d365,stroke:#333,stroke-width:1px style B fill:#fda085,stroke:#333,stroke-width:1px style C1 fill:#9fd3c7,stroke:#333,stroke-width:1px style C2 fill:#9fd3c7,stroke:#333,stroke-width:1px
🎯 总结
-
Socket 是通信基石
- TCP:跨主机、分布式通信
- UDS:本地高效通信
-
HTTP 是应用层协议
- 基于 Socket 实现
- 支持 Keep-Alive、HTTP/2、HTTPS
-
SSE & Streamable HTTP
- 面向 AI 与 MCP-Server 的实时流式通信
- 补充了传统 HTTP 的不足
理解 从 Socket → HTTP → 流式协议 的演进,有助于我们在不同场景下选择合适的通信方式,写出更高效、健壮的网络应用。