簡體   English   中英

Lua中的持久套接字與其他Lua代碼並行

[英]Persistent socket in Lua in parallel with other Lua code

我正在Lua中實現套接字,我正在使用的示例代碼使用以下方法來保持連接有效:

while true do
  -- handle socket traffic here
  socket.sleep(1)
end

顯然,該循環阻止了其余項目代碼的運行,但是如果退出循環,套接字服務器會立即說連接已關閉。

那么如何在其余Lua代碼正常運行的同時保持套接字同時打開? (是否有某種后台工作支持?協程可以用於此目的嗎?)

如前所述,我使用Lua Lanes啟動了一個線程,該線程正在執行套接字I / O並在后台運行。

http://kotisivu.dnainternet.net/askok/bin/lanes/

看一下這個答案,它給出了有關使用Lua Lanes和套接字的信息。

LuaLanes和LuaSockets

那里提供的雙線程輪詢解決方案可能是最可行的,但是那里也有關於協程的信息。

(您的問題與此問題相似(並且我已將其適當地標記為重復),但這是我的答案的副本,為您提供方便!)

有多種方法可以解決此問題。 您將選擇哪一項取決於您要完成多少工作。 *

但是首先,您應該(自己)弄清楚要處理的是UDP還是TCP。 UDP套接字沒有“底層TCP堆棧”。 同樣,UDP是錯誤的協議,用於發送諸如文本或照片之類的整個數據。 這是一個不可靠的協議,因此除非您使用的是托管套接字庫(例如ENet ),否則不能保證會收到每個數據包。

Lua51 / LuaJIT + LuaSocket

輪詢是唯一的方法。

  • 阻塞: socket.select帶任何時間參數調用socket.select並等待套接字可讀。
  • 非阻塞:使用超時參數0調用socket.select ,並在要讀取的套接字上使用sock:settimeout(0)

然后,只需反復調用這些即可。 我建議為非阻塞版本使用協程調度程序 ,以允許程序的其他部分繼續執行而不會引起太多延遲。

Lua51 / LuaJIT + LuaSocket + Lua Lanes (推薦)

與上述方法相同,但是套接字存在於使用Lua Lanes最新資源 )創建的另一個Lane(另一個線程中的輕量級Lua狀態)中。 這使您可以立即從套接字讀取數據並將其讀入緩沖區。 然后,使用linda將數據發送到主線程進行處理。

這可能是解決您問題的最佳方法。

我已經做了一個簡單的例子,可以在這里找到 它依賴於Lua Lanes 3.4.0( GitHub repo )和一個修補的LuaSocket 2.0.2( 補丁博客文章 re'patch)

結果是有希望的,盡管如果從中衍生出示例代碼,則絕對應該重構它。

LuaJIT +特定於操作系統的套接字

如果您有點受虐狂,則可以嘗試從頭開始實現套接字庫。 LuaJITFFI庫使純Lua成為可能。 Lua Lanes也將對此有用。

對於Windows,我建議看看William Adam的博客 他在LuaJIT和Windows開發方面經歷了一些非常有趣的冒險。 至於Linux及其它其余部分,請查看C教程或LuaSocket的源代碼,並將其轉換為LuaJIT FFI操作。

(如果API要求,LuaJIT支持回調 ;但是,與從Lua到C的輪詢相比,性能開銷很大。)

LuaJIT + ENet

ENet是一個很棒的圖書館。 它在TCP和UDP之間提供了完美的結合:需要時可靠,否則不可靠。 它還像LuaSocket一樣抽象了特定於操作系統的詳細信息。 您可以使用Lua API進行綁定,也可以通過LuaJIT的FFI直接訪問它(推薦)。

*雙關是無意的。

其他答案很好,但是有點錯過了這里最重要的一點:

如今在處理套接字時幾乎不需要使用線程

為什么? 由於多個套接字非常普遍,因此操作系統(最著名的是* ix系統)以epoll函數的形式實現了“多次輪詢”。

所有高性能網絡庫(例如ZeroMQ)僅保留幾個線程,並在其中運行。 這樣可以降低內存需求,但不會犧牲速度。

因此,我的建議是直接連接到OS庫,這在Lua中非常容易。 您不必自己編寫代碼-谷歌快速搜索為我帶來了這個epoll包裝器 [1],您仍然可以使用協程僅從實際有一些數據的套接字中讀取。

您可能還想看看ZeroMQ庫本身

[1] NeopalliumZMQ創建了Lua綁定,因此我認為這是合法的。

您確實可以為此目的使用協程。 這就是流行的Copas庫的功能。

根據您的用例,您可以使用Copas或查看其源代碼以了解其功能。 您可能還會看到使用Copas的lua-websockets

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM