前端WebSocket实战:别再只会用HTTP了

前端WebSocket实战:别再只会用HTTP了

前端WebSocket实战:别再只会用HTTP了

毒舌时刻

这代码写得跟网红滤镜似的——仅供参考。

各位前端同行,咱们今天聊聊前端WebSocket。别告诉我你还在用轮询获取实时数据,那感觉就像每隔一分钟就去敲门问"好了没"——烦人又低效。

为什么你需要WebSocket

最近看到一个项目,实时聊天功能用轮询实现,每秒请求一次服务器,我差点当场去世。我就想问:你是在做实时通信还是在做DDoS攻击?

反面教材

// 反面教材:轮询获取数据 function startPolling() { setInterval(async () => { const response = await fetch('/api/messages'); const messages = await response.json(); updateMessages(messages); }, 1000); // 每秒请求一次 } // 服务器:求放过 // 带宽:我扛不住了 

毒舌点评:这代码,我看了都替你的服务器着急。每秒轮询一次,你是想让服务器变成蜜蜂吗?

前端WebSocket的正确姿势

1. 基础WebSocket使用

// 正确姿势:基础WebSocket class WebSocketClient { constructor(url) { this.url = url; this.ws = null; this.reconnectAttempts = 0; this.maxReconnectAttempts = 5; this.listeners = new Map(); } connect() { this.ws = new WebSocket(this.url); this.ws.onopen = () => { console.log('WebSocket连接成功'); this.reconnectAttempts = 0; this.emit('open'); }; this.ws.onmessage = (event) => { const data = JSON.parse(event.data); this.emit(data.type, data.payload); }; this.ws.onclose = () => { console.log('WebSocket连接关闭'); this.emit('close'); this.reconnect(); }; this.ws.onerror = (error) => { console.error('WebSocket错误:', error); this.emit('error', error); }; } send(type, payload) { if (this.ws && this.ws.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify({ type, payload })); } } on(event, callback) { if (!this.listeners.has(event)) { this.listeners.set(event, []); } this.listeners.get(event).push(callback); } emit(event, data) { if (this.listeners.has(event)) { this.listeners.get(event).forEach(callback => callback(data)); } } reconnect() { if (this.reconnectAttempts < this.maxReconnectAttempts) { this.reconnectAttempts++; console.log(`尝试重连... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`); setTimeout(() => this.connect(), 3000); } } disconnect() { if (this.ws) { this.ws.close(); } } } // 使用 const ws = new WebSocketClient('wss://api.example.com/ws'); ws.on('open', () => { console.log('连接成功'); }); ws.on('message', (data) => { console.log('收到消息:', data); }); ws.connect(); 

2. React中使用WebSocket

// 正确姿势:React中使用WebSocket import { useEffect, useRef, useState, useCallback } from 'react'; function useWebSocket(url) { const [isConnected, setIsConnected] = useState(false); const [messages, setMessages] = useState([]); const ws = useRef(null); useEffect(() => { ws.current = new WebSocket(url); ws.current.onopen = () => setIsConnected(true); ws.current.onclose = () => setIsConnected(false); ws.current.onmessage = (event) => { const data = JSON.parse(event.data); setMessages(prev => [...prev, data]); }; return () => { ws.current.close(); }; }, [url]); const sendMessage = useCallback((message) => { if (ws.current && ws.current.readyState === WebSocket.OPEN) { ws.current.send(JSON.stringify(message)); } }, []); return { isConnected, messages, sendMessage }; } // 使用 function ChatRoom() { const { isConnected, messages, sendMessage } = useWebSocket('wss://chat.example.com'); const [input, setInput] = useState(''); const handleSend = () => { sendMessage({ type: 'chat', content: input }); setInput(''); }; return ( <div> <div>状态: {isConnected ? '已连接' : '未连接'}</div> <div className="messages"> {messages.map((msg, i) => ( <div key={i}>{msg.content}</div> ))} </div> <input value={input} onChange={e => setInput(e.target.value)} /> <button onClick={handleSend}>发送</button> </div> ); } 

3. 使用Socket.io

// 正确姿势:使用Socket.io import { io } from 'socket.io-client'; const socket = io('https://api.example.com', { transports: ['websocket'], autoConnect: true, reconnection: true, reconnectionAttempts: 5, reconnectionDelay: 3000 }); // 连接事件 socket.on('connect', () => { console.log('连接成功, ID:', socket.id); }); // 断开连接 socket.on('disconnect', () => { console.log('连接断开'); }); // 监听消息 socket.on('message', (data) => { console.log('收到消息:', data); }); // 发送消息 socket.emit('chat message', { text: 'Hello' }); // 加入房间 socket.emit('join room', 'room-1'); // 离开房间 socket.emit('leave room', 'room-1'); 

毒舌点评:早这么写,你的实时通信早做好了。别告诉我你还在用轮询,那你还是趁早去用短信吧。

实战技巧:WebSocket指南

1. WebSocket使用场景

  • 实时聊天:即时通讯
  • 实时数据:股票、比分
  • 协同编辑:多人协作
  • 在线游戏:实时对战

