Recent

Author Topic: [SOLVED] SimpleIPC and Multiple Application Instances  (Read 8529 times)

evoshroom

  • Full Member
  • ***
  • Posts: 157
[SOLVED] SimpleIPC and Multiple Application Instances
« on: September 14, 2012, 02:02:57 am »
I have an application and a systray add-on to the application.  The application and the systray extension application each have a TSimpleIPCClient and a TSimpleIPCServer to facilitate two-way communication on the local machine.  The Server and Client connect via a unique ServerID property and I currently have the Global property set to True.  This part worked perfectly.

However, this becomes a problem if I want to run two copies of the program on the local machine (which is a possible use-case and is also extremely valuable for testing).  If two copies of the program are launched, because both copies have the same ServerID to connect to, the second copy takes over the first copy's connections and the first copy doesn't receive any data after that.

So, my question is, how can I run two copies of an application and two copies of its systray sister app and have them both speak to each other via SimpleIPC.

In some ways it seems like the InstanceID property of SimpleIPC may have something to do with this, but if so, I'm not quite sure how and I've found zero information about using the InstanceID of SimpleIPC online. 

Does anyone have any ideas about how to make this work?  :)
« Last Edit: September 15, 2012, 06:57:26 am by evoshroom »

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: SimpleIPC and Multiple Application Instances
« Reply #1 on: September 14, 2012, 02:45:14 am »
Hello evoshroom, did you try to open both application in different thread?.
I did something equal with Lazarus and J2ME.

Oh, maybe you didn't understand.  The problem is not opening two applications.  The problem is SimpleIPC connects via a global string called ServerID.  For example you will name ServerID := MyServer1 on the SimpleIPCClient and ServerID := MyServer1 on the SimpleIPCServer and that's how the client and server know to connect to each other.  If you open a second copy of the application it also tries to connect to MyServer1, which is the problem.  Threading things won't change that fact.

icey

  • New Member
  • *
  • Posts: 19
Re: SimpleIPC and Multiple Application Instances
« Reply #2 on: September 14, 2012, 08:31:21 pm »
You could increment ServerIDs until you get a free one  :)

MainApp:
Code: [Select]
unit ma_unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  simpleipc;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    IPCServer: TSimpleIPCServer;
    IPCClient: TSimpleIPCClient;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure IPCServerMessage(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  IPCClient.SendStringMessage('This goes to ' + IPCClient.ServerID);
end;

procedure TForm1.FormShow(Sender: TObject);
var
  isRunning  : boolean;
  checkForID : integer;
begin
  checkForID := 0;
  Repeat
    Inc(checkForID);
    IPCClient.ServerID := 'MainApp_' + IntToStr(checkForID);
    isRunning := IPCClient.ServerRunning
  until not isRunning;

  Self.Caption       := 'MainApp_' + IntToStr(checkForID);
  IPCServer.ServerID := 'MainApp_' + IntToStr(checkForID);
  IPCClient.ServerID := 'SysTray_' + InttoStr(checkForID);
  IPCServer.StartServer;

  Repeat
    Application.ProcessMessages
  until IPCClient.ServerRunning;
  IPCClient.Connect;

  IPCClient.SendStringMessage('This goes to ' + IPCClient.ServerID);
end;

procedure TForm1.IPCServerMessage(Sender: TObject);
begin
  Memo1.Lines.Add(IPCServer.StringMessage);
end;

end.

SysTray:
Code: [Select]
unit st_unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  simpleipc;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    IPCClient: TSimpleIPCClient;
    IPCServer: TSimpleIPCServer;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure IPCServerMessage(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormShow(Sender: TObject);
var
  isRunning  : boolean;
  checkForID : integer;
begin
  checkForID := 0;
  Repeat
    Inc(checkForID);
    IPCClient.ServerID := 'SysTray_' + IntToStr(checkForID);
    isRunning := IPCClient.ServerRunning
  until not isRunning;

  Self.Caption       := 'Systray_' + IntToStr(checkForID);
  IPCServer.ServerID := 'SysTray_' + IntToStr(checkForID);
  IPCClient.ServerID := 'MainApp_' + InttoStr(checkForID);
  IPCServer.StartServer;


  Repeat
    Application.ProcessMessages
  until IPCClient.ServerRunning;
  IPCClient.Connect;

  IPCClient.SendStringMessage('This goes to ' + IPCClient.ServerID);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  IPCClient.SendStringMessage('This goes to ' + IPCClient.ServerID);
end;

procedure TForm1.IPCServerMessage(Sender: TObject);
begin
  Memo1.Lines.Add(IPCServer.StringMessage);
end;

end.

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: SimpleIPC and Multiple Application Instances
« Reply #3 on: September 15, 2012, 06:56:44 am »
Oh, that's very clever.  I feel daft for not thinking of having the SimpleIPCClient pretend to be the ServerID type of the SimpleIPCServer to check for previously existing instances of that server and then incrementing the SeverID by one.   Thank you very much!
« Last Edit: September 15, 2012, 07:26:14 am by evoshroom »

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: SimpleIPC and Multiple Application Instances
« Reply #4 on: September 15, 2012, 08:03:47 am »
Code: [Select]
procedure TForm1.IPCServerMessage(Sender: TObject);
begin
  Memo1.Lines.Add(IPCServer.StringMessage);
end;

end.

Oh, one question though.  Are you sure ServerMessage works like that?  That's how I originally assumed it worked too, but that code doesn't ever add anything to the Memo.

I had to set up a timer with a interval of 1000 and use this code in the timer to get it working:

Code: [Select]
if sipcServer.Active then
  if sipcServer.PeekMessage(1,true) then
   Memo1.Lines.Add(sipcServer.StringMessage);

Am I missing something in regard to that?

 

TinyPortal © 2005-2018