webSocket & SSE

SSE 和 Websocket 的比较 本文详细解析了SSE和WebSocket这两种实现实时通信的技术。SSE是一种基于HTTP的单向通信机制,适用于实时更新数据的应用场景。WebSocket是一种全双工通信协议,支持双向通信,适用于实时互动的应用场景。它们在通信模型、连接性、实时性、浏览器支持和API复杂性等方面存在一些区别。选择SSE还是WebSocket取决于您的应用需求。如果您只需要服务器向客户端推送数据,并且实时性要求不高,SSE是一个简单可行的选择。 阅读详情

一、通讯方式
1.单工通讯
消息只能单方向传输的工作方式。
2.半双工通讯
可以实现双向的通信,但不能双向同时进行传输,必须轮流交替地进行传输。
3.双工通讯
同一时刻可以进行双向传输。
二、实现web实时通讯有很多,如下:
1.常轮询
由浏览器发送一个请求,服务端接收请求后,再没有新数据时先将请求阻塞,直到有新数据或者超时时才返回
2.短轮询
由浏览器发送一个请求,服务端无论是否有新数据都及时响应,http连接结束;(可以通过自定义返回数据标识或者判断数据是否为空来判断这次请求是否有新数据返回)
3.webSocket协议
是一种网络通信协议,是真正的双向平等对话,属于服务器推送技术的一种
4.长连接
服务器端发送完新数据也不断开连接,继续等待下一份新数据,直到超时
5.心跳机制
客户端每个一段时间向服务端发送一个心跳消息,服务器接收心跳消息后恢复同样的心跳消息,直到超出心跳时长还没有响应则认为断开

三、通信技术之websocke实现
1.服务端:
需要导入的依赖:

    < dependency >
        < groupId > javax.websocket </ groupId >
        < artifactId > javax.websocket-api </ artifactId >
        < version > 1.1 </ version >
    </ dependency >
    < dependency >
        < groupId > org.springframework </ groupId >
        < artifactId > spring-websocket </ artifactId >
        < version > 4.0.5.RELEASE </ version >
    </ dependency >

服务端具体实现:


import java.io.IOException;
import java.util.Hashtable;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Controller;
import org.springframework.web.socket.server.standard.SpringConfigurator;

// 该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。
/**
           类似Servlet的注解mapping。无需在web.xml中配置。
 * configurator = SpringConfigurator.class是为了使该类可以通过Spring注入。
*/
@Controller
@ServerEndpoint(value = "/websocket.do/{userId}",configurator = SpringConfigurator.class)
public class WebsocketController {
    // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    private static int index = 0;
    public WebsocketController(){}


