1

I need a program that can create pre-defined shapes on screen according to that commands I send to it via TCP. I'm trying to listen to a port and so that I can use them. Before waiting of a command (via network) I have the commands required to create a square (I plan to change its attributes via network commands)

The problem is it is not creating any graphics or opening the window as it should be..

require "socket"
require "mime"
require "ltn12"

host = "localhost"
port = "8080"
server, error = socket.bind(host, port)
if not server then print("server: " .. tostring(error)) os.exit() end


screen=MOAISim.openWindow ( "test", 640, 640 )

viewport = MOAIViewport.new (screen)
viewport:setSize ( 640, 640 )
viewport:setScale ( 640, 640 )

layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
MOAISim.pushRenderPass ( layer )

function fillSquare (x,y,radius,red,green,blue)
a = red/255
b = green/255
c = blue/255
MOAIGfxDevice.setPenColor ( a, b, c) -- green
MOAIGfxDevice.setPenWidth ( 2 )
MOAIDraw.fillCircle ( x, y, radius, 4 ) -- x,y,r,steps
end
function onDraw (  )

fillSquare(0,64,64, 0,0,255)
end

scriptDeck = MOAIScriptDeck.new ()
scriptDeck:setRect ( -64, -64, 64, 64 )
scriptDeck:setDrawCallback (    onDraw)


prop = MOAIProp2D.new ()
prop:setDeck ( scriptDeck )
layer:insertProp ( prop )


while 1 do
   print("server: waiting for client command...")
   control = server:accept()
    command, error = control:receive()
    print(command,error)
    error = control:send("hi from Moai\n")

end

It is waiting of the command from client at control = server:accept() but it is not opening up the graphics window as it should.. Is there any command to force it to open or render

Thank you

Charles
  • 50,943
  • 13
  • 104
  • 142
Ansel Zandegran
  • 636
  • 8
  • 18

3 Answers3

2

MOAI doesn't run your scripts in a separate thread. A blocking call (server:accept) or forever loop (while true do) will block your MOAI app and it will appear to freeze while it merrily sits in your script forever.

So you have to do two things:

  1. Use non-blocking calls. In this case, you need to set your server's timeout to 0. That makes server:accept return immediately. Check it's return value to see if you got a connection.
  2. Put your while loop in a coroutine and yield once per iteration.

You'll need to handle the client the same way, using non-blocking calls in a coroutine loop.

function clientProc(client)
  print('client connected:', client)

  client:settimeout(0) -- make client socket reads non-blocking

  while true do
    local command, err = client:receive('*l')
    if command then 
      print('received command:', command) 
      err = client:send("hi from Moai\n")
    elseif err == 'closed' then
      print('client disconnected:', client)
      break
    elseif err ~= 'timeout' then
      print('error: ', err)
      break
    end
    coroutine.yield()
  end
  client:close()
end

function serverProc()
    print("server: waiting for client connections...")

    server:settimeout(0) -- make server:accept call non-blocking

    while true do
        local client = server:accept()
        if client then
            MOAICoroutine.new():run(clientProc, client)
        end
        coroutine.yield()
    end
end

MOAICoroutine.new():run(serverProc)
Mud
  • 28,277
  • 11
  • 59
  • 92
0

Set the timeout for the server socket, since the accept is a blocking call.

server:settimeout(1)
Pavan K
  • 4,085
  • 8
  • 41
  • 72
0

Thanks Mud...I found that before u replied so the following coroutine works

function threadFunc()
    local action
    while 1 do

    stat, control = server:accept()
    --print(control,stat)
    while 1 do
        if stat then
            command, error = stat:receive()
            print("Comm: ", command, error)
            if command then

                stat:close()
                print("server: closing connection...")
                break
            else
                break
            end
            --[[
          error = stat:send("hi")
          if error then
              stat:close()
              print("server: closing connection...",error)
              break
          end  ]] --
        else
            break
        end

    end
    coroutine.yield()
end
end

That was very helpful though

Ansel Zandegran
  • 636
  • 8
  • 18