通知和代理有什么区别?

- 代理是一对一的,设置delegate属性,在需要的时候,通过delegate调用selector方法!

- 通知是一对多的,只要发生事件,会以广播的形式,通知所有的监听者


- 通知中心/发布通知的对象不需要知道监听者是谁,发布对象和监听者之间的耦合度很低

- 监听者需要知道通知的名称字符串,如果发布者还传递userInfo字典,监听者同时需要知道字典的键名

- 技巧:在oc的框架中,如果定义通知,通常通知的名字包含“Notification”字样,同时,key会和通知定义写在一起


- 通知监听方法不能有返回值

- 代理可以有返回值

<think>WebSocket HTTP 长轮询都是用于实现服务器客户端之间实时通信的技术,但它们在实现机制、性能适用场景上有显著区别。 ### 1. 通信模型 - **WebSocket**: - 基于 TCP 的全双工通信协议,建立连接后,客户端服务器可以随时主动发送数据。 - 一次 HTTP 握手后,连接升级为 WebSocket 连接(状态码 101),后续通信使用 WebSocket 协议。 - **HTTP 长轮询**: - 客户端发送一个 HTTP 请求到服务器,服务器保持连接打开直到有新数据可发送(或超时)。 - 当服务器有数据时响应请求,客户端收到响应后立即发送新的请求,从而模拟实时通信。 ### 2. 连接开销 - **WebSocket**: - 连接建立后,数据传输开销很小(仅需 2~10 字节的头部)。 - 避免了重复的 HTTP 头部开销。 - **HTTP 长轮询**: - 每个请求/响应都包含完整的 HTTP 头部(通常几百字节)。 - 频繁建立新连接(或保持长连接)导致额外开销。 ### 3. 延迟 - **WebSocket**: - 消息实时到达,无延迟(网络条件允许下)。 - **HTTP 长轮询**: - 服务器有新数据时才能响应,但客户端在收到响应后需要重新发起请求,存在一定延迟。 ### 4. 服务器压力 - **WebSocket**: - 维持大量并发连接时,每个连接占用内存资源,但无频繁连接建立的开销。 - **HTTP 长轮询**: - 服务器需要处理大量并发连接(每个客户端至少一个连接),且频繁重建连接增加 CPU 负担。 ### 5. 适用场景 - **WebSocket**: - 高频双向通信(如聊天、实时游戏、股票行情)。 - 需要低延迟的场景。 - **HTTP 长轮询**: - 兼容性要求高(支持所有 HTTP 代理)。 - 低频更新场景(如通知系统)。 ### 代码示例对比 #### WebSocket 客户端 (JavaScript) ```javascript // 建立 WebSocket 连接 const socket = new WebSocket('ws://example.com/ws'); // 接收消息 socket.onmessage = (event) => { console.log('Received:', event.data); }; // 发送消息 socket.send('Hello Server!'); ``` #### HTTP 长轮询客户端 (JavaScript) ```javascript function longPoll() { fetch('/poll') .then(response => response.text()) .then(data => { console.log('Received:', data); longPoll(); // 立即发起下一次请求 }) .catch(error => { console.error('Polling error', error); setTimeout(longPoll, 5000); // 出错后等待5秒重试 }); } longPoll(); // 开始长轮询 ``` ### 总结 | 特性 | WebSocket | HTTP 长轮询 | |--------------|--------------------|----------------------| | 协议 | WebSocket (TCP) | HTTP (TCP) | | 通信方向 | 全双工 | 半双工(模拟全双工) | | 头部开销 | 极小(仅初始握手) | 每次请求完整头部 | | 延迟 | 极低 | 较高(请求间延迟) | | 服务器资源 | 内存占用高 | CPU 连接占用高 | | 兼容性 | 现代浏览器 | 所有浏览器 | --- §§相关问题§§: 1. WebSocket 协议握手阶段是如何工作的? 2. 在 Java 中如何配置 WebSocket 的最大消息大小? 3. HTTP 长轮询中如何处理服务器端超时? 4. 如何为不支持 WebSocket 的客户端提供降级方案?</think>### WebSocket HTTP 长轮询的区别 #### 1. 连接机制 **WebSocket**: - 建立持久的全双工 TCP 连接 - 通过一次 HTTP 握手升级协议(状态码 101) - 连接保持打开状态,双方可随时发送数据 ```java // WebSocket 连接建立后持续通信 @OnMessage public void onMessage(Session session, String message) { // 随时处理消息 session.getAsyncRemote().sendText("Echo: " + message); } ``` **HTTP 长轮询**: - 客户端发起请求,服务器保持连接直到有数据 - 服务器响应后客户端立即发起新请求 - 本质是多个短连接的序列 ```java // 长轮询伪代码(Servlet实现) protected void doGet(HttpServletRequest req, HttpServletResponse resp) { // 等待新数据(最多30秒) Data data = waitForNewData(30, TimeUnit.SECONDS); resp.getWriter().write(data.toString()); } ``` --- #### 2. 通信效率 | 指标 | WebSocket | HTTP 长轮询 | |--------------|-------------------|-------------------| | 头部开销 | 初始握手后无开销 | 每次请求完整HTTP头| | 延迟 | 毫秒级 | 取决于轮询间隔 | | 带宽占用 | 极低 | 较高(重复头部) | | 连接数 | 1个持久连接 | 频繁重建连接 | --- #### 3. 数据流动方向 **WebSocket**: - 全双工通信 - 服务端可主动推送数据 - 无需客户端请求即可发送 **HTTP 长轮询**: - 半双工通信 - 服务器只能在响应时发送数据 - 客户端必须主动发起请求 --- #### 4. 适用场景 **WebSocket 适用场景**: - 实时聊天应用 - 在线多人游戏 - 金融实时行情推送 - 协作编辑工具 **HTTP 长轮询适用场景**: - 兼容旧版浏览器/代理 - 低频更新场景(如通知系统) - 需要穿透严格防火墙的环境 --- #### 5. 协议支持 **WebSocket**: - 独立协议(ws:// 或 wss://) - 支持二进制文本帧 - 内置心跳保活机制 **HTTP 长轮询**: - 基于标准 HTTP/1.1 - 只支持文本数据传输 - 需手动实现超时重试 --- #### 6. 资源消耗比较 ```mermaid graph LR A[客户端] -->|WebSocket| B[1个TCP连接] A -->|长轮询| C[每30秒新建TCP连接] B --> D[恒定内存占用] C --> E[频繁TCP握手/TLS协商] D --> F[低CPU开销] E --> G[高CPU开销] ``` --- ### 技术选型建议 1. **选择 WebSocket 当**: - 需要毫秒级实时性 - 高频双向数据交换 - 现代浏览器环境 2. **选择长轮询当**: - 需要兼容旧版 IE 浏览器 - 数据更新频率低(>1分钟) - 网络环境有严格协议限制 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值