Interest in a Networking Sockets Workaround
-
Hey all,
I just got a networking socket workaround in prototype state. I have an external C++ program open a namedPipe and have sketchups ruby API open it as a normal file.So I have a workable method for passing data back and forth. I was planning on using it strictly for my own goals meaning I don't need generic socket control...but if people are interested enough I would be willing to put work into a SIMPLE generic socket interface and of course I would open source the C++ bridge.
--Interaction and details are below--
IE.
C++ program opens namedPipe "\.\pipe\networkBridge" and waits for commands.
Sketchup Ruby API opens file "\.\pipe\networkBridge" and sends commandsCommands are something like:
TCPOpen SOCKET_ID 192.168.1.27 8000
TCPSend SOCKET_ID DATADATADATA
UDPSend 192.168.1.27 9000 DATADATADATAThe Bridge will automatically write any information from the sockets to the named pipe and the Ruby program must suck it in like drinking from a firehose. There will be a format for incoming data so the ruby program can tell what event happened on which socket.
Something like:
SOCKET_ID EVT_ID EVENT_DATA -
Hello RabidCicada,
I'm very interested on your work. I'd tried to directly write a Socket inside SU with the SKSocket but this (non offical) Sketchup class is not fully fonctional. It was (for me) the only way to fire events from outside Sketchup (with a SKSocket_listener).
But with your C++ Bridge I understand that you can send data to Sketchup from your pipe. I there a pool on incoming datas or is-it like handled events ?
-
It would be event driven. You'll have to set up your own structure on your side for mapping the socket_id to whatever handler you want to handle it.
On the sketchup side you would sit in an infinite loop reading from the named_pipe_file and then parse and handle everything that comes through.
Given the example I provided above of it you would have to read in then parse SOCKET_ID EVT_ID DATADATADATA.
I'll work on it some more in the coming couple weeks. It's not that difficult at all...I just don't have lots of time.
-
Just wanted to note my interest in this effort. I'd love to have a reliable way to send and receive data on sockets.
However, I'm curious why you're writing the server in C++. Is there some reason why it couldn't be written in Ruby?
-
@rabidcicada said:
On the sketchup side you would sit in an infinite loop reading from the named_pipe_file and then parse and handle everything that comes through.
you will have a lot of fun with Sketchup stucked in an infinite loop. or you can use the existing Sketchup Bridge that I made in 2006.
-
Wow....I forgot all about this.
I'll check out your bridge. Looks like you probably tooka the same route I did. I had a successfulbridge built for quite some time....just never finished flushing out the command set.
The client of the bridge wont have a problem sitting in an infinite loop. I handle that in the bridge.....and last I checked the google API supported threads...so that wouldn't be an issue.
Any other concerns to be aware of TBD?
-
the client bridge, the one that runs inside Sketchup in ruby code must return quickly otherwise Sketchup UI will freeze in "white death" as it is mono thread
-
For the Sketchup side you'll need a message queue and an Observer.
Here's a preliminary example that seems to work.
It uses an AttributeDictionary as the queue, and an EntityObserver (since that's the superclass of the AttributeDictionary class.)ISSUES:
(1) This approach will likely need an AppObserver and ModelObserver as well, to be sure that the 'SocketQueue' dictionary is removed from the model before saving, and when Sketchup closes.
(2) May need modifiction to work on Mac with mutilple models open.
-
A word about the queue keys.
They will need to be unique and/or oridinal. Perhaps a timestamp string?
-
Thanks guys. I appreciate the help you are willing to give:).
My motivation for doing this network bridge was because I wanted to pursue a larger project that required network comms.I just recently became interested in actually doing that original project again so I think I will pick this up and run with it
-
@richmorin said:
Just wanted to note my interest in this effort. I'd love to have a reliable way to send and receive data on sockets.
However, I'm curious why you're writing the server in C++. Is there some reason why it couldn't be written in Ruby?
Sorry I never answered this. I believe you've probably figured it out by now but Sketchup doesn't support sockets. Not in an official sense and not very well even in the hacked up unofficial sense:)...or at least...last time I looked (long time ago)
-
Strange that for all the interest, noone at all took a look at the code example in my previous post.
-
Hey Dan,
Tried to load it up...Don't know how to get it to work.Running latest free Sketchup version and installed RDE etc. I think I execute the script correctly via your isntructions (copied all files into plugin dir, start sketch, start RDE, register Script, run code)but nothing valueable happens. I hit "run" after I type Sketchup.version into RDE....nothing useful, just error. Could use a little help if you really are up for getting your Ruby Bridge out there.
I'm using Sketchup 8 on Windows 7.
Your example ruby code for the Dictspy.rb doesn't do any good without the bridge part.
My Bridge was specifically networking...but if you get the whole shebang then I can just build ontop. Failing any further input from you I can keep working on my own interface which would be just the networking sockets.
-
It seems that Sketchup is running the bridge_load script as I can get UI.messagebox statements that I put into it.
I even get the "SketchUp Bridge already started", if I force RDE to run the macro via Macro->SUB. So it seems like something is getting executed.
But when I go to use Sketchup.version in RDE I get C:/Users/RABIDC~1/AppData/Local/Temp/rb4126.tmp:1:in `<main>': uninitialized constant Object::Sketchup (NameError)
Which makes me think it's not being recognized.I know I could have all sorts of configuration problems so let me know what you think. Ruby 192, windows 7, Sketchup 8.
-
@rabidcicada said:
Hey Dan,
Your example ruby code for the Dictspy.rb doesn't do any good without the bridge part.Of course not! (I was showing what needs to be done on the Ruby-side.)
YOUR bridge needs to write "transactions" (which will be attributes consisting of a key [a unique timestamp is fine,] and a value which would be your data [as described in the first post,]) to the attribute dictionary of a special name.
I chose the dictionary name 'SocketQueue' for the example.
On the C++ side, you'll need to get the handle to the current model, and write your messages to the attribute dictionary named 'SocketQueue', using it's set_attribute() method.
You don't have a choice. The only way to have Sketchup perform an event-driven task, (because Sketchup "owns" the event loop,) is to use one of the Ruby API's observer classes that reacts to changes in a list-like object. The only candidate is the the AttributeDictionary class for the queue (which is a subclass of Entity,) and a custom EntityObserver subclass.
Then to process messages you (or whomever uses the bridge,) needs to replace the comment:
# This is where the message processing conditional statement goes.
(within the process_message method,) with some kind of conditional statement block(s) (if or case, etc.) that processes the messages.In practice it may be easier if coders create a subclass of the DictSpy, and override the process_message() method. The name DictSpy could be changed to QueueSpy, SocketQueueSpy, etc. whatever you wish.
You can get fancy and add a module method that dettachs the observer to stop processing, and another to attach it again. Perhap some queue methods to clear the queue, etc.
-
@rabidcicada said:
I know I could have all sorts of configuration problems so let me know what you think. Ruby 192, windows 7, Sketchup 8.
Sketchup 8 loads Ruby v1.8.6-p287
Sketchup cannot load Ruby in the 1.9.x branch (as far as I know, unless you found some trick?)RDE could be the problem... try testing your code using Alex's WebConsole/Editor.
-
RabidCicada how do you run the code in RDE ? from that error it looks that you dont use sub.exe to send the code from RDE to SketchUp via SketchUp Bridge
-
Thanks for the responses.
I am SEVERELY unfamiliar with hacking up sketchup...FYI.
Question:
Does Sketchup have it's own local copy of Ruby 1.8.6 etc? Or are you saying that I must use that version if I am to successfuly drive sketchup externally?I run code through RDE by simply typing it into the main editing window and then selecting "run" from the menu. Is that not the right way?
I've already registered the SUB script with RDE.
I may not be "executing" ruby code the right way. I start Sketchup with the scripts and exe in the plugins directory. I believe bridge_load.rb runs because I get a messagebox notification I put in there on purpose (for the success case). Then I start RDE. I run SUB script via toolbar->macro->SUB (I get the error about only one instance being allowed). Then I type some code into the normal box in RDE. Then I hit "run" and I get the error.Am I supposed to do things differently?
I would appreciate if you laid out an exact step by step example to successfully execute a "Hello World" in a messagebox from the RDE interface.
-
Should I separately install Ruby 1.8.6?
-
Thanks for the pointer to Alexs stuff...I'll play with that also.
Advertisement