This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

HELP luasocket changed in build 31
#1
Hi,

Please help.  I have the LM5 running RC1 firmware.  Luasocket is upgraded to luasocket_2.0.2-31_imx6.ipk  it was working in the 29 build.  This particular LM5 is running resident scripts for a websocket client which is working.  I really don't want to break that.

The UDP server does not receive when I have the TCP client active.  I can comment out the TCP client then it works.  The event script can send to the resident script fine.  I have tried changing the timeout value for both TCP client and the UDP server.  Makes no difference.  I need to use copas because I have delay commands sent out to the TCP device.   

Does anyone have an idea.

Resident script on 0 seconds
Code:
if not ready then
  copas = require("copas")
  socket = require("socket")

  server = socket.udp()
  server:setsockname("127.0.0.1",51034)
  function handler(uskt)
    uskt = copas.wrap(uskt)
    log("UDP connection handler")
    while true do
      local s, err
      log("receiving...")
      s, err = uskt:receive(1024)
      if not s then
        log("Receive error: ")
        log(err)
        return
      end
      log("Received data, bytes:")
      log(s)
    end
  end
  copas.addserver(server, handler, 0)
 
  function parse(data)
    log(data)
  end
 
  function sendtcp(command)
    skt:send(command)
    sleep(0.5)   
  end
   
  function init()
    log('in init')
    sendtcp('#COSMSGS=false\r')   
    sendtcp('#MODEL?\r')  
  end
  ready=true
end


if not skt then
  --add receive thread
  copas.addthread(function()
      local reconnect = function()
        skt, err = socket.connect('192.168.0.175', 4999)
        skt:settimeout(1)
        if(not err) then       
          init()
        else
          log('[tcp-client] error connecting ')
          return
        end     
      end
      if not skt or skt==nil or skt.state=='CLOSED' then
        reconnect()
      end
      if(skt)then
        while true do
          local resp,err = skt:receive('*r')
          -- if theres no connection start a new connection
          if(skt.state=='CLOSED')then
            if not resp then
              log("[tcp-client] Receive error: ")
              copas.removethread(skt)
              skt = nil
              break
            end
          else
            if(resp~=nil) then
              local fd,prtd = pcall(parse,resp)
              if(fd==false)then
                log("Error with parsemsg")
              end
            end
          end
        end     
      end
    end) 

end
copas.loop()

Event script
Code:
if event.type=='groupwrite' then
  local socket = require('socket')
  local client = socket.udp()
  local evt = event.dst..','..tostring(grp.getvalue(event.dst))
  log(evt)
  if client then
    client:sendto(evt, '127.0.0.1', 51034)
    client:close()
  end
elseif event.type =='groupread' then
  grp.response(event.dst,grp.getvalue(event.dst))
end
Reply
#2
I'll check this more thoroughly but there are some issues with your script:

1. Do not use socket.connect() because it is blocking, use copas.connect()
2. There's no need to pass any length to UDP receive. Without any length it will return one datagram (or error on timeout) per call
3. Your reconnect procedure seems wrong, you don't have to call removethread and sockets do not have state field
4. sendtcp does not check if socket is connected/available
Reply
#3
Hi,

copas.connect is blocking also. is there a working example with copas?

Thanks

Roger
Reply
#4
From docs:
copas.connect(skt, address, port)
Connects and transforms a master socket to a client just like LuaSocket socket:connect(). The Copas version does not block and allows the multitasking of the other handlers and threads.
Reply
#5
That's what I did  and removed the bad stuff.  Still blocks out.  tried with or without timeout and timeout of 0 and 1.  

Code:
if not skt then
  --add receive thread
  copas.addthread(function()
     skt = socket.tcp()       
       err = copas.connect(skt,'192.168.0.175', 4999)
       skt:settimeout(1)
       log(skt)
       log(err)

      if(skt)then
        init()
        while true do
          local resp,err = skt:receive('*r')
            if(resp~=nil) then
              local fd,prtd = pcall(parse,resp)
              if(fd==false)then
                log("Error with parsemsg")
              end
            end
        end     
      end
    end)
end
Reply
#6
Working example:
Code:
if not ready then
  copas = require('copas')
  socket = require('socket')

  udpserver = socket.udp()
  udpserver:setsockname('127.0.0.1', 51034)

  function udphandler(udpsock)
    udpsock = copas.wrap(udpsock)
    log('udp connection handler')

    while true do
      local data, err = udpsock:receive()
      if data then
        log('received data', data)
      end
    end
  end

  function parse(data)
    log(data)
  end

  function sendtcp(command)
    if connected then
      tcpsock:send(command)
      copas.sleep(0.5)
    end
  end

  ready = true

  function tcpconnect()
    local sock = socket.tcp()

    tcpsock = copas.wrap(sock)
    tcpsock:settimeout(1)

    connected, err = tcpsock:connect('192.168.0.175', 4999)

    if connected then
      log('connect ok')
      sendtcp('#COSMSGS=false\r')
      sendtcp('#MODEL?\r')
    else
      log('connect failed', err)
      copas.sleep(1)
    end
  end

  function tcphandler()
    while true do
      if connected then
        local resp, err = tcpsock:receive('*r')

        if resp then
          local status, data = pcall(parse, resp)
          if not status then
            log('parse failed', data)
          end
        elseif err == 'closed' then
          log('disconnected')

          connected = false
          tcpsock:close()
          tcpsock = nil
          collectgarbage('step')
          copas.sleep(1)
        end
      end

      if not connected then
        tcpconnect()
      end
    end
  end

  copas.addserver(udpserver, udphandler, 0)
  copas.addthread(tcphandler)
end

copas.loop()
Reply
#7
Hi,

Yes it works, BIG thank you. Perfect. Have a great day.

Thanks,

Roger
Reply


Forum Jump: