3

LUA は初めてで、Corona SDK を使用して LUA で tcp メッセージング ライブラリを作成しています。コルーチンで実行されている場合でも、ソケット読み取り操作がアプリケーション UI をハングさせるという問題がありました。

コルーチンの開始方法:

function Messaging:readLoop()
   self.readCoroutine = coroutine.create(function() self:blockingLoop() end)
   coroutine.resume(self.readCoroutine)
end

ブロッキング ループ:

function Messaging:blockingLoop()
   line,err,rest = self.sock:receive(BUFSIZE) -- <= Hangs UI if there is no incoming data 
end

もちろん、コルーチンがスレッドと同等ではないことは知っていますが、LUA インタープリターがブロッキング操作で別のコルーチンに切り替わることを期待していました (GIL を使用した Python スレッドのように)。UIをブロックせずにソケットから読み取る可能性はありますか? たとえば、実際のスレッド化または非同期アプローチでは? ありがとう。

PS BUFSIZ を排除することはオプションではありません。0.2..0.4 秒でも UI をまったくブロックしたくないからです (モバイル ネットワークの遅延が遅い)。

4

3 に答える 3

2

Corona には、非同期ソケット通信を可能にするLuaSockets が含まれています

于 2013-01-07T22:52:43.523 に答える
1

コロナには、非同期呼び出し用のnetwork.request API があります。

それを使用したくない場合は、この非同期 http ライブラリをご覧ください。

于 2013-01-07T20:56:28.007 に答える
0

MudSatheeshJMによって投稿されたリンクに基づいて、誰かに役立つ可能性のあるメッセージング クラスを最終的に作成しました。

-- Messaging prototype
Messaging = {sock = nil, sockTimer = nil}

-- Messaging constructor
function Messaging:new (o)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   return o
end

function Messaging:connect()
   self.sock = socket.tcp()
   print( self.sock:connect(HOST, PORT) )
   self.sock:settimeout(0)
   self.sockTimer = timer.performWithDelay(50, function() self:checkData() end, 0)
end

function Messaging:close()
   timer.cancel(self.sockTimer)
   self.sock:close()
end

function Messaging:checkData()
   local data, status, rest = self.sock:receive()
   local s
   if data then
      s = data
   else
      s = rest
   end
   if s:len() ~= 0 then
      print ('received', s)
   end
end

重要事項:

  1. self.sock:settimeout(0)は、ソケットを非ブロックにするために必要です
  2. local data, status, rest = self.sock:receive() <- ほとんどの場合、「タイムアウト」エラーが発生すると、データは「rest」変数に格納されます。そのため、データがどのように正確に転送されたかを知るために、以下のチェックが必要です。
于 2013-01-08T20:03:48.850 に答える