Socket Server in QC plug-in (Xcode)

williamcotton's picture

Hey guys,

So, I'm working on my first custom QC plug-in, and I'm reading in the docs that:

"The custom patch does not require a run loop to be present and running. (If you need a run loop, then you must set up the run loop on a secondary thread and communicate with it.)"

I'm wondering if anyone has any experience with this sort of thing and could give me some pointers before I start getting too deep in to it.

I'm guessing I need to fire up NSThread and use DistributedObjects to communicate between the main thread and the thread with the socket server running on it.

Basic overview:

A QC plug-in listening on a port and accepting incoming connections. Each connection will send real-time values to the QC patch, and the QC patch will output a Structure of all the connections and their associated values.

BTW, I'm using the CocoaAsyncSocket library for the networking, as it's very straight-forward and keeps me from having CFNetwork related nightmares.

Did any of the Kineme plug-ins require the use of NSThread?

William

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

cwright's picture
Re: Socket Server in QC plug-in (Xcode)

Don't use DO for intra-app communication -- there's a ton of overhead, and a few caveats when you're using DO. Just used shared resources, and proper locking, and you'll be fine between threads. (DO's mainly for inter-app communication)

If possible, you could drop down to the basic POSIX socket stuff (bind(), accept(), etc) -- it's tedious, but pretty simple.

Many many many plugins/apps of ours use NSThread. it's a pretty simple, straightforward class.

williamcotton's picture
Re: Socket Server in QC plug-in (Xcode)

Thanks for the heads up!

I'll give it a shot and let y'all know how it turns out!

William

williamcotton's picture
Re: Socket Server in QC plug-in (Xcode)

So, I'm using NSThread, and all is well... my little wrapper class for AsyncSocket is working out, and the server is up and running when the plugin is in a QC composition... I can tell because I can telnet in to it.

However, the delegate callbacks for AsyncSocket aren't working at all... I've got it working in single thread situations on both the desktop as well as the iPhone, so I sort of know my way around the library.

Here's my code: http://pastie.org/526628

Thread communication in Cocoa is just plain new to me. The thread pertinent code is in RBYQuartzComposerPatchPlugIn.m, ~lines 89 - 104.

Also, the call to NSLog(@"Server is up and running") in TCPSocketServer.m on line 61 shows up in the logs, so I know it's getting that far... it's just that none of the delegate methods, like didAcceptNewSocket: are ever called.

I know this is a 3rd party library, but I'm just wondering if you can see any blatant mistakes that I'm making when it comes to running something inside of a thread.

BTW, if you're looking for a nice little socket library, check it out: http://code.google.com/p/cocoaasyncsocket/

cwright's picture
Re: Socket Server in QC plug-in (Xcode)

Looks like you need a runloop -- I think your server thread is ending, as well, but I don't know (I've never used that framework before).

Honestly, runloops and server objects are really overkill -- curl up with a posix networking book for an evening, do a server the right way, and manage it from there.

williamcotton's picture
Re: Socket Server in QC plug-in (Xcode)

Well, I got it all up and running! There's still a few little gotchas, but its working as intended, at least for version 0.1.

Thanks for your suggestions!

cwright's picture
Re: Socket Server in QC plug-in (Xcode)

sweet, glad you're up and running :)

Out of curiosity, what does your plugin do?

ginsu777's picture
Re: Socket Server in QC plug-in (Xcode)

I am interested in your plugin as well. I was using a device that was on serial so I used the serial plugins, and it worked. however, I want to get data from a new device which is USB and I can listen to the data (XML output) through the terminal -- it works fine.

Now i have to change the Serial version of the QC composition and turn it into one that can take data from an IP port driven by the USB device -- the company makes an app (quarqd) that is used to interface with the device, and so its all cool. I think I can then plug it into my string truncate and get the same data out the other end (its xml).

I want to automatically open 2 terminals in my QC composition an ultimately APP and start up the listening program in one, and then listen to the port using something else. As I said, it all works with the serial device, but can your plugin be the thing to make this work with the usb device?

Here's the commands, and what the data looks like (after the program is running in the first terminal, I type this in the second terminal):

nc localhost 8168
X-set-channel: 0h
 
<<data stream is XML and looks like this>>
<HeartRate id='8655h' timestamp='1278200656.36' BPM='76' />
<HeartRate id='8655h' timestamp='1278200656.60' BPM='76' />
<HeartRate id='8655h' timestamp='1278200656.85' BPM='76' />
<HeartRate id='8655h' timestamp='1278200657.09' BPM='76' />
[blockcode]
 
  About XML messages:
        <$xml_message id=$ID time=$TIME $xml_message_dataname=$value 
             [$xml_message_dataname=$value [...]] />