2. 最佳实践

  1. 重连机制:断线自动重连
  2. 心跳检测:保持连接活跃
  3. 消息确认:确保消息送达
  4. 错误处理:优雅处理异常

最后想说的

WebSocket不是新技术,是实时通信的标准。别再只会用HTTP了——WebSocket一下,你的应用会实时起来。

WebSocket就像电话,HTTP就像写信。紧急的事打电话,不急的事写信。别什么事都写信,学会打电话。

Read more

AI绘画新选择:Z-Image-Turbo与Stable Diffusion对比体验

AI绘画新选择:Z-Image-Turbo与Stable Diffusion对比体验 你有没有试过在深夜赶一张海报,输入十几遍提示词,等三分钟生成,结果发现手部多长了两根手指?或者为了调一个参数翻遍GitHub Issues,最后发现只是少装了一个依赖?AI绘画的门槛,从来不在创意,而在环境、速度和确定性。 最近用上ZEEKLOG星图镜像广场里的「集成Z-Image-Turbo文生图大模型」镜像后,我重新打开了本地AI绘图的可能——不是“能跑”,而是“秒出”;不是“差不多”,而是“一眼就对”。它不靠堆步数换质量,也不靠降分辨率保流畅,而是用9步、1024×1024、开箱即用的方式,把文生图这件事拉回“所想即所得”的节奏。本文不讲架构论文,不列参数表格,只从真实使用出发,把Z-Image-Turbo和我们最熟悉的Stable Diffusion(SD 1.5 + SDXL)放在同一台RTX 4090D机器上,比生成速度、比细节还原、比提示词宽容度、比部署成本—

【数字图像处理与FPGA实现】00 绪,建立“算法思维“与“硬件思维“的桥梁

【数字图像处理与FPGA实现】00 绪,建立“算法思维“与“硬件思维“的桥梁

0、初衷 我的历程: 算法->rtl -> 算法&rtl 构建起这座桥,双向互译!直到 “写算法时心中有电路,写FPGA时心中有算法。” 阶段1:我曾是算法的"原教旨主义者"。 最早期,我和许多算法工程师一样,活在 MATLAB/Python/C语言 的抽象象牙塔里。 对我来说,图像就是 imread() 返回的那个完美矩阵, 处理就是调用 conv2() 或 cv2.GaussianBlur()等函数。 数据是静止的、无限的、免费的——内存不够就加条 DIMM, 算得慢就等几秒,边界处理? MATLAB 会帮我 padarray, Python 会帮我

低空经济新实践:无人机如何革新光伏电站巡检

低空经济新实践:无人机如何革新光伏电站巡检

引言:当低空经济遇见新能源革命 在“双碳”战略引领下,光伏电站如雨后春笋般遍布神州大地。截至2023年底,我国光伏发电装机容量已突破6亿千瓦,连续多年位居全球首位。然而,随着光伏电站规模的急剧扩大,传统人工巡检方式已难以满足高效、精准的运维需求。此时,低空经济的崛起为这一痛点带来了创新解法——无人机光伏巡检技术正在重新定义新能源设施的运维模式。 一、传统光伏巡检之困:低效、高风险、不精准 传统光伏巡检主要依赖人工方式,运维人员需要手持红外热像仪等设备,在光伏板阵列中徒步检查。这种方式存在明显短板: 1. 效率低下:一个100MW的光伏电站,人工全面巡检往往需要数周时间 2. 安全风险:高温、高电压环境下作业,人员安全隐患不容忽视 3. 漏检率高:人工目视检查难以发现细微缺陷,问题检出率通常不足70% 4. 数据离散:检查结果依赖个人经验,难以形成标准化数据资产 二、无人机智能巡检系统架构 现代无人机光伏巡检已形成完整的系统解决方案,主要由以下核心模块组成: 2.1 硬件配置 * 飞行平台:

FPGA上实现YOLOv5的一般过程

FPGA上实现YOLOv5的一般过程

在FPGA上实现YOLOv5 YOLO算法现在被工业界广泛的应用,虽说现在有很多的NPU供我们使用,但是我们为了自己去实现一个NPU所以在本文中去实现了一个可以在FPGA上运行的YOLOv5。 YOLOv5的开源代码链接为 https://github.com/ultralytics/yolov5 为了在FPGA中实现YOLOv5,我们首先在VOC数据集上面进行算法的训练,得到训练后的文件,并对训练后的文件进行8bit量化操作 得到三个权重文件。 之后为了将这个权重文件发送到FPGA上,所以我们再次使用python去解析这个权重文件,然后按照我们的FPGA加速器的架构对权重进行重组 解析的Python文件示意如下 得到的权重数据示意如下: 之后呢再来看一下yolov5的网络结构 放大一个局部来看一下,可以看到就是一些卷积,cat等操作 所以我们在FPGA实现的时候也是去实现这些基本的算子 FPGA上实现的结构图如下所示 在每个算子里面都是分为in_buf,out_buf,和控制模块计算模块组成 然后每个模块会有一堆的控制信号来控制整个NPU