Skip to main content
Inspiring
September 22, 2015
Question

Working with LRSocket, receiving

  • September 22, 2015
  • 2 replies
  • 3276 views

I'm trying to set up a communication between Lightroom and another process using LRSocket. I've worked out an LrSocket.bind with mode = "send" and that's all working fine but I cannot for the life of me get a receive working. Here's my Lua code:

Connection = {

}

function Connection.Listen( self, context )

        local running = true

        self.Listener = LrSocket.bind {

       functionContext = context,

            port = 4242,

            plugin = _PLUGIN,

            mode = "receive",

            onConnected = function( socket, port )

                 Debug.logn( "Listener connected on port " .. port )

            end,

            onMessage = function( socket, message )

                 Debug.logn( "Listener Got: " .. message );

            end,

            onClosed = function( socket )

                 Debug.logn( "Listener Closed on Port: " .. myPort )

                 running = false

            end,

            onError = function( socket, err )

                 if err == "timeout" then

                 end

            end,

  } -- bind

  while running do

  LrTasks.sleep( 1/2 ) -- seconds

  end

  self.Listener:close()

end

I've been testing with both telnet and a short python snippet shown below. Telnet fails to connect at all, the Python code connects and the onConnected callback is called but, although text is being sent, the onMessage callback doesn't get called. I wondered if anyone had managed to make this work at all or if anyone has any pointers on what might be going wrong.

import socket, select, sys, time

def Send( msg 😞

    TCP_IP = 'localhost'

    TCP_PORT = 4242

    BUFFER_SIZE = 1024

    MESSAGE = "Hello, World!"

    print "Sending on port ",  TCP_PORT

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    s.settimeout(2)

    s.connect((TCP_IP, TCP_PORT))

    s.send(MESSAGE)

    print "Sent"

    s.close()

    time.sleep( 5 )

    print "Closed"

Send( "Test")

Many thanks.

This topic has been closed for replies.

2 replies

Participant
September 23, 2015

I have been trying to use the new LrSocket for communication back and forth with a visual basic .net program.  I have been able to send a command to lightroom, but I cannot get lightroom to respond.

Make sure the command you send has a new line char at the end.

Here is the code I am using. This is based on some examples i saw somewhere. If someone could help me with the sending part. I cannot even get it to send to itself if I set the same port number.

local LrSocket = import "LrSocket"

local LrTasks = import "LrTasks"

local LrFunctionContext = import "LrFunctionContext"

local LrDialogs = import 'LrDialogs'

local LrApplication = import 'LrApplication'

local LrDevelopController = import 'LrDevelopController'

local LrSelection = import 'LrSelection'

LrLogger = import 'LrLogger'

myLogger = LrLogger( 'exportLogger' )

myLogger:enable( "print" )

-- Global consts

local RECEIVE_PORT = 9885

local SEND_PORT    = 9886

-- Global vars

local SERVER = {}

function process_Mess (command)

    dbgout("  Processing Mess")

    --dbgout(command)

    --LrDialogs.message( "Received Message", command, "info" );

    posblank1 = string.find  ( command, ' ', 1 )

    if posblank1

      then

        LRfunc = string.sub ( command, 1, posblank1-1)

      else

        LRfunc = command

    end

    dbgout ("  "..posblank1)

    dbgout (LRfunc)

   

    if LRfunc == "hello" then

        dbgout ("    Action: = Hello")

        LrDialogs.showBezel( "Hello", 2 )

      dbgout ("Send Message")

   

      SERVER:send( "Hello world \n" )

       dbgout ("Message Sent")

      

   end

    

end

local function startServer(context)

    SERVER = LrSocket.bind {

          functionContext = context,

          plugin = _PLUGIN,

          port = SEND_PORT,

          mode = 'send',

          onClosed = function( socket )

          end,

      onConnecting = function( socket, port )

            dbgout( "------- Server Waiting for Connection..")

            dbgout( "-------   Port: "..port)

        end,

        onConnected = function( socket, port )

            dbgout( "------- Server Connected")

            dbgout( "-------   Port: "..port)

        end,

          onError = function( socket, err )

      dbgout( "------- Server Error")

      dbgout( err)

            socket:reconnect()

          end,

        }

end

LrTasks.startAsyncTask( function()

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

         dbgout("Socket Receive");

         local running = true

        local client = LrSocket.bind {

        functionContext = context,

        plugin = _PLUGIN,

        port = RECEIVE_PORT,

        mode = 'receive',

        onMessage = function(socket, message)

            dbgout("Message:=")

            dbgout(message)

            process_Mess(message)

        end,

        onConnecting = function( socket, port )

            dbgout( "Waiting for Connection..")

        end,

        onConnected = function( socket, port )

            dbgout( "Connected")

        end,

        onClosed = function( socket )

          

            socket:reconnect()

            dbgout( "Closed")

              

            SERVER:close()

            startServer(context)

        end,

        onError = function(socket, err)

            if err == 'timeout' then -- reconnect if timed out

            socket:reconnect()

            end

        end

        }

      

       startServer(context)

      

        while true do

            LrTasks.sleep( 1/2 )

        end

      

        client:close()

        SERVER:close()

    end )

end )

kimaldisAuthor
Inspiring
September 23, 2015

It was the new line. Thanks for that.

I can't see anything wrong with your code, maybe it's at the VB end. Did you try with telnet?

I'll post working code when I'm all tidied up and in good order in a couple of days.

kimaldisAuthor
Inspiring
September 28, 2015

As promised, my working example of using LrSocket. It's Mac tested, should work for Windows but you'll need Python installed. It's a very simple send receive plugin, the Python script takes input from the terminal, sends it to the Lightroom plugin, the Lightroom plugin responds with a simple "OK". Start the plugin listening with File->Plugin Extras->Connection Test, kill it by sending it "exit" from the Python script. You can fire up either end first and it'll wait for a connection from the other end.

Code is reasonably well documented.

My understanding of sockets is workmanlike but not extensive, there may be better ways of doing this.

Plugin

kimaldisAuthor
Inspiring
September 22, 2015

I should add, I am calling all of this within a function context and a within an async task:

LrTasks.startAsyncTask( function()

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

            local Replier = Connection

            Replier:Listen( context )

        end)

    end)