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 不是选项,因为我根本不想阻止 UI,即使是 0.2..0.4 秒(移动网络延迟慢)

4

3 回答 3

2

Corona 包含 LuaSockets,它可以让您进行异步套接字通信,如此处所示

于 2013-01-07T22:52:43.523 回答
1

Corona 有一个用于异步调用的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 回答