I have a refresh spinner which looks nice and everything but when the network class starts sends and receive messages it blocks everything. I want to create a feeling that everything is running smoothly, which is doesn’t when the spinner isn’t moving. Can anyone assist me on how to make this a non-blocking network class or guide to some good resources?
local json = require( "json") local util = require("util.util") local \_G = require( "globals" ) module( ..., package.seeall ) local socket = require("socket") function newConnection( params ) params = params or {} if (not params.server or not params.port) then print( "SERVER OR PORT NOT SPECIFIED" ); return a end local self = {} self.buffer = "" self.server = params.server self.port = params.port self.isOpen = false function self:start( params ) self.callback = params.callback self.sock, err = socket.connect( self.server, self.port ) if ( self.sock == nil ) then print( "COULDN'T CONNECT TO SERVER ( self:start ): ", err ) return false; else print( "Connected." ) end self.isOpen = true self.sock:setoption( "tcp-nodelay", true ) -- disable Nagle's algorithm for the connection self.sock:settimeout(0) self.sock:setoption( "keepalive", true ) return true end function self:close() print( "Closing server connection" ) if self.sock then self.sock:close() self.sock = nil self.buffer = "" end end function self:reconnect() if ( not self.callback ) then print( "NO CALLBACK FUNCTION ON RECONNECT ATTEMPT" ) return false end print( "RECONNECTING TO SERVER" ) self:start({ callback = self.callback}) end function self:isActive() if self.sock == nil then return false else return true end end function self:send( msg, delay ) msg.DeviceID = \_G.DeviceID --""-- Needed for push notifications msg = json.encode(msg) msg = string.format("%05d", #msg + 6) .. msg local function send(message) if (self.sock == nil) then print( "SERVER CONNECTION LOST" ) self:reconnect() return false; end local send\_result, err, num\_byes = self.sock:send( message .. "\n") if (send\_result == nil) then print( "ERROR TRYING TO SEND MESSAGE TO SERVER: "..err..' SENT '..num\_byes..' BYTES' ); if ( err == 'closed') then self:reconnect() end return false; else print( "Message sent : "..json.encode( message ).." - "..send\_result ) end return true end if delay == nil or delay == false then timer.performWithDelay(200, function() send( msg) end ) elseif delay == true then send( msg) end end local counter = 10000 local network\_value = 1 -- Try different values to see if the battery consumption goes down function self:enterFrame() if counter \> network\_value then \_G.Connected = self:isActive() local input,output = socket.select( { self.sock }, nil, 0 ) -- this is a way not to block runtime while reading socket. zero timeout does the trick for i,v in ipairs(input) do ------------- local got\_something\_new = false while true do skt, e, p = v:receive(1) if skt then if skt ~= '\0' then self.buffer = self.buffer..skt else got\_something\_new = true self.buffer = "\_\_JSON\_\_START\_\_"..self.buffer.."\_\_JSON\_\_END\_\_" end end if p then if p ~= '\0' then self.buffer = self.buffer..p else got\_something\_new = true self.buffer = "\_\_JSON\_\_START\_\_"..self.buffer.."\_\_JSON\_\_END\_\_" end end if got\_something\_new == true then break end if not skt then break; end if e then print( "ERROR: "..e ); break; end end -- now, checking if a message is present in buffer... while got\_something\_new do -- this is for a case of several messages stocker in the buffer local start = string.find(self.buffer,'\_\_JSON\_\_START\_\_') local finish = string.find(self.buffer,'\_\_JSON\_\_END\_\_') if (start and finish) then -- found a message! local message = string.sub( self.buffer, start+15, finish-1) self.buffer = string.sub( self.buffer, 1, start-1 ) .. string.sub(self.buffer, finish + 13 ) -- cutting our message from buffer self.callback( message ) else self.buffer = "" break end end end counter = 0 else counter = counter + 1 end end Runtime:addEventListener('enterFrame', self) return self end
Best regards,
Tomas