    // Hashtable是线程安全的。
    private static Hashtable<WebsocketController, Long> webSocketMap = new Hashtable<WebsocketController, Long>();
    // 与客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;


    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("userId") Long userId,Session session)
    {
        System.out.println("userId:" + userId);
        this.session = session;
        webSocketMap.put(this, userId);
        addOnlineCount();
        System.out.println("有新连接加入!当前在线人数为:" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose()
    {
        webSocketMap.remove(this);
        subOnlineCount();
        System.out.println("当前连接已退出!当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session)
    {
         System.out.println("来自客户端的消息:" + message);
         // 这里就是随便模拟的,请不要在意,实际可以通过userId获得用户名称
         for(WebsocketController soc : webSocketMap.keySet())
         {
             try {
                 if(index % 2 == 0)
                 {
                     soc.sendMessage("小强" + ":" + message);
                 }
                 else
                 {
                     soc.sendMessage("璐璐" + ":" + message);
                 }
            } catch (IOException e) {
                e.printStackTrace();
            }
         }
         index ++;
    }

    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error)
    {
        System.out.println("出错了!!!!");
    }


    /**
     * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException
    {
         this.session.getBasicRemote().sendText(message);
         //this.session.getAsyncRemote().sendText(message);
    }

    // 获取连接数量,保持同步
    public static synchronized int getOnlineCount() 
    {
        return onlineCount;
    }

    // 连接数量加1,保持同步
    public static synchronized void addOnlineCount() 
    {
        WebsocketController.onlineCount++;
    }

    // 连接数量减1,保持同步
    public static synchronized void subOnlineCount() 
    {
        WebsocketController.onlineCount--;
    }
}

前端页面

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>聊天室</title>
</head>
<body >
<input id="text" type="text"/>
<button onclick="send()">发送</button>
<button onclick="closeWebSocket()">关闭连接</button>
<div id="message">
</div>
 在线人数<span id="onlineCount">1</span>人

</body>
<script type="text/javascript" src="http://localhost:8080/leasplat/newFile/js/jquery-3.0.0.js"></script>
<!-- <script type="text/javascript" src="http://localhost:8080/leasplat/newFile/js/websocket.js"></script> -->
<script type="text/javascript">
    var websocket = null;
    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:8080/leasplat/websocket.do/1");
    }
    else {
        alert("对不起!你的浏览器不支持webSocket")
    }
    //连接发生错误的回调方法
    websocket.onerror = function () {
        setMessageInnerHTML("error");
    };
    //连接成功建立的回调方法
    websocket.onopen = function (event) {
        setMessageInnerHTML("加入连接");
    };
    //接收到消息的回调方法
    websocket.onmessage = function (event) {
        setMessageInnerHTML(event.data);
    };
    //连接关闭的回调方法
    websocket.onclose = function () {
        setMessageInnerHTML("断开连接");
    };
    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,
    // 防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        var is = confirm("确定关闭窗口?");
        if (is){
            websocket.close();
        }
    };
    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        // $("#msg").append(innerHTML+"<br/>")
        console.log(innerHTML);
    };
    //关闭连接
    function closeWebSocket() {
        websocket.close();
    }
    //发送消息
    function send() {
        var message = $("#text").val() ;
        websocket.send(message);
        $("#text").val("") ;
    }
</script>
</html>

四、服务端信息推送技术sse
全称:server-sent-event
后端代码:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Random;

/**
 * Created by shiqiang on 2018/2/9.
 */
@Controller
public class SSEController {

    /**
     * 消息推送sse
     *
     * 这里不能进行return 否则后使得连接关闭,sse会默认重连,就陷入了连接、关闭的死循环了
     *
     * evensource.js 不支持sse当浏览器可以引入这个js进行支持
     */
    @RequestMapping(value = "/push", produces = "text/event-stream")
    public void push(HttpServletResponse response) throws Exception{
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf-8");
        while (true) {
            Random r = new Random();
            try {
                Thread.sleep(1000);
                PrintWriter pw = response.getWriter();
                pw.write("data:Testing 1,2,3" + r.nextInt() + "\n\n");
                pw.flush();

                // 当浏览器页面关闭,检测pw flush断开后刷新异常,return进行断开sse
                if (pw.checkError()) {
                    System.out.println("客户端断开连接");
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

前度页面代码块:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<!-- 我是在csdn网站上提取的一个jquery连接地址,大家可以换成你们下载的本地的jquery -->
<script src="http://c.csdnimg.cn/public/common/libs/jquery/jquery-1.9.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
         //只有新式的浏览器才有,EventSource是SSE的客户端
        if (!!window.EventSource) {
            var source = new EventSource('../../push');
            s = '';
            source.addEventListener('open', function(e) {
                console.log("连接打开");
            }, false);
            //添加SSE监听,获得服务器推送的消息
            source.addEventListener('message', function(e) {
                console.log(e);
                s += e.data + "<br/>";
                $('#msgFromPush').html(s);
            }, false);
            // 上次回调事件
            source.addEventListener("connecttime", function(event) {
                console.log("Connection was last established at: " + event.data);
            }, false);
            // 发生错误时
            source.addEventListener('error', function(e) {
                if (e.readyState == EventSource.CLOSED) {
                    console.log('连接关闭');
                } else {
                    // 关闭sse
                    source.close();
                    console.log(e.target.readyState);
                }
            },false);
        } else {
            console.log('你的浏览器不支持SSE');
        }
         /**
          * 上面的方法也可以写成 : source.onMessage = function(e){console.log(e)}
          * 上面的几个方法都可以以类似的方法写
          */
    </script>
</html>

更详细的讲解可以参考:
SSE:
http://javascript.ruanyifeng.com/htmlapi/eventsource.html
webSocket:
http://www.ruanyifeng.com/blog/2017/05/websocket.html

即时通讯开发中WebSocket和SSE技术如何实现Web端消息推送 无需发送 GET 消息并等待服务器响应,客户端只需监听该套接字,接收服务器更新,并使用收到的数据来发起或支持各种交互。与 WebSocket 相比,SSE 的一个优势是它是基于 HTTP 而运行的,不需要其他组件。SSE 是一个更简单且更快的解决方案,但它是不可扩展的。对于只需要能向客户端传输异步服务器消息的 Web 应用程序,服务器发送的事件是一个优雅且简单的解决方案。HTTP 服务器推送也称为 HTTP 流,是一种客户端-服务器通信模式,它将信息从 HTTP 服务器异步发送到客户端,而无需客户端请求。. 阅读详情

相关推荐

SSE与Websocket详解,SSE实现对话框流式输出

WebSocket它允许服务器和客户端之间进行实时的双向通信,即服务器可以主动向客户端发送数据,客户端也可以随时向服务器发送数据。Server-Sent Events(SSE)是一种基于 HTTP 的轻量级协议,允许服务器主动向客户端推送数据。它主要用于实现**单向实时通信**(服务器到客户端),适合需要服务器持续推送数据的场景(如实时通知、股票行情、流式文本输出等)。

警警的博客 2953

消息推送技术(sse、websocket)

消息推送-ajax长短轮循、sse技术、websocket技术

码农之路,向死而生 7002

【Nginx】【SSE】【WebSocket】Nginx配置SSE,WebSocket的转发请求

【Nginx】将普通 HTTP 请求、SSE 请求和 WebSocket 请求分别转发到对应的后端服务。为 SSE 和 WebSocket 提供必要的配置,确保连接的稳定性和实时性。在实际部署中,可以根据服务需求进一步调整参数,例如路径规则、超时时间和认证机制。

qq_59344127的博客 2770

SSE技术和WebSocket技术实现即时通讯

服务器发送事件SSE(Server-Sent Events)是一种基于HTTP的单向通信机制,用于实现服务器主动向客户端推送数据的技术,也被称为“事件流它基于HTTP协议,利用其长链接的特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端实时数据推送。WebSocket 是一种在单个 TCP 连接上进行全双工通信的网络协议。它是 HTML5 中的一种新特性,能够实现 Web 应用程序和服务器之间的实时通信,比如在线聊天、游戏、数据可视化等。

weixin_43599321的博客 6249

SSE 和 WebSocket 应用

SSE 全称 Server-Send Events 基于 HTTP 的单向通信协议。//EventSource 事件 onopen/onmessage/onerror。WebSocket 基于 HTTP 封装的 WS 双向通信协议。

weixin_42176639的博客 1173

SSE vs WebSocket:AI 驱动的实时通信抉择

本文将深入剖析SSE 与 WebSocket 的工作原理、优缺点,并结合代码示例和对比分析,帮助开发者在 AI 应用中选择最合适的实时通信方案。

一点一木 1569

FastAPI 使用案例 & 长链接(SSE & WebSocket)& 缓存框架

本文介绍了FastAPI的路由拆分、缓存和SSE流式响应实现方案。路由拆分采用模块化结构,通过APIRouter实现二级路由管理,支持异步/同步接口;缓存方案使用fastapi-cache2框架,支持Redis等多种后端;SSE流式响应适用于AI对话等场景。文章提供了完整的代码示例和最佳实践,包括目录结构、核心代码实现、启动配置和常见问题说明,帮助开发者快速构建高性能的FastAPI应用。

祁_z 165

WebSocket vs SSE: 实时数据推送到前端的选择与实现(详细)

对比实现Websocket和sse推送给前端数据选择与实现,以及各自的弊端,适用场景等等

todoitbo的博客 2万+

【Python笔记-FastAPI】实时通信(WebSocket & SSE)

使用FastAPI注册后台任务(如:邮件发送、文件处理等异步场景,不影响接口返回),监控后台任务执行进度(进度条功能)的代码示例。

木子家有小可爱的博客 3021

若依(RuoYi)项目里,Quartz定时任务踩坑实录:并发控制、事务回滚与异常处理

本文深入解析若依(RuoYi)项目中Quartz定时任务的并发控制、事务回滚与异常处理三大核心问题。通过实战案例揭示@DisallowConcurrentExecution注解的局限性和Redis分布式锁的应用,详细讲解Spring事务集成方案及多数据源事务管理,并提供生产级监控体系搭建指南,帮助开发者规避Quartz在生产环境中的常见陷阱。

weixin_28731223的博客 413

WVP+ZLM国标平台实战:从设备注册失败到视频播放黑屏,我遇到的5个典型问题与解法

部署WVP+ZLM国标视频平台时,设备注册失败、视频播放黑屏等问题常常让运维人员头疼不已。本文将基于真实运维场景,剖析五个最具代表性的故障案例,提供从网络配置到版本兼容性的全链路解决方案。

weixin_33178839的博客 362

【AI大模型接入SDK】WebSocket & SSE 协议

选用SSE:业务只需要服务端向客户端推送,客户端不需要在长连接通道内回传消息,例如 AI 流式输出、监控日志、消息通知。选用WebSocket:业务需要双方频繁实时交互,例如在线对战游戏、聊天室、实时文档协同。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 4584

CentOS7上装不了最新Chrome?别折腾依赖了,试试这个老版本安装法(附103.0.5060.24 beta下载地址)

本文提供了在CentOS7上安装兼容版Chrome的详细指南,解决了因GLIBC版本限制导致的最新版Chrome无法安装的问题。推荐使用Chrome 103.0.5060.24 beta版本,并附有下载地址和完整安装步骤,包括禁用自动更新和配套工具安装,确保系统稳定性和功能完整性。

weixin_29289821的博客 570

http/sse/websocket 三大协议演化历史以及 sse协议下 node.js express 服务实现打字机案例 & 负载均衡下的广播实现机制

自从2022年底chatgpt上线后,sse就进入了大众的视野,之前是谁知道这玩意是什么?但是打字机的效果看起来是真的很不错,一度吸引了很多人的趋之若鹜,当然了这个东西的确挺好用,而且实现很简单,之前我用python的demo讲了一下SSE的概念,看起来有很多人看,但是并没有说明白这个原理,这次再彻底把这个原理给说明白,而且我发现通过node.js 的Express框架来说明这个概念更加简洁,所以今天就用Express框架来说明SSE概念,这样对前端同学更加友好。

王森的博客 1798

envi反演水质参数_遥感水质反演之反演模型

水质反演的框架图此为反演模型的章节第一部分,统计学基础:概率论、矩阵和数理统计的知识统计学知识框架# 1 基本统计概念知识在于应用,而非记忆!我们都是在样本的层面去操作数据的,以达到对总体性质的估计和推断,拿到一组数据首先进行基本的统计描述,常用的有:样本均值: 样本方差(调整方差)不是除以n,而是n-1, 标准差为样本方差开方即可皮尔逊积矩相关系数(简称相关系数): 相关系数范围在[-1,...

weixin_35275922的博客 3229

Qwen-Image-2.1本地图像生成整合包:8G显存一键部署指南

文生图模型是AI视觉创作的核心技术,其本地化部署需兼顾模型能力、硬件适配与工程易用性。Qwen-Image-2.1作为支持文本生成、图像编辑与多图参考的统一架构模型,突破了传统Diffusion模型在消费级显卡上的运行瓶颈。通过AWQ量化、vLLM推理优化与ComfyUI节点重构,实现8G显存稳定运行,显著降低CUDA环境配置复杂度。该方案面向设计师、教师与普通用户,提供开箱即用的本地AI图像工作流,适用于电商主图迭代、教学配图生成与IP角色延展等真实场景,让高质量图像生成真正走出云端,落地桌面。

weixin_29082143的博客 401

开发者必备的这些API协议,Apipost都支持!

从HTTP到金融报文,Apipost用六大协议支持+5大自动化能力重新定义接口调试!可以说,Apipost是协议万花筒调试自动化的结合体。无论你是写API的老手,还是调微服务的新人,用好这些功能,效率直接起飞!互动话题互动话题:你被哪种协议虐到怀疑人生?A. gRPC流式调试B. ISO8583长度计算C. GraphQL嵌套查询D. Websocket心跳维护。

Kairo_01的博客 957

基于aarch64分析kernel源码 六:kernel_init进程(1号进程)、kthreadd进程(2号进程)

kernel_init进程(1号进程)、kthreadd进程(2号进程)分析

OnlyLove_的博客 766

Web 开发 —— 高阶 WebSocket 和 SSE

随着大语言模型的流行,因为使用了 SSE 或者 Websocket的技术进行流式的交换,使得 SSE 和 Websocket也火了起来,今天我们来讲解,如何在 Solon 中实现 Websocket 服务端和 SSE 服务端。与 Websocket 不同的是,SSE 是单向连接,请求的过程是不带会话连接的,所以需要自己管理好会话。此处只是做简单的鉴权,和消息的回复,如果要实现完整的 IM 服务,还需要做会话的管理的逻辑。我们这里通过一个简易的 im 的服务做为例子。在主类开启 Websocket。

发强-CrazyAirhead的专栏 2227

SerDes系列之如何选择AC耦合电容

交流耦合电容用于隔离PCB互连时的直流分量(Common-mode voltage),同时传递交流分量(Voltage swing),其作用类似于一个高通滤波器,但是,如果电容容值选取不当,使用过程中会产生信号质量问题,典型的应用场景:当包含相同的长串1或0的NRZ数据应用于该高通滤波器时,会发生低频电压跌落,导致低频模式相关抖动(PDJ)。

一只豌豆象的博客 2354

QGis二次开发 —— 2、第一个程序 - 加载栅格tif与矢量shp文件(附源码)

QGis二次开发 —— 2、第一个程序 - 加载栅格tif与矢量shp文件(附源码)

1100

chatGPT流式输出前端实现fetch、SSE、websocket

在 SSE 中,浏览器通过发送 HTTP GET 请求到服务器上特定的 SSE 端点(endpoint),然后服务器通过该连接发送事件(event)和相关数据到客户端,故SSE 主要使用 GET 请求。fetch 本身不直接支持流式输出,但你可以使用 ReadableStream 和 TextDecoder 等 Web Streams API 来实现类似的效果。WebSocket 是一种全双工通信协议,允许客户端和服务器之间进行实时的双向通信,并且支持POST请求。:进入src文件下载所需。

qq_48434912的博客 6900

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SSE 和 WebSocket 的对比

选择SSE还是WebSocket取决于具体的应用需求:如果只需要单向的数据推送,且对实时性要求不高,可以优先考虑SSE。它的实现简单,资源占用较少,适合简单的实时功能。如果需要双向的实时通信,或者对数据传输的效率和延迟有较高要求,那么WebSocket是更合适的选择。在实际开发中,还可以根据项目的具体需求和技术栈来选择合适的方案。例如,在使用Spring框架时,可以通过Spring WebSocket模块轻松集成WebSocket功能;而对于SSE,则可以通过配置响应头和处理流式输出实现。

2401_89793006的博客 1796

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an &ldquo;advanced algorithms&rdquo; book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

实现实时Web应用,使用AJAX轮询、WebSocket、还是SSE呢??

文章目录短轮询(Short Polling)长轮询(Long Polling)Comet “服务器推” (这玩意现在用的很少了,了解一下即可)WebSocket原理:方法:事件:SSE原理事件总结 在日常的开发中,我们经常能碰见服务端需要主动推送给客户端数据的业务场景,比如数据大屏的实时数据、新闻数据、消息中心的未读消息,聊天功能、股票走势、天气情况等等。 我们的方案大概就是轮询、WebSocket、SSE 短轮询(Short Polling) 客户端定期(例如每几秒)发送AJAX请求到服务器。服务器立

Hassan的小博客! 1851

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

SSE和WebSocket

SSE和WebSocket SSE SSE:server send event。服务端发送事件,指服务端主动给客户端推送消息(单向) 服务端代码: package com.example.demo.sse; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CrossOrigin

anyview93的博客 1507

Python Flask 后端向前端推送信息——轮询、SSE、WebSocket

后端向前端推送信息,实现方案有轮询、SSE、WebSocket。本文提供前后端运行代码。

XerCis的博客 7267
上一篇: 通过 Java 获取发起访问的客户端的IP地址
下一篇: java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column aa to TIMESTAMP
code1Boy
博客等级 码龄10年 45粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值