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

[新手请教] PHP 如何向前端主动发起操作

  •  
  •   spip232 · 2017-10-09 18:25:25 +08:00 · 4944 次点击
    这是一个创建于 2603 天前的主题,其中的信息可能已经有所发展或是发生改变。

    类似秒杀的一个活动,现在的问题是,当商品被抢走后,怎么向前端发起信息,让在线用户看到该商品被标记成已结束抢购?后台使用 php 新手求指导,请前辈详细说下思路,非常感谢

    41 条回复    2017-10-10 20:02:44 +08:00
    silov
        1
    silov  
       2017-10-09 18:35:29 +08:00
    1.前端主动校验
    2.socket
    yhxx
        2
    yhxx  
       2017-10-09 18:47:02 +08:00
    没写过秒杀,瞎猜一下
    用库存行吗
    sgq1990
        3
    sgq1990  
       2017-10-09 18:57:46 +08:00
    长连接 swoole webSocket
    keenwon
        4
    keenwon  
       2017-10-09 19:01:42 +08:00
    server send event
    shoaly
        5
    shoaly  
       2017-10-09 19:04:44 +08:00   ❤️ 1
    1 我看到的网站都是这样处理的, 不用告诉前端已经抢完了, 前端继续提交交易订单, 然后再订单提交的地方后端这个时候再查库存, 如果发现没有库存, 那么下单就失败并且提示用户秒杀的商品没有了!
    2 事实上的秒杀如果真的访问量非常大的话, 并不会去实时检查这个库存的, 太费资源, 步凑 1 中严格说来 涉及到事务锁操作
    spip232
        6
    spip232  
    OP
       2017-10-09 19:13:51 +08:00
    @shoaly 秒杀库存只有 1 件,我是想当商品被抢了之后,当前打开的用户会看到商品已经被抢的标记(结束了),对于您说的 1 我是有提示的,但是现在我不懂向前台发送操作,商品开始秒杀后,即时被抢了,已经打开的商品列表中商品的倒计时还是不停的倒计下去,我就想被抢了就停止倒计时并标记结束
    spip232
        7
    spip232  
    OP
       2017-10-09 19:14:29 +08:00
    @sgq1990
    @keenwon
    @silov
    好的,我搜索下
    Immortal
        8
    Immortal  
       2017-10-09 19:28:57 +08:00   ❤️ 2
    感觉你思路走偏了
    一般处理逻辑是这样的:
    1\所有用户进入页面,看到的都是倒计时,然后抢购开始
    2\某一个用户抢购成功,其他用户(等待倒计时结束并停留在页面中的用户)还是在能够点击抢购,但是服务端返回已被购买,然后页面变成已结束
    3\这时候如果新用户进入到当前页面,直接是结束状态

    这样是不会涉及主动推送的,虽然你这样用户体验会好一些.
    而且这种我个人觉得轮询都够了,上 websocket 不是很有必要,比如在抢购开始后几秒检查一下状态
    spip232
        9
    spip232  
    OP
       2017-10-09 19:55:42 +08:00
    @Immortal 有个商品列表页的,这个列表页的商品会一直倒计时,如果商品被抢了,不提示就一直倒计时,这样给用户的感觉不好,看起来还在进行,点进去又结束,用户体验不好
    spip232
        10
    spip232  
    OP
       2017-10-09 19:58:49 +08:00
    @Immortal 你说的是商品详情页,是我没说清楚,我现在要解决的是列表页,就是有很多商品同时在倒计时状态,然后可能某一件被抢购了,就要标记那个商品结束了而不是继续倒计时
    dobelee
        11
    dobelee  
       2017-10-09 20:01:12 +08:00 via Android
    需要前端主动 ajax 才行。现在可以考虑 Websocket,但是很少这么做的。
    spip232
        12
    spip232  
    OP
       2017-10-09 20:08:30 +08:00
    @keenwon 了解了下 SSE,应该能满足我的需求,谢谢您
    spip232
        13
    spip232  
    OP
       2017-10-09 20:09:15 +08:00
    @dobelee 我尝试了 AJAX,定时请求,但是消耗有点大,就又去掉了
    spip232
        14
    spip232  
    OP
       2017-10-09 20:09:57 +08:00
    @dobelee 因为是在商品列表页使用
    Pastsong
        15
    Pastsong  
       2017-10-09 20:30:54 +08:00
    SSE 标准已经被边缘化了,而且 MS 系浏览器不支持(不打算支持)
    spip232
        16
    spip232  
    OP
       2017-10-09 20:43:24 +08:00
    @Pastsong 嗯,搜索到的资料也不多,SSE 在单个商品页我还能处理,可是在商品列表页怎么处理我弄不明白,SSE 能传递参数吗?
    @keenwon
    qiayue
        17
    qiayue  
       2017-10-09 20:47:08 +08:00
    websocket 轻松解决
    spip232
        18
    spip232  
    OP
       2017-10-09 20:51:32 +08:00
    @qiayue 因为 ws 还要 python,后台还要安装其他的,我还没搞明白,新手。。。
    singer
        19
    singer  
       2017-10-09 20:54:01 +08:00 via iPhone
    1、Swoole 的 websocket,秒杀结束了就向所有的连接发送秒杀结束的请求,
    2、同一,断开连接(前端用 js 判断断开后小时结束秒杀)
    3、前端主动请求后端,不断请求,直到秒杀结束。(服务器消耗特别大)
    spip232
        20
    spip232  
    OP
       2017-10-09 20:55:56 +08:00
    @singer 您说的这个是不是比较适合商品详情页,如果列表页呢?有多个商品需要推送呢?
    qiayue
        21
    qiayue  
       2017-10-09 20:58:31 +08:00
    用 nodejs 起一个 ws 服务,也就几十行代码
    php 与 nodejs 可以用 http 通讯,也可以用 socket
    spip232
        22
    spip232  
    OP
       2017-10-09 21:00:08 +08:00
    @qiayue 好的,我了解去
    singer
        23
    singer  
       2017-10-09 21:01:31 +08:00 via iPhone
    @spip232 都可以的,后端可以返回数组。比如说列表里有 1、2、3、4 四个商品,2 被秒杀完了。你主动推送 2 被秒杀完的请求。比如 array ("2"=>"0"){这个具体内容你自己定义,这是个例子},前端就用 js 解析这个请求就可以了。
    dobelee
        24
    dobelee  
       2017-10-09 21:34:59 +08:00 via Android
    @spip232 列表的话,永远只 ajax 一个,不是每个商品都 ajax 分开的。
    zjsxwc
        25
    zjsxwc  
       2017-10-09 21:54:29 +08:00 via Android
    用 ajax 轮询呗,要注意的是必须搞几个和业务无关的独立的服务器来专门处理这种 ajax 轮询请求,秒杀这种瞬间流量大的请求一多会把业务服务器搞卡出翔。
    Immortal
        26
    Immortal  
       2017-10-09 22:10:30 +08:00
    @spip232
    额,你的意思是你的秒杀是一个限时秒杀,在一定时间内被秒杀或者倒计时结束后没有被购买都算做结束?
    这个要根据你列表的量级和同时秒杀数来看,我个人觉得就算是用 ajax 也不会有太大的问题,一请求到已经结束,当前这个 ajax 就不会再进行查询请求了,这个主要是要解决一个峰值的问题,不能让页面的所有用户同一时间全部进行查询,这个你自己考虑怎么解决,比如一定时间内的随机值.

    建议你先进行下性能测试,ajax 完全能满足需求的话就直接 ajax,上 websocket 会多很多工作,比如其他同学说的另外开一个服务什么的,一旦多一个服务就要多保证一个服务的稳定,部署维护也是增加一定的负担,虽然代码没多少.如果 ajax 不能满足在走 websocket
    spip232
        27
    spip232  
    OP
       2017-10-09 23:06:49 +08:00
    @Immortal
    “一请求到已经结束,当前这个 ajax 就不会再进行查询请求了”这个跟您说的一样,目前是使用 ajax,结束了不会在让其请求,现在的问题就是峰值不好控制
    Moker
        28
    Moker  
       2017-10-09 23:20:00 +08:00
    展示和提交的时候做好状态约定即可
    spip232
        29
    spip232  
    OP
       2017-10-09 23:21:33 +08:00
    @Moker 是列表页哦?您是只用 ajax 直接轮询吗?
    Moker
        30
    Moker  
       2017-10-09 23:31:32 +08:00
    @spip232 是的,这种方案是可以的,性能也还不错,简单,列表页的频率不需要那么频繁,点详情或者提交的时候再去查询一次,如果库存已经是 0,前端可以更新状态。
    dangyuluo
        31
    dangyuluo  
       2017-10-09 23:34:23 +08:00
    如果你不想使用其他库比如 websocket 的话,我觉得 ajax 是一个比较好的方法。
    Sapp
        32
    Sapp  
       2017-10-09 23:47:47 +08:00 via Android
    socket 推送消息,然后前端处理就行了
    conn4575
        33
    conn4575  
       2017-10-09 23:48:40 +08:00
    秒杀不都是用队列吗?
    spip232
        34
    spip232  
    OP
       2017-10-10 09:07:33 +08:00
    @Moker 那就要用户主动点击才行了对吗?你是不是这个意思?我是需要及时不点击也要更新状态
    Moker
        35
    Moker  
       2017-10-10 10:14:42 +08:00
    @spip232 你可以定时请求啊
    spip232
        36
    spip232  
    OP
       2017-10-10 10:44:42 +08:00
    @Moker 我现在就是这么做,但很明显一轮询就感觉服务器反应压力大了
    ZXCDFGTYU
        37
    ZXCDFGTYU  
       2017-10-10 12:11:25 +08:00
    别 socket 了,直接就是下单的时候再去查询商品状态,前端页面展示的时候,如果当时没有秒杀完则 js 倒计时,如果秒杀结束则页面显示秒杀结束
    ZXCDFGTYU
        38
    ZXCDFGTYU  
       2017-10-10 12:12:28 +08:00
    这样做简单粗暴短平快,不然你单为了一个消息通知耗费太多没用的时间就太不值当的了
    spip232
        39
    spip232  
    OP
       2017-10-10 12:44:29 +08:00
    @ZXCDFGTYU 我现在需要解决的不是商品详情页哦,是商品列表页,有众多商品需要判断呢
    rozbo
        40
    rozbo  
       2017-10-10 18:16:25 +08:00
    放队列一个个来
    boboliu
        41
    boboliu  
       2017-10-10 20:02:44 +08:00 via Android
    那就动态生成列表页啊。。。

    或者 ws 一把梭挺好的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1351 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:25 · PVG 01:25 · LAX 09:25 · JFK 12:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.