请教一般后端发送给前端消息该怎么实现 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rqxiao
V2EX    Java

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

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

    场景:用户在扫码支付成功后,第三方支付方会异步回调本系统内的一个地址,希望收到回调返回成功后,给前端发送 您已支付成功订单 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
    liKeYunKeji
        49
    liKeYunKeji  
       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     Solana     1324 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 17:04 PVG 01:04 LAX 09:04 JFK 12:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86