使用WebSocket與具名管道支援遠端輸入輸出

2022-03-13 16:22:42 字數 2325 閱讀 5597

在專案的beta階段,我們團隊提出了乙個新的內容,就是要為每個使用者提供乙個真正的開啟即用的簡易開發環境。為了真正實現快捷這一亮點,我決定在這個功能的實現上不再使用docker容器技術,從而免去了專案啟動的時間開銷,由此可以大大減少白屏時間。

而面臨的乙個問題就是輸入輸出問題,在alpha階段,我們專案的輸入輸出是依賴於每個專案對應的容器的真實終端來實現的,而現在沒有了docker技術,首要解決的就是輸入輸出問題。

考慮到使用者的輸入和輸出是完全非同步的,我第一時間想到了websocket技術。

websocket技術作為http技術的補充被提出,主要解決了http協議中服務端不能主動向客戶端傳送資料的問題。正如其名,該技術就像是web應用中的socket技術,支援客戶端和服務端的全雙工通訊。

在這個專案中,因為輸出輸入都是非同步的,客戶端隨時可能傳送輸入資料到伺服器,伺服器也隨時可能返回執行輸出到客戶端,所以採用這個技術十分合適。

下面首先說一下websocketsession相關的內容

websocketsession

類似http技術中的session,websocketsession代表了乙個客戶端和服務端之間的連線會話,websocket採用長連線技術,所以客戶端在獲取了websocket物件後,可以長時間使用該物件和服務端進行資料的收發,相應的,在服務端也會有乙個相應的websocketsession物件用於資料的讀取和傳送。

在這個專案中,採用了乙個執行緒處理乙個websocketsession的處理方式,通過執行緒池技術來實現執行緒的復用,提高資源的利用率

public class task implement runnable 

@override

pubilc void run()

}

通過這樣的方式,實時將從管道中讀取的新資料通過websocketsession傳送回客戶端。

而輸入的處理則需要在handler中完成,而這就涉及websocket的四種事件

websocket的四種事件

在上述事件發生時,websocket協議規定會傳送相應的訊息使得連線雙方都得知該事件

由此,可以利用onmessage事件,在收到客戶端發來的新輸入時,將該輸入重定向到輸入管道中,從而使得執行的**可以讀取到相應的內容。

相應的,在收到onclose事件時,可以進行一系列的資源**,如執行緒的中斷、檔案的刪除、**執行程序的銷毀等。

接下來就是考慮如何將使用者的輸入重定向到程式,再將程式執行的輸出重定向到網路的輸出。

我知道linux下有管道,於是寫了這樣一段**

# main.py

a = input()

print(a)

echo 1 | python main.py

發現是可以正常輸出的,這也驗證了我的想法。

但是緊接著另乙個問題出現了,使用者的輸入不是一次性的,因此不能像上面那樣一口氣將輸入內容送入程式

通過網上搜尋,了解到還有具名管道,平時使用的|是臨時管道,而與之相對應的有具名管道,它會以乙個檔案的形式存在,可以復用。

mkfifo input.pipe

python main.py < input.pipe

# can write to input.pipe much times

相應的,輸出也可以使用具名管道,使得伺服器可以持續從輸出管道中獲得程式執行的輸出內容。

mkfifo input.pipe

mkfifo output.pipe

python main.py < input.py > output.py

# can write to input.pipe much times

# can read from output.pipe much times

這是主體的實現思路,下面介紹具名管道使用的一些細節

具名管道的eof產生機制

對於乙個具名管道,當沒有任何寫入者時,從該管道中可以讀取到eof

因此,在這個專案的應用場景中,顯然不能每次收到乙個輸入,就開啟乙個writer,寫入後就關閉,因為這樣會導致管道輸入端沒有寫入程式,從而產生eof,使得應用程式的讀取提前終止,產生錯誤。

解決的辦法也十分簡單暴力,可以使用乙個writer一直作為管道的輸入端,保證管道不會產生eof,當程式執行完成或是使用者主動終止程式時,再關閉該writer即可

具名管道的生命週期

乙個具名管道分別有輸入端和輸出端,整個管道的宣告週期如下

至此,通過websocket技術和具名管道技術,就很好地解決了非同步輸入輸出問題,使得軟體的白屏時間大大減少。

WebSocket理解與使用

概念 websocket 是 html5 開始提供的一種在單個 tcp 連線上進行全雙工通訊的協議。特點 websocket 使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在 websocket api 中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續...

具名插槽的簡單使用

插槽是給元件預留的空間,當封裝元件時往往會給元件使用插槽,插槽如何使用由父元件決定,插槽中的內容表示如果沒有在該元件中插入其他任何內容,就預設顯示插槽中的內容。具名插槽則是當子元件需要顯示不同的效果時使用具名插槽,通過name屬性給插槽命名。案例如下 上圖中在子元件的模板中定義了三個具名插槽,分別為...

Slot 具名插槽的使用

在我們使用插槽的時候,可能裡面會有多個插槽,這個時候也可以定義多個插槽 比如在元件中定義三個插槽,而我只想把標題放在中間,只呼叫中間的插槽的話該怎麼辦。有的人可能會說直接引用不就好了,這種肯定不行,這樣三個都替換掉了。如下右邊的三個就可以看出來,要換的話就全部換掉了,達不到想要的結果 當我們想替換其...