• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
1

Communication between a LR plugin and an iOS app over a LAN

Explorer ,
Jul 14, 2017 Jul 14, 2017

Copy link to clipboard

Copied

I want to create a plugin for Lightroom 6+ (this is new to me) that allows two way communication to take place between LR and an iOS app. The iOS device would be on the same local network.

What is the best method of accomplishing this? I was thinking about using LRSocket, this is the most direct method? I assume with this method the iOS app would need to act as the server and the LR plugin would be the connecting client? But, all the documentation and examples I’ve found, regarding general LRSocket usage, imply that localhost is used. This would make communication with an iOS device over WiFi impossible?

TOPICS
SDK

Views

1.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 14, 2017 Jul 14, 2017

Copy link to clipboard

Copied

You could try running a proxy that forwards the connection from LR to the remote device. It's been a couple of decades since I worked with network proxies, but I recall there used to be simple proxies available.   Perhaps someone knows more about what's currently available, but Google may be your friend here. Or you write your own proxy: Your plugin starts the proxy, connects to it with LrSocket, the proxy then connects to the iOS device (or vice versa).

You could use HTTP from the device to LR, using polling with long-running GETs to send information back to the device.  Or you could use HTTP from LR to the device.  Or you could use HTTP in both directions.   See this post (which was written before LrSocket was released) for more detaIls about that: Re: How to send lightroom data to arduino?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 14, 2017 Jul 14, 2017

Copy link to clipboard

Copied

I feel like dealing with a proxy could be more of a hassle than it is worth.

I might look at HTTP Long Polling but it wouldn't be my first choice.

I'm now leaning toward using a tiny standalone app on the computer w/LR installed that acts as the server. The app can communicate over the LAN with the server app and the server app and LR plugin can communicate via localhost.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jul 20, 2017 Jul 20, 2017

Copy link to clipboard

Copied

I'm working on a shortcut app that communicates with Lightroom using both http & LrSockets. The app catches shortcut keypresses and passes Lua code to a Lightroom plugin that runs the code and sends back data. The app also runs a web server that serves up pages that can send and receive code & data back and forth to Lightroom. I'm using LrSockets to send Lua code to Lightroom and to receive data back from the keypresses and http post in Lightroom to talk to the webserver. Both work equally well both from localhost or from another device.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 20, 2017 Jul 20, 2017

Copy link to clipboard

Copied

Is the app running locally on the same computer? I wasn't able to find any information about setting up a socket connection with LRSocket without using localhost. Right now I have a small app on the computer acting as the go-between for Lightroom and the iOS app.

iOS App <- IP -> Mac App <- localhost -> Plugin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jul 20, 2017 Jul 20, 2017

Copy link to clipboard

Copied

Sorry, yes, you're right; I haven't looked at this in a while. The app runs on localhost.  I'm using LrSocket to talk between LR and the app on hotkey presses but it also runs a web server  and a websocket server which are used to communicate from a browser, or whatever, on remote machines. Websocket because it's faster if you need to stream data.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 22, 2017 Jul 22, 2017

Copy link to clipboard

Copied

I'm having another related problem that you might be able to help with...

I have a small app that functions as a server for handling socket connections (TCP). I have an iOS app that can connect and communicate with this app without any problems. But, the plugin I'm testing with using LRSocket will not even connect to the sever app let alone send messages.

I'm using Adobe's basic example for "send" with LrSocket. When trying to connect It returns an error saying "failed to open localhost:54345". I used this program https://sourceforge.net/projects/sockettest/?source=typ_redirect​ to test my server as well, this program can connect to my server without any problems.

This is the code for my plugin that is returning the connecting error.

local LrFunctionContext = import "LrFunctionContext"

local LrDialogs = import 'LrDialogs'

local LrSocket = import "LrSocket"

local LrTasks = import "LrTasks"

import "LrTasks".startAsyncTask( function()

        LrFunctionContext.callWithContext( 'socket_remote', function( context )

            local running = true

           

            local sender = LrSocket.bind {

              functionContext = context,

              plugin = _PLUGIN,

              port = 54345,

              mode = "send",

              onConnecting = function( socket, port )

               -- TODO

              end,

              onConnected = function( socket, port )

               -- TODO

              end,

              onMessage = function( socket, message )

               -- nothing, we don't expect to get any messages back from a send port

              end,

              onClosed = function( socket )

               running = false

              end,

              onError = function( socket, err )

               if err == "timeout" then

                socket:reconnect()

               end

               LrDialogs.message( err, err, nil )

              end,

             }

             sender:send( "Hello world" )

            

            while running do

              LrTasks.sleep( 1/2 ) -- seconds

            end

           

            sender:close()

        end )

end )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 22, 2017 Jul 22, 2017

