如何在Corona SDK Lua中运行阻塞操作?

时间:2013-01-07 20:02:25

标签: sockets asynchronous tcp lua coroutine

我是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的情况下从套接字读取?例如,使用真正的线程或异步方法?感谢。

P.S。消除BUFSIZ不是选项,因为我根本不想阻止UI,即使是0.2..0.4秒(移动网络延迟缓慢)

3 个答案:

答案 0 :(得分:2)

Corona contains LuaSockets将允许您进行异步套接字通信,如here所示。

答案 1 :(得分:1)

Corona有一个network.request API用于异步调用..

如果您不想使用它,请查看this asynchronous http library

答案 2 :(得分:0)

根据 Mud SatheeshJM 发布的链接,我最终制作了一个可能对某人有帮助的短信课程

-- 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. 本地数据,状态,rest = self.sock:receive()&lt; - 在大多数数据库中,数据将在&#34; rest&#34;变量&#34;超时&#34;出现错误,这就是为什么我们需要在下面检查以了解数据的确切传输方式