UDP Socket and Threading in API
-
Hey,
I'm trying to integrate a new self developed input device into SU. The device is connected over RS232 and data is processed through an C# application.
Now I tried to send the data over UDP to SU. This is my Ruby Plugin code for testing:require 'socket' server = Thread.new { $port = 3157 $maxSize = 100 serverSocket = UDPSocket.new serverSocket.bind("127.0.0.1", $port) UI.messagebox("Socket open!") loop { data = serverSocket.recvfrom($maxSize) if data.length != 0 UI.messagebox(data) end } }
If I send a UDP message to this socket, i don't get a message from SU but Windows shows me, that the socket is open.
Could anybody tell me why this is not working? Thank you!Greetings,
Patrick -
Probably because we are running embedded Ruby as a subprocess of Sketchup's process... (unlike when you run Ruby in it's own process from the command shell.)
The Sketchup application "owns" the main event loop, and controls when Ruby code actaully executes. So you need to follow the Sketchup API "rules".
Also.. Threads in Ruby 1.8.x branch do not work well in an embedded Ruby evironment.
But there is a special Sketchup API "thread-like" block method that can give you a polling type mechanism.
timer_id = UI.start_timer(delay,repeat) { #block of code }
see API doc:
UI.start_timer
and:
UI.stop_timer -
As Dan pointed out UI.start_timer works pretty good with UDP. Here's how I'd write it:
require 'socket' serverSocket = UDPSocket.new serverSocket.bind("127.0.0.1", 3157) timer_id = UI.start_timer(0.1, true) { begin data = socket.recvfrom_nonblock(100) new_message = true rescue Errno;;EWOULDBLOCK new_message = false rescue Errno;;ECONNRESET new_message = false UI.stop_timer @timer_id break end if new_message == true UI.messagebox(data) end }
The major different is the UI.start_timer in place of the "Thread" and "Loop" in your example. You'll also see that it uses .recvfrom_nonblock with some error catching instead of just .recvfrom. This is because sketchup will hang if nothing is sent to the socket. If you're sure that there will be a constant stream of data you might be able to get it to work with blocking.
Advertisement