V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rqxiao
V2EX  ›  Java

请教一般后端发送给前端消息该怎么实现

  •  
  •   rqxiao · 2020-08-17 10:33:19 +08:00 · 8406 次点击
    这是一个创建于 1563 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景:用户在扫码支付成功后,第三方支付方会异步回调本系统内的一个地址,希望收到回调返回成功后,给前端发送 您已支付成功订单 xx 元!

    之前没做过消息发送到前端这方面的,想请教下简单的或者常用的做法是什么,就用 websocket ? 现在后台是 springboot,前端是 ios

    第 1 条附言  ·  2020-08-17 18:29:19 +08:00
    嗯 这个系统是给客户端 ios 用的
    52 条回复    2020-08-18 17:12:29 +08:00
    juzzle
        1
    juzzle  
       2020-08-17 10:38:20 +08:00
    刷新一下页面,请求下后端 获取一下支付结果就好了
    aogu555
        2
    aogu555  
       2020-08-17 10:38:32 +08:00
    扫码支付的话一般是让前端做个定时器轮询,不断发请求查询支付状态
    kkkkkrua
        3
    kkkkkrua  
       2020-08-17 10:38:39 +08:00
    别想着同步的方案,前端轮询就行
    janxin
        4
    janxin  
       2020-08-17 10:45:15 +08:00
    websocket, long polling
    dadaoqueyi
        5
    dadaoqueyi  
       2020-08-17 10:54:07 +08:00
    websocket (emq)
    TomatoYuyuko
        6
    TomatoYuyuko  
       2020-08-17 10:58:10 +08:00
    轮询成本最低
    lyusantu
        7
    lyusantu  
       2020-08-17 11:12:49 +08:00
    免费就前端轮询,图方便就买服务,如果量不大的话,GoEazy 还挺方便
    paulee
        8
    paulee  
       2020-08-17 11:28:54 +08:00
    你是想做消息推送吗?一般情况下,前端轮询就行(前端注意轮询频率和边界判断,别写 Bug 把服务器爆了
    wangritian
        9
    wangritian  
       2020-08-17 11:30:57 +08:00
    支付场景轮询就好了,不需要长期推消息
    xuanbg
        10
    xuanbg  
       2020-08-17 11:37:17 +08:00
    一般异步结果前端轮询即可
    LongMaoz
        11
    LongMaoz  
       2020-08-17 11:44:12 +08:00
    轮询就行了,上 WebSocket 也行
    devliu1
        12
    devliu1  
       2020-08-17 11:48:48 +08:00
    轮询、SSE 、WS 都可以
    xkeyideal
        13
    xkeyideal  
       2020-08-17 11:52:38 +08:00
    拉倒最后一个评论才说出最好的方式,sse 啊,一个半双工的场景,用 ws 干啥,轮询那么浪费资源,考虑一下服务端压力呢
    ky11223344
        14
    ky11223344  
       2020-08-17 12:00:36 +08:00
    可以试试 server sent events, 看下 js 的 EventSource API
    liuzhaowei55
        15
    liuzhaowei55  
       2020-08-17 12:03:25 +08:00 via iPhone
    前端倒数 5 秒然后到后台查询结果,现在大部分都是这个操作吧
    fhsan
        16
    fhsan  
       2020-08-17 13:06:12 +08:00
    eventsource
    wc951
        17
    wc951  
       2020-08-17 13:50:46 +08:00 via Android
    有一项远古的技术叫 dwr
    yingqi7
        18
    yingqi7  
       2020-08-17 14:00:48 +08:00 via iPhone
    感觉大家都前端轮询,或者用户刷新返回消息
    sujin190
        19
    sujin190  
       2020-08-17 14:11:07 +08:00
    这种等待时间不会很长的,合适的做法还是 ajax 请求后保持直到有数据或者超时,要实现保持也有很多方法,比如 redis 的 pubsub,zookeeper,或者用分布式锁服务啥的都很方便,websocket 会复杂一些,也需要单独长连接处理服务才能支持,不能直接在 web 中实现成一个 rest api

    https://github.com/snower/slock

    用 go 实现过这样一个锁服务,分布式 Event 的语义也很简单,使用支付 ID 为 key,已 1 为 lock_id 在创建订单的时候锁住,前端等待的时候尝试 2 为 lock_id 获取锁,异步通知的时候释放 lock_id 为 1 的锁,这时候 lock_id 为 2 的获取成功就代表这个分布式 Event 被激活了也就是支付完成,前端等待会立刻收到反馈返回,搞定
    berlin4h
        20
    berlin4h  
       2020-08-17 14:11:36 +08:00
    1 、支付页面生成一个唯一标识
    2 、付款成功后支付页面服务端发起请求,查询唯一标识是否支付成功
    3 、服务器收到请求,查询。如果未支付,进入等待(wait),不立即返回
    4 、一旦收到第三方通知支付成功,立即返回(notify)
    5 、页面收到结果,做后续处理
    步骤大概如此,但是有个问题,步骤 2 如果请求超时,如何处理?处理方式是,一段时间没有扫描后,后端返回 timeout,前端重新发起一个相同的网络请求
    ebony0319
        21
    ebony0319  
       2020-08-17 14:24:32 +08:00
    BBCCBB
        22
    BBCCBB  
       2020-08-17 14:37:27 +08:00
    场景简单的话 server sent events 应该是简单靠谱的方案. 好像 twitter 都在用.
    rf99wSiT6IxH1Z23
        23
    rf99wSiT6IxH1Z23  
       2020-08-17 15:56:40 +08:00   ❤️ 2
    三种方案:
    1. Long polling
    2. WebSocket
    3. Server Sent Events

    链接地址: https://javascript.info/

    正好我也有类似需求
    edk24
        24
    edk24  
       2020-08-17 16:20:57 +08:00
    只有这一个场景的话 可以考虑轮询

    二维码扫码登录也是用的轮询
    dallaslu
        25
    dallaslu  
       2020-08-17 17:22:55 +08:00
    轮询最简单,但是短轮询有可能有一点延迟感。长轮询会好一些。Spring Boot 用可以换 Undertow,用上 WebAsyncTask
    gitjavascript
        26
    gitjavascript  
       2020-08-17 17:30:55 +08:00
    这种东西轮询就好了,没必要搞麻烦的
    wysnylc
        27
    wysnylc  
       2020-08-17 17:50:28 +08:00
    websocket-socketio
    不要使用 http 轮询,不及时而且浪费资源,最终还是得升级成 websocket 还不如一步到位
    zachlhb
        28
    zachlhb  
       2020-08-17 17:51:23 +08:00 via Android
    iOS 可以做推送,APP 上收到推送后进行相应的处理
    zhlssg
        29
    zhlssg  
       2020-08-17 17:58:30 +08:00   ❤️ 1
    long polling 的性能并不比轮询好
    OHyn
        30
    OHyn  
       2020-08-17 18:01:08 +08:00
    轮循最简单,有点追求就上 websocket
    OHyn
        31
    OHyn  
       2020-08-17 18:01:40 +08:00
    对了,还有 server sent events,这个最合适。
    bagel
        32
    bagel  
       2020-08-17 18:03:18 +08:00
    说 Server Sent Events 的,没看到是 iOS 吗。都不在浏览器里。
    las917vki
        33
    las917vki  
       2020-08-17 18:10:04 +08:00
    長轮询就行了。
    sprit
        34
    sprit  
       2020-08-17 18:18:42 +08:00
    不能叫前端叫客户端
    BoarBoar
        35
    BoarBoar  
       2020-08-17 18:45:04 +08:00
    轮询实现简单,性能低。ws 性能高但实现相对复杂,特别是如果其他场景都是 http 的话,需要重写一些组件比如鉴权,为了一个性能要求不高的场景显然是不划算的
    devliu1
        36
    devliu1  
       2020-08-17 23:08:09 +08:00
    补充一下,SSE 只是一种传输方式,和浏览器没有必然的联系。
    ccraohng
        37
    ccraohng  
       2020-08-18 07:56:09 +08:00 via Android
    观察 大厂们相关服务,云后台,类似的都是轮训。性能低从何谈起
    Nich0la5
        38
    Nich0la5  
       2020-08-18 09:11:52 +08:00 via Android
    虽然轮训的确性能低,但大厂都在用
    pkoukk
        39
    pkoukk  
       2020-08-18 09:59:35 +08:00
    这种情况就是典型的轮询
    CantSee
        40
    CantSee  
       2020-08-18 09:59:52 +08:00
    必然是轮询!让他循环查询,间隔个一两秒!
    CantSee
        41
    CantSee  
       2020-08-18 10:01:19 +08:00
    @xkeyideal 是 IOS 不是 H5
    xkeyideal
        42
    xkeyideal  
       2020-08-18 10:19:39 +08:00
    @CantSee 看一下楼主补充的时间与我回复的时间
    linxb
        43
    linxb  
       2020-08-18 10:22:53 +08:00
    @Nich0la5 simple is best 轮训最可靠
    2506810
        44
    2506810  
       2020-08-18 10:39:25 +08:00
    这种情况下当然是轮询了,用了 websocket 的话技术复杂度增加,而且 nginx 配置还得改
    2506810
        45
    2506810  
       2020-08-18 10:42:16 +08:00
    轮询技术难度低方便扩展,而且你看微信公众号或阿里云二维码登录都是 2 秒一次轮询后台的
    admingyu
        46
    admingyu  
       2020-08-18 10:48:49 +08:00
    只是这个场景没必要 websocket,就每隔两秒请求一次服务器该订单的支付状态,有结果之后跳转就行了
    wyz123723
        47
    wyz123723  
       2020-08-18 11:10:14 +08:00
    setinterval 循环完事儿了
    evam
        48
    evam  
       2020-08-18 11:30:41 +08:00
    pytth
        49
    pytth  
       2020-08-18 12:27:32 +08:00
    定时轮询,例如 2 秒请求一次支付结果
    1 、发起支付请求,向数据库创建订单,标记为未支付
    2 、支付成功后,异步发送支付结果,更新订单,标记为已支付
    3 、轮询当前订单的支付状态
    justin2018
        50
    justin2018  
       2020-08-18 15:27:02 +08:00
    我已支付 支付遇到问题 两个按钮 😁
    stevenkang
        51
    stevenkang  
       2020-08-18 15:46:29 +08:00
    网商银行还款,之前操作后界面上立马就有反应,现在倒计时 5 秒后才有结果,你猜为什么。
    DoUSeeMe
        52
    DoUSeeMe  
       2020-08-18 17:12:29 +08:00
    心跳机制了解一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5849 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:31 · PVG 11:31 · LAX 19:31 · JFK 22:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.