Copy link to clipboard

Copied

I don't see anything obviously wrong.  Some thoughts:

- Try port numbers from different parts of the range of valid numbers.

- Try using "telnet" at the other end as the test server, e.g. "telnet localhost 54345".

See this thread for a sample script that worked (at least last summer): Re: LrSocket running on Windows - problems

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 22, 2017 Jul 22, 2017

Copy link to clipboard

Copied

When I do "telnet localhost 54345" I get the Hello World back. Assuming I catch it before the plugin times out.

I also get Hello World back if I use that SocketTest app (using it as a client).

Am I misunderstanding something? I thought LR acts as the client in this case (connecting to the external server app I made)? Is that not how it works? Should I treat LR as the server for both send/receiving messages?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 22, 2017 Jul 22, 2017

Copy link to clipboard

Copied

I had assumed it always acts as a server, and that's what these tests show. But someone like @kimaldis who's used LrSocket extensively will be more authoritative...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 23, 2017 Jul 23, 2017

Copy link to clipboard

Copied

You are correct. Connecting to the LR plugin as a client for both sending and receiving allows the app to communicate with it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jul 24, 2017 Jul 24, 2017

Copy link to clipboard

Copied

Again, it's been a while and I don't have my laptop in front of me for a few days but from memory: I had to faff around quite a lot to get this to work and I do remember that getting the app end right took a degree of fiddling before it worked, due mostly to my only just working knowledge of sockets. My code is in Swift, you're more than welcome to it when I get my laptop back if it helps. Toward end of week. I'll be open sourcing it anyway when I get my head around GitHub.

Be sure you open the LrSocket before the app, both for receive and send. You get 5-10 seconds.

You'll need a socket each for send and receive.

If you're sending and expecting a response in tasks you may need some kind of handshaking to avoid the picking up the wrong return message.

I really wish they'd made this handle both send and receive on the one connection/port. Like telnet, for example. It would have made life much easier. And I've no idea why they restricted it to localhost either.

All that said, when you get it working it works well. I have a very nice custom hot key mechanism that runs lua code snippets and a very neat way of controlling lightroom and displaying information in a browser on a remote device. Again, I'll open source it when I figure out GitHub. I'll also be looking for people to test it, if anyone's interested.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jul 24, 2017 Jul 24, 2017

Copy link to clipboard

Copied

Oh, make sure the strings you send and receive are terminated in new lines.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 24, 2017 Jul 24, 2017

Copy link to clipboard

Copied

I've gotten to the point that I can send/receive messages between a Mac app and the plugin. Though I would appreciate seeing your code as well!

For whatever reason it doesn't seem to matter for me whether the client or the plugin start first. Nor does it matter if I miss that 10-15 second opening before a timeout. Maybe it is a result of restarting/reconnecting if the connection closes or timesout?

onClosed = function( socket )

     socket:reconnect()

     cr.SERVER:close()

     startServer(context)

end,

  

onError = function(socket, err)

     if err == 'timeout' then

          socket:reconnect()

     end

end

I do have a separate question, I am curious whether or not you notice anything weird when quitting Lightroom with your plugin installed?

When I quit Lightroom with my plugin started, it takes ~5 seconds for Lightroom to close the window and another ~10 seconds before the task completely dies (the dot under the icon in the Dock disappears). It is essentially in a non-responsive state for a number of seconds. Without my plugin installed it quits nearly automatically (a couple of seconds or less). I haven't tested it enough to know if anything else in Lightroom degrades in performance.

This is also true for another plugin that I did not write but uses sockets.

I'm not sure if there is some kind of cleanup or something I should be doing in my plugin code so that it closes more gracefully and rapidly?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jul 24, 2017 Jul 24, 2017

Copy link to clipboard

Copied

LATEST

Yes, I would think it's the reconnect that's masking the timeout. My plugin fires my app for me' it never gets that far.

I have a bit of a delay when Shut lightroom down but I wouldn't say it was out of the ordinary. I haven't checked it without the plugin running.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines