解紅濤 ,趙偉林
(1.東北石油大學(xué)計(jì)算機(jī)與信息技術(shù)學(xué)院,黑龍江 大慶 163318;2.武警陜西總隊(duì)機(jī)動(dòng)支隊(duì),陜西 西安 710038)
油田井控指的是在油田生產(chǎn)施工過程中對發(fā)生的井涌及井噴進(jìn)行控制,具體而言是指通過特定的技術(shù)手段,對地下開采區(qū)域的壓力進(jìn)行調(diào)控,以確保井下壓力平衡,從而進(jìn)行油田資源的安全開采[1]。油田井控技術(shù)的正確應(yīng)用能夠有效、及時(shí)地控制井涌井噴,保護(hù)油氣層,避免破壞資源以及環(huán)境污染。因此,油田井控業(yè)務(wù)人員的專業(yè)知識(shí)水平高低決定了能否正確運(yùn)用井控技術(shù)避免油田事故的發(fā)生。為了提高井控業(yè)務(wù)人員的專業(yè)知識(shí)水平,油田企業(yè)開始引進(jìn)并實(shí)施各種員工培訓(xùn)計(jì)劃方案。傳統(tǒng)的紙質(zhì)資料培訓(xùn)、講課培訓(xùn),主要是以文字為內(nèi)容載體,以課堂講授為培訓(xùn)的形式,雖有一定的培訓(xùn)效果,但形式單調(diào),內(nèi)容枯燥,難以激發(fā)學(xué)員的學(xué)習(xí)熱情,培訓(xùn)效果并不理想[2]。在油田企業(yè)的井控培訓(xùn)中,有的使用設(shè)備模擬事故發(fā)生,進(jìn)行井控操作培訓(xùn),但是這種形式成本高、數(shù)量少,受培訓(xùn)時(shí)間和地點(diǎn)限制等,不能廣泛應(yīng)用。
隨著網(wǎng)絡(luò)技術(shù)和教育技術(shù)的發(fā)展,在線培訓(xùn)逐漸成為一種常用的培訓(xùn)方式。在線練習(xí)作為在線培訓(xùn)的一種重要形式,相對于傳統(tǒng)的紙質(zhì)練習(xí)形式,在線練習(xí)系統(tǒng)更加快捷,練習(xí)安排更加省時(shí)省力,并且能夠打破常規(guī)的時(shí)間和地域約束,學(xué)員答題練習(xí)自由、操作簡單。為了提高學(xué)員的學(xué)習(xí)熱情,有的學(xué)習(xí)平臺(tái)引入了PK(Player Killing)對戰(zhàn)練習(xí)模塊,比如常用的“學(xué)習(xí)強(qiáng)國”APP中具有“雙人對戰(zhàn)”和“四人賽”等學(xué)習(xí)模塊[3];祝翔等人[4]研發(fā)的基于WebSocket的PK答題系統(tǒng)也具有PK答題功能。這些PK功能提高了用戶的使用熱情。但是在油田專業(yè)知識(shí)尤其是井控知識(shí)培訓(xùn)領(lǐng)域中未見引入PK對戰(zhàn)模式。
本文借鑒網(wǎng)絡(luò)游戲中的PK對戰(zhàn)思想,把PK對戰(zhàn)學(xué)習(xí)模式融入到井控知識(shí)在線練習(xí)系統(tǒng)中。系統(tǒng)中的在線PK模塊采用共享內(nèi)存形式實(shí)現(xiàn)進(jìn)程間通信,采用的數(shù)據(jù)庫為MySql5.7,因?yàn)樵摪姹緮?shù)據(jù)庫支持EVE定時(shí)任務(wù),方便模擬消息進(jìn)程用戶傳遞和維護(hù)信息。融入了PK對戰(zhàn)模式的井控知識(shí)在線練習(xí)系統(tǒng),結(jié)合積分獎(jiǎng)勵(lì)機(jī)制,能夠極大地提高學(xué)員的熱情,達(dá)到良好的培訓(xùn)效果。
為實(shí)現(xiàn)學(xué)員對井控知識(shí)的練習(xí)不受時(shí)間和空間的限制,本文研發(fā)的系統(tǒng)采用B/S模式,應(yīng)用SSM開發(fā)框架,整體架構(gòu)采用MVC設(shè)計(jì)模式。該系統(tǒng)功能模塊主要包括6個(gè)部分:用戶信息管理、井控資料管理、答題積分管理、題庫管理、個(gè)人在線練習(xí)、PK對戰(zhàn)。系統(tǒng)開發(fā)思想為AOP面向切面開發(fā),Spring為整體控制容器,包括類對象的創(chuàng)建與分配,采用單例模式生成,從而保證線程間數(shù)據(jù)獨(dú)立。
系統(tǒng)在線PK模塊需要模擬2個(gè)用戶的信息交互,即進(jìn)程間通信。進(jìn)程間通信主要包括7種方式:管道、命名管道、消息隊(duì)列、共享內(nèi)存、信號(hào)、信號(hào)量、套接字。井控知識(shí)在線練習(xí)系統(tǒng)主要用到上述中的共享內(nèi)存,即用戶雙方共享數(shù)據(jù)庫中同一個(gè)數(shù)據(jù)塊[5]。
2.1.1 共享內(nèi)存
共享內(nèi)存允許2個(gè)不同的繼承或用戶同時(shí)訪問。不同進(jìn)程之間共享的內(nèi)存通常是相同的物理內(nèi)存段。進(jìn)程可以將相同的物理地址段連接到自己的地址空間,所有進(jìn)程都可以訪問共享內(nèi)存中的地址。如果一個(gè)進(jìn)程將數(shù)據(jù)寫入共享內(nèi)存,所做出的更改會(huì)被其他會(huì)話監(jiān)聽。該方式不提供線程同步相關(guān)支持,即沒有自動(dòng)機(jī)制阻止第二個(gè)進(jìn)程開始讀取共享內(nèi)存,直到第一個(gè)進(jìn)程完成對共享內(nèi)存的寫入操作。因此在后臺(tái)模擬數(shù)據(jù)監(jiān)聽時(shí),所建立的線程必須是用戶間獨(dú)立,每一個(gè)用戶不可以在后臺(tái)直接申請實(shí)例化線程,需要用戶創(chuàng)建匿名線程并綁定在自己的后臺(tái)服務(wù)代碼上[6]。
2.1.2 模擬實(shí)現(xiàn)方式
數(shù)據(jù)庫采用的是MySql5.7版本支持計(jì)劃事物EVE[7]。當(dāng)用戶登錄時(shí)分配唯一綁定的數(shù)據(jù)庫會(huì)話,從Spring-config中的C3P0數(shù)據(jù)庫連接池申請,默認(rèn)單例保持唯一。用戶登錄成功后會(huì)通過JDK1.8版本特性Lambda創(chuàng)建內(nèi)部線程,因?yàn)榫€程匿名存在,會(huì)自動(dòng)綁定用戶獨(dú)立的代碼部分,隨著主類的釋放而釋放,即隨著用戶的退出而釋放。只需要讓線程去監(jiān)聽或修改數(shù)據(jù)庫信息內(nèi)容,就能達(dá)到獲取信息、發(fā)送信息的效果。同時(shí)數(shù)據(jù)庫定時(shí)任務(wù)會(huì)對用戶的狀態(tài)信息做維護(hù),比如用戶登錄狀態(tài)每30秒刷新一次以判斷他人是否在線。
服務(wù)器端共享內(nèi)存解決在線PK問題,Session在其中起到了重要作用。Session變量為服務(wù)器端變量,存在服務(wù)器上,主要形式為Key-Value鍵值對存儲(chǔ)形式,支持Map集合形式可以作為共享內(nèi)存的消息表。Session中Key儲(chǔ)存在服務(wù)器端內(nèi)存上,Value儲(chǔ)存在堆上,服務(wù)器自行管理Session的Key-Map,整體訪問速度較快,自帶時(shí)間參數(shù)方法,一段時(shí)間未被讀寫將被數(shù)據(jù)庫釋放,使用時(shí)要設(shè)置釋放時(shí)間超過整個(gè)在線PK的時(shí)間,釋放后不會(huì)影響后臺(tái)線程的運(yùn)行,這樣就能發(fā)現(xiàn)用戶掛機(jī)狀態(tài),即Session消失但是數(shù)據(jù)庫顯示登錄狀態(tài),此時(shí)用戶回到操作界面需要刷新才能正常使用。
該功能模擬兩個(gè)用戶間通信,采用共享內(nèi)存的方式進(jìn)行交互。首先登錄者都有登錄狀態(tài)信息,其中一個(gè)用戶可以查看其他用戶的狀態(tài)信息,根據(jù)狀態(tài)信息找到PK對象發(fā)出PK請求,即修改對象用戶PK狀態(tài)信息為自己的ID,對方會(huì)看到自己的PK狀態(tài)被改變,此時(shí)對方將給出回復(fù),0代表拒絕,1代表同意。如果同意雙方將進(jìn)入答題界面,如果不同意,請求者會(huì)收到拒絕信息提示。為避免對方用戶長時(shí)間無回應(yīng)造成一直等待,需要加入數(shù)據(jù)信息維護(hù)函數(shù),定時(shí)去改變用戶狀態(tài)信息,如30秒不回復(fù)函數(shù)將自動(dòng)回復(fù)0拒絕。
在線PK過程中,主要實(shí)現(xiàn)方式為共享內(nèi)存,異步刷新同一個(gè)數(shù)據(jù)表來模擬通信。主要處理方法分為兩種:異步刷新(異步線程查詢數(shù)據(jù)庫)、設(shè)置狀態(tài)(修改表內(nèi)狀態(tài)信息)。主要流程分為:查看狀態(tài)(異步刷新)、發(fā)送請求(設(shè)置狀態(tài))、接受請求(異步刷新)、回復(fù)請求(設(shè)置狀態(tài))、接受答復(fù)(異步刷新)。這樣就完成了一個(gè)完整的用戶間會(huì)話。核心模塊在線PK數(shù)據(jù)流如圖1所示。
當(dāng)一方用戶查看到另一方用戶在線時(shí),點(diǎn)擊對方信息后面的“申請對戰(zhàn)”功能按鈕,發(fā)出對戰(zhàn)申請。此時(shí),該用戶會(huì)將目標(biāo)用戶的對戰(zhàn)目標(biāo)(數(shù)據(jù)庫中PK字段)信息設(shè)置為自己的ID,同時(shí)運(yùn)用Ajax開啟異步線程去監(jiān)聽對方答復(fù)(數(shù)據(jù)庫中jieshou字段)。此時(shí)另一個(gè)用戶有Ajax異步開啟的線程監(jiān)聽自己的PK字段,如果PK字段ID發(fā)生改變,就會(huì)向界面彈出會(huì)話“用戶ID為×××的人向您發(fā)出了對戰(zhàn)申請”,如果點(diǎn)擊接收,會(huì)將自己的jieshou字段變?yōu)?,表示接收邀請,此時(shí)雙方會(huì)跳轉(zhuǎn)到答題界面,并且將自己的pking變?yōu)閷Ψ降腎D,表示在答題過程中。如果有第三人上線查看在線用戶,就會(huì)看到正在答題的人并且無法再申請對戰(zhàn),保證PK人數(shù)一直是兩個(gè)人。具體實(shí)現(xiàn)如圖2所示。
對戰(zhàn)申請成功后,進(jìn)入答題界面。在答題過程中,為了防止第三人再次發(fā)出PK請求造成干擾,需要實(shí)時(shí)將用戶狀態(tài)設(shè)置成PK模式,杜絕第三方用戶干擾。因此,在答題界面前端引入Ajax異步,后臺(tái)申請線程實(shí)時(shí)將自己的狀態(tài)信息修改為PK對戰(zhàn)中,同時(shí)數(shù)據(jù)庫建立計(jì)劃事務(wù),每5秒對用戶對戰(zhàn)狀態(tài)進(jìn)行維護(hù),保證為PK狀態(tài)。
答題結(jié)束后,系統(tǒng)將數(shù)據(jù)提交到后臺(tái)。通過計(jì)算得出結(jié)果并且將結(jié)果保存到數(shù)據(jù)庫中,在數(shù)據(jù)庫中有仿照RDS數(shù)據(jù)庫消息隊(duì)列實(shí)現(xiàn)的數(shù)據(jù)表,數(shù)據(jù)表中主要分為3個(gè)部分,即消息、消息發(fā)出者、消息接收者。因?yàn)閷?zhàn)雙方提交答題時(shí)間不同,所以先提交的用戶要等待后提交的答題結(jié)果。對戰(zhàn)雙方的結(jié)果界面還要有異步線程刷新消息隊(duì)列表。當(dāng)后完成提交的用戶提交結(jié)束后,先提交的用戶就能得到相應(yīng)的結(jié)果消息,并且與自己的結(jié)果對比,從而得出最終的PK勝負(fù)。系統(tǒng)考慮到了兩種特殊PK情況,一種情況是其中一個(gè)用戶在PK時(shí)退出系統(tǒng),另一個(gè)用戶就不必等待結(jié)果直接判定勝利;另一種情況是設(shè)置等待結(jié)果的最長時(shí)間為答題的限制時(shí)間10分鐘,其中一方答完提交后,若10分鐘后對方還未答完提交,則判定對方PK失敗。具體實(shí)現(xiàn)結(jié)果如圖3所示。
圖3中10個(gè)按鍵編號(hào)代表對應(yīng)題目的正確情況,紅色代表錯(cuò)誤,綠色代表正確,點(diǎn)擊紅色按鍵就會(huì)顯示對應(yīng)題目的答案,點(diǎn)擊綠色按鍵可以收藏對應(yīng)的題目,同時(shí)錯(cuò)誤的題目也會(huì)自動(dòng)收藏到收藏表中。
在線練習(xí)功能也是本系統(tǒng)最為重要的功能模塊,主要?jiǎng)澐譃?個(gè)子功能,分別為:順序練習(xí)、隨機(jī)練習(xí)、強(qiáng)化練習(xí)3種組題方式,并且每種組題方式都分為計(jì)時(shí)與非計(jì)時(shí)兩種模式。
(1)順序練習(xí):每個(gè)用戶在完整信息子表中都有一個(gè)名為userpath表,它主要記錄的信息為userid、部門題庫、答題數(shù)量。用戶答題前選擇順序答題模式,提交tisum(出題數(shù)量)和wbid(題庫ID),后臺(tái)首先會(huì)根據(jù)getSession獲得自己的ID,再結(jié)合前臺(tái)選擇的題庫ID找到用戶答題數(shù)(tipath)。根據(jù)數(shù)據(jù)庫全部題數(shù)(allsum)、出題數(shù)量以及自己的答題數(shù)目,確定每次順序練習(xí)時(shí)的起始題目和結(jié)束題目。
(2)隨機(jī)練習(xí):用戶提交前臺(tái)答題設(shè)置信息,主要包括題庫ID(bmid)和出題數(shù)量(tisum)等。后臺(tái)接收到隨機(jī)答題請求,首先根據(jù)題庫ID(bmid)查找題庫內(nèi)全部題目數(shù)量,之后創(chuàng)建Set集合,利用Set集合特性(無序不可重復(fù))和隨機(jī)數(shù)范圍0~(題庫最大題目數(shù)量-1)這個(gè)區(qū)間去生成整數(shù)類型隨機(jī)數(shù)并插入Set中,當(dāng)Set長度達(dá)到題數(shù)(tisum)長度后結(jié)束,根據(jù)集合中的隨機(jī)數(shù)到題庫中抽題并將題目集合傳送到前端完成組題工作。
(3)強(qiáng)化練習(xí):每個(gè)用戶在完整的數(shù)據(jù)子表中都有一個(gè)uaiti表,表中記錄了用戶收藏的題目以及答錯(cuò)的題目。主要結(jié)構(gòu)為用戶編號(hào)userid、題目標(biāo)號(hào)tiid、收藏類型over。用戶通過前端向后臺(tái)提交數(shù)據(jù):題庫(wbid)、題數(shù)(tisum)。后臺(tái)會(huì)以多表鏈接查詢的方式從收藏表中采用上述隨機(jī)數(shù)的模式去抽取題目,抽取到的題目跳轉(zhuǎn)到答題界面完成組題。
(4)計(jì)時(shí)與非計(jì)時(shí):用戶在答題界面選擇計(jì)時(shí)與非計(jì)時(shí)兩種模式。若選擇計(jì)時(shí)模式之后會(huì)出現(xiàn)時(shí)間選擇框,系統(tǒng)會(huì)將選擇模式及時(shí)間傳入組題后臺(tái),組題結(jié)束后會(huì)將這些信息一起發(fā)送到答題界面端,答題界面會(huì)根據(jù)該信息做出判斷。如果是計(jì)時(shí)就會(huì)根據(jù)計(jì)時(shí)時(shí)間預(yù)編譯一個(gè)倒計(jì)時(shí)提示,事件結(jié)束后自動(dòng)提交用戶答案。計(jì)時(shí)模式的在線練習(xí)功能模塊如圖4所示。
為激發(fā)培訓(xùn)人員的學(xué)習(xí)熱情,提高油田井控知識(shí)培訓(xùn)效果,本文在設(shè)計(jì)油田井控知識(shí)在線練習(xí)系統(tǒng)時(shí)引入了對戰(zhàn)游戲中的PK對戰(zhàn)模式,開發(fā)實(shí)現(xiàn)了具有PK對戰(zhàn)模式的井控知識(shí)練習(xí)系統(tǒng)。在系統(tǒng)的PK對戰(zhàn)功能中,采用了進(jìn)程間通信、共享內(nèi)存等技術(shù),仿照Redis數(shù)據(jù)庫方法,在MySql中申請本機(jī)事務(wù)權(quán)限,插入計(jì)劃事務(wù),模擬動(dòng)態(tài)數(shù)據(jù)。同時(shí)還用到消息隊(duì)列的思想與Ajax異步處理相結(jié)合實(shí)現(xiàn)消息傳遞與接收。本系統(tǒng)在滿足井控知識(shí)練習(xí)培訓(xùn)需求的基礎(chǔ)上,提高了員工答題練習(xí)的積極性。通過PK對戰(zhàn)的答題形式,使用戶擺脫了枯燥的單機(jī)模式,同時(shí)也能培養(yǎng)競爭意識(shí),營造積極向上的學(xué)習(xí)氛圍。