php实现题目抢答、商品秒杀等类型的需求
最近和其他部门合作项目,当然我是负责php接口方面的工作,
get到一些东西,所以来分享记录一下。
项目需求:
题目将通过主持人ipad投射至大屏幕,选手按‘抢答’
按钮进行抢答。抢答成功,选手所在组,以及大屏幕上广播抢答成功者的ipad屏幕,
抢答失败选手,返回抢答失败界面。
需求分析:
这里抢答,其实就是和秒杀活动机制一样了,不过这里场景可能稍微复杂点,
需要用到强弱连接,实时广播,大家可以去看看GatewayWordker当然,今天我们只是单纯
讨论抢答机制是如何实现。那么既然抢答,就要考虑高并发问题了。
思路分析:
1.把题目的状态写在redis里面,比如题目还没有被抢状态为1,抢完状态为0
2.选手进行抢答时,查询redis状态,为0,直接返回,题目已经被抢完;
3.选手进行抢答时,查询redis状态,为1,进入下一步逻辑操作,修改redis状态为0,
进入数据库查询改题目数据,运用行级琐机制。返回逻辑处理结果
框架依然用的是laravel,开发模式用的是仓库模式,这用有利于项目后期的维护和升级。
(数据字段涉及安全,暂时用test1等表示便好)
/******首先进行题目获取,并把题目对应的redis编号改为1******/
/**
* @desc 随机获得抢答题题目
* @date 2017/4/19 17:26
* @param [type]
* @author 十月桂花香十里
* @return [bool or array]
*/
public function getQuickQuestion(){
//获取抢答题随机题号id
$randNum = $this->getRandArray(config('test.start_quick_id'),config('test.end_quick_id'),config('djm.max_quick'));
DB::transaction(function () use ($randNum){
//将抢答题题号id写进redis,值为1题目可以进行抢答,0不可以进行抢答(为了便于后期维护,0和1都可以写进配置文件中)
$redis = PRedis::connection('default');
foreach($randNum as $k=>$v){
$redis->set("check_quick_id_".$v,1);
}
//将数据库中抢答题对应的id记录,test3状态改为可进行抢答
//DjmQuestion::whereIn('id', $randNum)->update(['test3'=>1]);
});
$res = DjmQuestion::whereIn('id', $randNum)
->orderByRaw(DB::raw("FIELD(id, ".implode(',', $randNum).")"))
->get(['id','test1','test2','test3','test4']);
if($res){
foreach($res as $k=>$v){
$res[$k]['test6'] = json_decode($v['test6'],true);
}
//处理需要返回的数组
return $res;
}else return false;
}
/******利用php的array_slice函数实现编号的随机选择******/
/*
* function getTenNum( int $min, int $max, int $num)
* 生成一定数量的随机数
* $min 和 $max: 指定随机数的范围
* $num: 指定生成数量
*/
public function getRandArray($min,$max,$num){
$array = range($min,$max);
shuffle($array);
$array = array_slice($array, -$num);
return $array;
}
/******选手抢答题目逻辑的实现******/
/**
* @desc 选手进行题目的抢答
* @date 2017/4/19 18:19
* @param [$id $uid]
* @author 十月桂花香十里
* @return [bool or array]
*/
public function userQuickAnswer($id='',$uid){
//判断uid是否是答题选手
if(!in_array($uid, config('test1.check_uid'))) return false;
//判断$id是否存在
if($id < config('test1.start_quick_id') || $id > config('test1.end_quick_id')) return false;
//redis判断题目是否可以进行抢答
$redis = PRedis::connection('default');
$check_quick_status = $redis->get("check_quick_id_".$id);
if($check_quick_status ==1){
//运用事务,添加共享锁
//DB::transaction(function () use ($redis,$id){
//将redis的状态和数据库field3改为0,变为不可抢答
//DjmQuestion::where('id',$id)->sharedLock()->update(['test1'=>0]);
//});
//将redis的状态改为0,变为不可抢答
$redis->set("check_quick_id_".$id,0);
//redis绑定此题和选手的关系
$redis->set("check_quick_id_".$id."_".$uid,1);
//获取本条数据记录
return DjmQuestion::find($id)->toArray();
}else return false;
}
/******选手抢答题目回答的实现******/
/**
* @desc 选手进行抢答题的回答
* @date 2017/4/20 10:09
* @param [$id,$uid]
* @author 1245049149@qq.com
* @return [bool or array]
*/
public function userQuickAnswerResult($id,$uid,$answer){
//判断uid是否是答题选手
if(!in_array($uid, config('djm.check_uid'))) return false;
//判断$id是否存在
if($id < config('djm.start_quick_id') || $id > config('djm.end_quick_id')) return false;
//redis判断此题和选手是否绑定关系
$redis = PRedis::connection('default');
$check_user_quick_status = $redis->get("check_quick_id_".$id."_".$uid);
if($check_user_quick_status == 1){
//关系如果已经绑定,判断选手答题情况
$redis->set("check_quick_id_".$id."_".$uid,0);
$check_answer = config('djm.check_answer'); //题目编号答案对照(如果题目数量不多且固定的话,建议写进配置文件中,不用查询数据库)
if($check_answer[$id] == strtoupper($answer)){
//回答正确分数自加5
DjmQuestionScore::where('test10',$uid)
->where('test11',config('djm.quick_test11'))
->increment('test12',5);
return array(
'msg' => '回答正确',
'status' => 1,
);
}else{
//回答错误分数自减5
DjmQuestionScore::where('test10',$uid)
->where('test11',config('djm.quick_test11'))
->decrement('score',5);
return array(
'msg' => '回答错误,正确答案:'.$check_answer[$id],
'test12' => $check_answer[$id],
'status' => 0,
);
}
}else return false;
}
ok,功能至此实现了。
php实现题目抢答、商品秒杀等类型的需求的更多相关文章
- PHP商品秒杀问题解决方案实例详解【mysql与redis】
本文实例讲述了PHP商品秒杀问题解决方案.分享给大家供大家参考,具体如下: 引言 假设num是存储在数据库中的字段,保存了被秒杀产品的剩余数量. if($num > 0){ //用户抢购成功,记 ...
- PHP商品秒杀计时实现(解决大流量方案)
PHP商品秒杀功能我们多半以整点或时间点为例子,这样对于php来说处理不复杂,但有一个问题就是如果流量大要如何来处理,下面我们一起来看看解决办法. 要求要有小时分钟秒的实时倒计时的显示,用户端修改日期 ...
- zookeeper实现商品秒杀抢购
package com.test; import java.io.IOException; import java.util.List; import java.util.concurrent.Cyc ...
- 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层
作者:nnngu 项目源代码:https://github.com/nnngu/nguSeckill 这是一个整合IDEA+Maven+SSM框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...
- Java秒杀系统实战系列~商品秒杀代码实战
摘要: 本篇博文是“Java秒杀系统实战系列文章”的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即“商品秒杀”功能模块的代码实战. 内容: “商品秒杀”功能模块是建立在“商品详情”功 ...
- 02 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之Service层
作者:nnngu 项目源代码:https://github.com/nnngu/nguSeckill 首先在编写Service层代码前,我们应该首先要知道这一层到底是干什么的. Service层主要负 ...
- 03 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之web层
Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 前端交互流程设计 对于一个系统,需要产品经理.前端工 ...
- 04 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之高并发优化
Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 关于并发 并发性上不去是因为当多个线程同时访问一行数 ...
- 使用redis 中的事务处理实现商品秒杀
redis中的事务处理: redis中的事物事物处理是指能够批量的执行一组命令(当事务开始执行时,事务中的命令能够按照按照规定好的顺序执行而不会被插队或打断): 与mysql事务的区别在于:mysql ...
随机推荐
- 微软 深度学习 cntk ,我目前见过 安装方式最简单的一个框架,2.0之后开始支持C# 咯
嗨,你也是我这种手残党么?之前试着安装着mxnet和tensorflow,但是因为时间比较短所以往往来不及安装完就失去兴趣,今天看到微软的cntk可以用了,一次性安装好了,并且测试通过 本人环境: W ...
- MySQL学习笔记(四)—存储过程
一.概述 存储过程是数据库定义的一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程可以避免开发人员重复的编写相同的SQL语句,而且存储过程是在MySq ...
- Mysql清理二进制日志的技巧
1:二进制日志 二进制日志记录了所有的DDL(数据定义语言)语句和DML(数据操作语言)语句,但是不记录包括数据查询的语句.语句以"事件"的形式保存,它描述了数据的更改过程,此日志 ...
- MongoDB基础教程系列--第八篇 MongoDB 副本集实现复制功能
为什么用复制 为什么要使用复制呢?如果我们的数据库只存在于一台服务器,若这台服务器宕机了,那对于我们数据将会是灾难,当然这只是其中一个原因,若数据量非常大,读写操作势必会影响数据库的性能,这时候复制就 ...
- ASP.NET CORE部署到Linux
ASP.NET CORE部署到CentOS中 在Linux上安装.NET Core 参考:https://www.microsoft.com/net/core#linuxcentos 配置Nginx ...
- Java 原始数据类型的计算:运算符重载(Operator Overload)和类型转换(Type Conversion)
原文阅读:<算法(第四版)>第一章 第一节:基础编程模型 有没有在面试的时候被问到:下面这几行代码的执行结果是什么?依据是什么? System.out.println (5/3); Sys ...
- java复习(9)---数据库JDBC
java写工程当然需要连接数据库.JDBC技术是连接数据库和应用程序的纽带,本节主要说明如何连接数据库. java中提供sql类. package re09; import java.sql.*; p ...
- while循环语句的几种方式
我们知道,在Python中经常我们要使用循环,其中最常用的是while循环,while有很多结合方式,我们知道,如果一个循环没有结束语句那么就失去了意义,所以我们一定要有结束语句,下面来看看while ...
- 篇2 安卓app自动化测试-初识python调用appium
篇2 安卓app自动化测试-初识python调用appium --lamecho辣么丑 1.1概要 大家好!我是lamecho(辣么丑),上一篇也是<安卓app自动化测 ...
- CSS3 基础知识[转载minsong的博客]
CSS3 基础知识1.边框 1.1 圆角 border-radius:5px 0 0 5px; 1.2 阴影 box-shadow:2px 3px 4px 5px rgba(0,0,0 ...