一些在線系統的計時操作的實現(spring-boot計時器使用,時間戳比較先後)

最近在搞一個含有在線考試模塊的系統。既然是考試,必不可少的一部分就是計時了。

總的來說,需要計時的系統大體上分兩種:1.規定時間內的倒計時。2.規定時間段內的計時判斷。

對於第一種倒計時,我覺得下面這篇文章寫的很好,這是鏈接:

https://blog.csdn.net/a13432421434/article/details/71346153

對於第二種倒計時,我並沒有找到合適的,首先介紹一下這個項目的實現,總的是前後端分離,前端試用的是vue,後臺用的是spring-boot。

一開始的想法:就單純前端獲取Internet時間,然後把與後臺返還來的結束時間對比,如果結束就結束。後來一想- -如果考生懂點JS知識,控制檯幾行代碼就可以無限延長考試時間了。

(PS:當然了,也會有很多人說用閉包寫進去就行了)但是這樣是不好的,同樣存在隱患。

後來的想法:前端無時無刻在調用一個接口,將當前的時間傳給後臺(或是間隔一段時間傳),這樣是存在併發隱患,因爲考試的不可能就是一個學生,spring-boot通俗的講只有一個入口,這樣無論間隔多久- -一起傳送的數據仍然是一起的,佔用過大。

再後來的想法:前端不傳數據,由後臺單獨計時,從開始時間計時到規定的結束時間,一旦時間結束了,那就向前端發送考試結束的信息。但是轉念一想,也是不存在的。如果是這樣,前端還是需要不斷的執行一個函數,和上面的想法幾乎沒差別不過就是避免了被懂js的人修改作弊。

最後的想法:利用springboot中的schelling機制,添加計時任務,比如每10分鐘,5分鐘檢查一次考試的數據表數據。通過當前時間和規定開始時間結束時間的比較,來更新當前數據狀態下的考試狀態。未考,考中,已考。

代碼如下

1.現在你的項目啓動項APPLICATION中加入如下的註解

@EnableScheduling //boot定時任務

這是spring-boot的計時任務的必要註解。

2.新建一個類,輸入如下代碼

package com.project.myBeans;

import com.project.entity.Exam;
import com.project.service.ExamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.util.List;

/**
 * @Author: TateBrown
 * @date: 2018/7/3 15:51
 * @param:
 * @return:
 */
@Component
@EnableAutoConfiguration
@RestController
public class SchedulingTask {

    @Autowired
    ExamService examService;

    /**
     * @Description:定時掃描所有考試任務修改考試state.
     * @param: []
     * @return: void
     * @author: TateBrown
     * @Date: 2018/7/3
     */
    @Scheduled(fixedRate = 60000)//每隔一分鐘查一次
    public void CheckExam() {
        List<Exam> list = examService.GetAllExam();
        Timestamp curtime = new Timestamp(System.currentTimeMillis());
        for (Exam tmp : list) {
            Timestamp tmpfinishtime = tmp.getFinishtime();
            Timestamp tmpstarttime = tmp.getStarttime();
            if (curtime.before(tmpstarttime)) {
                tmp.setState(1);
                examService.modify(tmp);
            } else if ((curtime.equals(tmpstarttime) || curtime.after(tmpstarttime)) && (curtime.equals(tmpfinishtime) || curtime.before(tmpfinishtime))) {
                tmp.setState(2);
                examService.modify(tmp);
            } else {
                tmp.setState(3);
                examService.modify(tmp);
            }
        }
    }
}

我這裏的數據是由時間戳進行存儲的,所以上述也是時間戳比較前後的方法。其中第一句是獲取全部考試的信息,第二句是獲取當前的系統時間並轉換成時間戳模式,後面的就是根據當前時間判斷是否更新數據。

優化:存在的優化空間就是對於已考過的考試,我們不需要這樣掃描,我們每次之找出全部未考和考中的考試。這樣的做法是必然需要的,但是這裏我就不貼代碼了。

總結:最後的做法就是符合了邏輯,因爲這必然是有幾場考試同時發生的存在的。而且完全由後臺控制,較被修改的可能較小。

邏輯上講,後臺纔是控制進程的地方,前後端分離的特性應該是把前端後端儘可能的分離開來。可能還有更好的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章