一、设计思路
直播上课的时候如何对学生进行考勤是个问题,本文提供了一个方法仅供参考,就是在直播过程中不定期进行点名,点到的学生必须在30秒(可自定义)内进行回复,否则视为缺席。
点名使用websocket来发送和接收消息。
二、搭建websocket服务器
使用workerman作为websocket服务端。
Linux下启动workerman
启动 php start.php start -d
停止 php start.php stop
查看状态 php start.php status
Windows下启动workerman
首先需要把PHP添加到系统环境变量里面。
启动 右键点击start_for_win.bat,选择【以管理员身份运行】
停止 直接关闭进程
添加websocket事件
修改Applications\Chat\Events.php
添加以下事件
// 直播点名
case 'dianming':
// 非法请求
if(!isset($_SESSION['room_id']))
{
throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
}
$room_id = $_SESSION['room_id'];
$client_name = $_SESSION['client_name'];
$new_message = array(
'type'=>'dianming',
'from_client_id'=>$client_id,
'from_client_name' =>$client_name,
'to_client_id'=>'all',
'content'=>nl2br(htmlspecialchars($message_data['content'])),
'time'=>date('Y-m-d H:i:s')
);
return Gateway::sendToGroup($room_id ,json_encode($new_message));
// 直播点名学员回应
case 'dianming_reply':
// 非法请求
if(!isset($_SESSION['room_id']))
{
throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
}
$room_id = $_SESSION['room_id'];
$client_name = $_SESSION['client_name'];
$new_message = array(
'type'=>'dianming_reply',
'from_client_id'=>$client_id,
'from_client_name' =>$client_name,
'to_client_id'=>'all',
'content'=>nl2br(htmlspecialchars($message_data['content'])),
'time'=>date('Y-m-d H:i:s')
);
return Gateway::sendToGroup($room_id ,json_encode($new_message));
然后重启workerman
三、控制端程序设计
效果如下图所示
点击【点名】按钮后通过websocket发送一条消息,消息内容包含被点名的学员ID或者其他标识,主要JS代码如下
//批量点名
function dianmingsome(){
var checkednum = $("#list_form").find("input[name='memberid[]']:checked").length;
if(checkednum==0){
layer.msg("您还没有选择", {icon: 2});
return false;
}
layer.load(0, {shade: [0.2, '#393D49']});
var useridstr = ",";
$("#list_form").find("input[name='memberid[]']:checked").each(function(index, elem){
useridstr += elem.value +",";
});
var to_client_id = "all";
var to_client_name = "所有人";
ws.send('{"type":"dianming","to_client_id":"'+to_client_id+'","to_client_name":"'+to_client_name+'","content":"'+useridstr+'"}');
layer.msg("点名消息已发送,请等待学员回应...", {icon: 1});
layer.closeAll('loading');
return false;
}
四、被点名端程序设计
效果如下图所示
被点名的学员收到消息后自动弹出提示框,并开始倒计时。
倒计时结束后提示框消失,无法再进行回应。
主要JS代码如下
//弹出层索引
var index11, index12;
//点名倒计时
var reply_timer, reply_timerb;
var leftseconds = 30;
//被点名时
function dianming(from_client_id, from_client_name, content, time){
if(content===undefined){
return false;
}
if(content.indexOf(","+ client_userid +",")>=0){
leftseconds = 30;
clearInterval(reply_timer);
clearInterval(reply_timerb);
index11 = layer.confirm('你被点名了,请在'+ leftseconds +'秒内回应,否则视为缺席。',
{title:'点名时间', btn: ['确定回应','取消']},
function(){
clearInterval(reply_timer);
clearInterval(reply_timerb);
dianming_reply();
dianming_close();
},
function(){
clearInterval(reply_timer);
clearInterval(reply_timerb);
dianming_close();
}
);
reply_timer = setTimeout(function(){
dianming_close();
}, 30000);
reply_timerb = setInterval(function(){
leftseconds--;
if(leftseconds<=0){
clearInterval(reply_timerb);
dianming_close();
}
$(".layui-layer-content").html('你被点名了,请在'+ leftseconds +'秒内回应,否则视为缺席。');
}, 1000);
}
}
//回应点名
function dianming_reply(){
var to_client_id = "all";
var to_client_name = "所有人";
$.ajax({
url: '/zhibod/dianming/replyok',
type: 'POST',
dataType: "json",
data: {"zhiboid":zhiboid},
beforeSend: function(){
layer.load(0, {shade: [0.2, '#393D49']});
},
success: function(result){
if(result.code=="success"){
ws.send('{"type":"dianming_reply","to_client_id":"'+to_client_id+'","to_client_name":"'+to_client_name+'","content":"'+client_userid+'"}');
layer.msg("回应成功", {"icon":1});
}else{
layer.msg(result.msg, {"icon":2});
}
},
error: function(){
layer.msg("系统错误,请联系管理员", {"icon":2});
},
complete: function(){
layer.closeAll('loading');
}
});
}
//关闭点名
function dianming_close(){
layer.close(index11);
}
回应成功后控制端的点名状态会自动更新。