如题 spring 全家桶用习惯了 换个东西反而写不出来了
后来学了一段时间 socket 实现了前后端通信
现在还有一个问题卡了很久没解决,请教各位大佬
一场拍卖假如说一共有 5 个阶段,其中每个阶段都有倒计时,有些操作会影响倒计时,比如出价加 5 秒,之类的。然后我要从 socket 里实时的读取到当前是什么阶段的什么状态,倒计时还剩多少秒。
其实一开始感觉不复杂,就到了实现的时候发现,线程也已经忘了怎么写了。。。百度也找不到合适的框架什么的能刚好合适这个需求。
今天就只想求个思路,比如说用 MQ 好,还是自己手搓线程好,还是怎么实现最合理。Thanks♪(・ω・)ノ 谢谢
1
yumenawei 2023-10-30 09:40:08 +08:00
搜一下 websocket 看下,我也没具体了解过,好像可以解决你的问题
|
2
doublestart 2023-10-30 09:41:31 +08:00
一个用户出价, 然后通过发送消息给其他用户就行了, 用户量不大, 没必要用 MQ
|
3
bigLinux 2023-10-30 09:42:20 +08:00
当发生一些会影响倒计时的操作时,让前端发一个 UDP 的消息给后端,发消息的同时前端加上 5 秒,然后服务器收到这个消息也加上 5 秒。
|
4
doublestart 2023-10-30 09:42:58 +08:00
先学习下网络编程, 游戏服务端开发相关的, 找个开源项目看看
|
5
kujio 2023-10-30 09:44:52 +08:00
如果是会影响倒计时的操作,任何用户发送了这些操作,就同步发送给所有用户,通知他们重新倒计时,并带上倒计时开始时间
|
6
awalkingman 2023-10-30 09:45:00 +08:00
要实时,不就是 websocket 双工通信或者高频 http 定时轮询吗,这个语言框架有啥关系?
要定时,redis 或者别的中间件设置一下过期时间。就一台机子一个服务的话在应用里自己设置过期时间也行。 总之和语言没关系。 |
7
banmuyutian 2023-10-30 09:46:25 +08:00 3
|
8
janwarlen 2023-10-30 09:47:09 +08:00
@banmuyutian #7 啊?
|
9
darkengine 2023-10-30 09:48:13 +08:00
客户端只负责发起 ’我要出价‘ 这个动作
当前时间能不能出价,出价之后加 5 秒这些操作都在服务器端做,完成后把结果告诉客户端 |
10
c2const 2023-10-30 09:49:09 +08:00
@banmuyutian
啊? |
11
lsk569937453 2023-10-30 09:55:20 +08:00 1
把倒计时的时间设计成 redis 的 key 的过期时间,所有的前后端通信只走 http 。
1.拍卖人员点击"开始拍卖",则写入 redis 中一个 key ,并且过期时间为 1 分钟。 购买人员打开网页,则前端以每 0.5 秒一个的定时任务去请求这个 key 的剩余时间。如果购买人员点击加价,则将 redis 的 key 的过期时间加 5 秒。 这个方案还有一些细节,比如想要记录一个购买阶段的截止时间,而 redis 中的 key 过期就删除了,则需要配合数据库一起完成。 |
12
zzzmh OP 我好像没描述准确,现在是用 springboot websocket ,实现了前后端交互,现在缺流程控制,比如说后端在 19.00 分给前端发启动拍卖,并给前端一个初始倒计时,然后中间加入的人,也会在初始化的时候,得到一个与其他人同步的倒计时。然后进入下一阶段,也会给前端发进入下一阶段,倒计时剩余多少时间。然后有人出价就会增加倒计时秒数,并同步给其他人。以此类推。现在就是这个倒计时怎么实现我很蛋疼,可能是网站写多了,游戏没学过,现在思路转变不过来。
|
13
zzzmh OP @lsk569937453 多谢,感觉合适
|
14
lsk569937453 2023-10-30 10:02:20 +08:00 1
技术方案 2:
在数据库/redis 中记录最终的时间,然后前端去计算秒数,所有的前后端通信只走 http 。 1.拍卖人员点击"开始拍卖",则写入 redis 中一个 key ,且 value 值为当前时间+1 分钟后的时间。 购买人员打开网页,则前端以每 0.5 秒一个的定时任务去请求这个 key 的时间,然后计算出剩余的倒计时。如果购买人员点击加价,则将 redis 的 key 的过期时间加 5 秒。 |
15
lsk569937453 2023-10-30 10:02:49 +08:00
@lsk569937453 如果购买人员点击加价,则将 redis 的 key 的 value 的时间加 5 秒。
|
16
banmuyutian 2023-10-30 10:05:29 +08:00
|
17
asmoker 2023-10-30 10:05:56 +08:00 via Android
这不就是在线答题差不多
|
18
aibx01 2023-10-30 10:12:29 +08:00
如果仅仅是定时这个需求。
把结束时间存 redis 中,前端也记录一个时间,5s ~10s 去跟后端进行同步即可。每次加时,后端拿到锁之后,去更新 redis 的即可,redis 到期时间设置为 实际的结束时间。如果加时判断 redis 已不存在,则为拍品时间已结束。 |
19
xianyv 2023-10-30 10:14:10 +08:00 1
@zzzmh 倒计时用 redis 的 key 的过期时间,等 redi 的这个 key 过期了,就通过 websocket 通知其他用户拍卖结束.
|
20
zhazi 2023-10-30 10:19:32 +08:00
while true 每秒检查一次就行了
|
21
FawkesV 2023-10-30 10:20:46 +08:00
初始设置是 redis 唯一 key ,value 存最后出价的人,到期时间存为结束时间。
点击加价就加锁来更新 出价人 value 和 结束时间吧 . --- 前端每次出价时,前端也自动更新页面的时间。再用高频轮训 http 请求去获取当前商品的结束竞拍时间, |
22
conjane 2023-10-30 10:33:42 +08:00
可以看看 akka
|
23
sunjiayao 2023-10-30 10:50:26 +08:00
加价 http 请求-> 锁 {redis 加价}-> 加价成功 -> 通过 ws 向所有客户端推送最新价格和时间
|
24
dengji85 2023-10-30 10:57:40 +08:00
前端轮循,后台返回拍卖的属性,拍卖阶段,剩余倒计时;
|
25
relsoul 2023-10-30 10:58:18 +08:00
如果是小项目不要走 websocket ,如果要走 可以试试 socket.io ,我的建议是 直接前端轮询就行( 1s ),减少前后端的心智负担。所有的计算后端放 redis 处理。后端做延迟/定时任务更新 redis 的 key 即可。拍卖完成后落 db 。
如果是大型项目估计也不用我说 架构层应该已经评估了时间与开发量得出了解决方案。 |
26
hush3 2023-10-30 11:06:05 +08:00
后端每秒定时向所有前端发一次消息,当有客户端改价,那计时器肯定要在后端这个改价接口里有变动,但是不影响每秒发给所有前端的逻辑,所有前端也能在下一秒收到改价后的新倒计时。
感觉剩余时间存内存一个变量就行吧 |
27
Keppel 2023-10-30 11:13:38 +08:00
上半年实现了一个类似的拍卖功能,需求都类似
|
28
magicfield 2023-10-30 11:27:55 +08:00
实时的要求就用长连接嘛,实现一般就是 http 轮询或 websocket ,邪道点还能用 hook 。
真实时间由后端控制,放数据库/redis ,小系统直接放缓存都行。 前端时间仅作为显示时间,定期 http 轮询同步或 websocket 同步 |
29
rev1si0n 2023-10-30 11:40:21 +08:00
没试过,redis 的 pubsub 应该可以解决这个问题吧,每个客户连上对应的端点后,自动监听频道,客户端发价后后端验证处理并向频道广播。如果使用 web 框架的话应该也不需要单独开线程直接每个请求对应上去。
|
31
coderxy 2023-10-30 11:44:38 +08:00
你这需求根本不需要 websocket ,倒计时写到 redis 里, 客户端每 200ms 轮询一下当前倒计时并展示出来就完事了。 这种拍卖的业务不可能有多高的并发的。 不然你得自己写一套类似于长连接通讯的东西,对你来说开发量和熟练度都是问题。
|
32
cvbnt 2023-10-30 12:04:51 +08:00 via Android
1 ,开始拍卖后写入 redis 设置倒计时
2 ,用户点击按钮后发送 http 请求到后端,后端对时间进行扣减 3 ,重点:后端要创建一个 server-sent events 接口,拍卖开始后所有用户通过 SSE 接口建立长连接,由 SSE 接口定时返回倒计时时间,用户前端显示倒计时(长连接避免轮询创建 http 请求降低服务器压力,相比 websocket ,sse 改造成本低且所有现代化浏览器都支持 sse ) |
33
Seulgi 2023-10-30 16:07:09 +08:00
实际上不就是一个时间戳,一些动作触发+x 秒的操作,socket 同步给各个用户,页面实现时间戳转倒计时。
|
34
XepMCWEKZ76L695l 2023-10-30 16:56:04 +08:00
@coderxy 正解
|