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

我是 LUA 的新手,正在使用 Corona SDK 在 LUA 中编写 tcp 消息库。我遇到了一个问题,即使在协程中运行 socket 读取操作,它仍会挂起应用程序 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?谢谢。

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

点赞
用户1137788
用户1137788

Corona有一个网络请求 API可用于异步调用。

如果你不想使用它,可以看一下这个异步 http 库

2013-01-07 20:56:28
用户501459
用户501459

Corona 包含 LuaSockets,这使得可以进行异步套接字通信,正如这里所展示的那样。

2013-01-07 22:52:43
用户1009342
用户1009342

基于MudSatheeshJM发布的链接,我最终制作了一个消息类,可能对某些人有帮助

--消息原型
Messaging = {sock = nil, sockTimer = nil}

--消息构造函数
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() <- 在大多数情况下,当“timeout”错误出现时,数据将在“rest”变量中,因此我们需要在下面进行检查以了解数据的传输方式
2013-01-08 20:03:48