1

Lua でソケットを実装しています。作業中のコード例では、次の方法を使用して接続を維持しています。

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

ループは明らかに残りのプロジェクト コードの実行を妨げますが、ループを終了すると、ソケット サーバーはすぐに接続が閉じられたことを通知します。

では、Lua コードの残りの部分が通常どおり実行されているときに、同時にソケットを開いたままにしておくにはどうすればよいでしょうか? (ある種のバックグラウンド ジョブ サポートはありますか?この目的でコルーチンを使用できますか?)

4

4 に答える 4

0

あなたが述べたように、Lua Lanes を使用して、ソケット i/o を実行し、バックグラウンドで実行されているスレッドを開始しました。

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

Lua Lanes とソケットの使用に関する情報を提供するこの回答をご覧ください。

LuaLanes と LuaSockets

そこで提供されるデュアルスレッド ポーリング ソリューションはおそらく最も実行可能ですが、コルーチンに関する情報もあります。

于 2013-02-23T23:48:26.133 に答える
0

実際、その目的のためにコルーチンを使用できます。これは、人気のあるライブラリCopasが行うことです。

ユース ケースに応じて、Copas を使用するか、そのソース コードを見て、それがどのように機能するかを確認できます。Copas を使用するlua-websocketsも参照してください。

于 2013-02-25T10:56:20.967 に答える
0

他の答えは素晴らしいですが、ここで最も重要な点を見逃しています:

最近では、ソケットを扱うときにスレッドを使用する必要はほとんどありません

なんで?epoll複数のソケットが非常に一般的であるため、OS (最も顕著なのは *ix システム) は関数の形で「複数のポーリング」を実装しました。

ZeroMQ などの高性能ネットワーク ライブラリはすべて、少数のスレッドのみを保持し、それらの内部で動作します。これにより、メモリ要件が低下しますが、速度は犠牲になりません。

したがって、OS ライブラリに直接接続することをお勧めします。これは、 Luaでは非常に簡単です。自分でコードを書く必要はありません - Google 検索でこの epoll ラッパーが見つかりました[1] その後、コルーチンを使用して、実際にデータを持つソケットからのみ読み取ることができます。

ZeroMQ ライブラリ自体も参照してください。

[1] Neopalliumは ZMQ用の Lua バインディングを作成したので、合法だと思います。

于 2013-02-24T10:23:52.257 に答える
0

(あなたの質問はこの質問に似ています(そして、私は適切に重複としてフラグを立てました)が、便宜上、私の回答のコピーをここに示します!)

この問題を処理するにはさまざまな方法があります。どちらを選択するかは、実行したい作業の量によって異なります。*

ただし、最初に、UDP と TCP のどちらを扱っているかを (自分自身で) 明確にする必要があります。UDP ソケットの「基礎となる TCP スタック」はありません。また、UDP は、テキストや写真などのデータ全体を送信するために使用するプロトコルとしては不適切です。これは信頼性の低いプロトコルであるため、マネージ ソケット ライブラリ ( ENetなど) を使用していない限り、すべてのパケットを受信できる保証はありません。

Lua51/LuaJIT + LuaSocket

ポーリングが唯一の方法です。

  • ブロッキング:socket.select時間引数なしで呼び出し、ソケットが読み取り可能になるまで待機します。
  • ノンブロッキング:socket.selectのタイムアウト引数を指定して呼び出し、読み取り元のソケット0で使用sock:settimeout(0)します。

次に、これらを繰り返し呼び出すだけです。ノンブロッキング バージョンではコルーチン スケジューラを使用することをお勧めします。これにより、プログラムの他の部分があまり遅延することなく実行を継続できるようになります。

Lua51/LuaJIT + LuaSocket + Lua レーン(推奨)

上記の方法と同じですが、Lua Lanes (最新ソース) を使用して作成された別のレーン (別のスレッドの軽量 Lua 状態) にソケットが存在します。これにより、データをソケットからバッファに即座に読み取ることができます。次に、lindaを使用してデータを処理のためにメイン スレッドに送信します。

これはおそらくあなたの問題に対する最良の解決策です。

これの簡単な例を作成しました。こちらから入手できます。これは、Lua Lanes 3.4.0 ( GitHub リポジトリ) と、パッチが適用された LuaSocket 2.0.2 (ソースパッチブログ投稿 re' patch )に依存しています。

結果は有望ですが、このサンプル コードから派生する場合は、間違いなくリファクタリングする必要があります。

LuaJIT + OS 固有のソケット

少しマゾヒスティックな人は、ソケット ライブラリをゼロから実装してみることができます。LuaJITFFI ライブラリは、純粋な Lua からこれを可能にします。Lua Lanes はこれにも役立ちます。

Windows については、 William Adam のブログを参照することをお勧めします。彼は、LuaJIT と Windows の開発に関して非常に興味深い冒険をしてきました。Linux などについては、C のチュートリアルや LuaSocket のソースを見て、LuaJIT FFI 操作に翻訳してください。

(LuaJIT は、API が必要とする場合、コールバックをサポートします。ただし、Lua から C へのポーリングと比較して、パフォーマンス コストが大幅に低下します。)

LuaJIT + ENet

ENetは優れたライブラリです。TCP と UDP の完璧な組み合わせを提供します。また、LuaSocket と同様に、オペレーティング システム固有の詳細を抽象化します。Lua API を使用してバインドするか、LuaJIT の FFI (推奨) 経由で直接アクセスできます。

意図しないしゃれ。

于 2013-02-24T10:12:46.670 に答える