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