直播點(diǎn)名簽到系統(tǒng)設(shè)計(jì)

一、設(shè)計(jì)思路

直播上課的時(shí)候如何對(duì)學(xué)生進(jìn)行考勤是個(gè)問題,本文提供了一個(gè)方法僅供參考,就是在直播過程中不定期進(jìn)行點(diǎn)名,點(diǎn)到的學(xué)生必須在30秒(可自定義)內(nèi)進(jìn)行回復(fù),否則視為缺席。

點(diǎn)名使用websocket來發(fā)送和接收消息。

二、搭建websocket服務(wù)器

使用workerman作為websocket服務(wù)端。

Linux下啟動(dòng)workerman

啟動(dòng) php start.php start -d

停止 php start.php stop

查看狀態(tài) php start.php status

Windows下啟動(dòng)workerman

首先需要把PHP添加到系統(tǒng)環(huán)境變量里面。

啟動(dòng) 右鍵點(diǎn)擊start_for_win.bat,選擇【以管理員身份運(yùn)行】

停止 直接關(guān)閉進(jìn)程

添加websocket事件

修改Applications\Chat\Events.php

添加以下事件

// 直播點(diǎn)名
case 'dianming':
    // 非法請(qǐng)求
    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));
// 直播點(diǎn)名學(xué)員回應(yīng)
case 'dianming_reply':
    // 非法請(qǐng)求
    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

三、控制端程序設(shè)計(jì)

效果如下圖所示


點(diǎn)名_1.png

點(diǎn)擊【點(diǎn)名】按鈕后通過websocket發(fā)送一條消息,消息內(nèi)容包含被點(diǎn)名的學(xué)員ID或者其他標(biāo)識(shí),主要JS代碼如下

//批量點(diǎn)名
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("點(diǎn)名消息已發(fā)送,請(qǐng)等待學(xué)員回應(yīng)...", {icon: 1});
  layer.closeAll('loading');
  return false;
}

四、被點(diǎn)名端程序設(shè)計(jì)

效果如下圖所示


點(diǎn)名_2.png

被點(diǎn)名的學(xué)員收到消息后自動(dòng)彈出提示框,并開始倒計(jì)時(shí)。

倒計(jì)時(shí)結(jié)束后提示框消失,無法再進(jìn)行回應(yīng)。

主要JS代碼如下

//彈出層索引
var index11, index12;
//點(diǎn)名倒計(jì)時(shí)
var reply_timer, reply_timerb;
var leftseconds = 30;
 
//被點(diǎn)名時(shí)
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('你被點(diǎn)名了,請(qǐng)?jiān)?lt;span class="layui-badge">'+ leftseconds +'</span>秒內(nèi)回應(yīng),否則視為缺席。', 
      {title:'點(diǎn)名時(shí)間', btn: ['確定回應(yīng)','取消']}, 
      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('你被點(diǎn)名了,請(qǐng)?jiān)?lt;span class="layui-badge">'+ leftseconds +'</span>秒內(nèi)回應(yīng),否則視為缺席。');
    }, 1000);
  }
}
 
//回應(yīng)點(diǎn)名
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("回應(yīng)成功", {"icon":1});
      }else{
        layer.msg(result.msg, {"icon":2});
      }
    },
    error: function(){
      layer.msg("系統(tǒng)錯(cuò)誤,請(qǐng)聯(lián)系管理員", {"icon":2});
    },
    complete: function(){
      layer.closeAll('loading');
    }
  });
}
 
//關(guān)閉點(diǎn)名
function dianming_close(){
  layer.close(index11);
}

回應(yīng)成功后控制端的點(diǎn)名狀態(tài)會(huì)自動(dòng)更新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容