unit fClientForm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uROClient, uROClientIntf, uRORemoteService, uROBinMessage, uROIndyTCPChannel, ComCtrls, ImgList, ExtCtrls; type TClientForm = class(TForm) ROMessage: TROBinMessage; ROChannel: TROIndyTCPChannel; RORemoteService: TRORemoteService; gbSum: TGroupBox; edA: TEdit; edB: TEdit; udA: TUpDown; udB: TUpDown; lblA: TLabel; lblB: TLabel; btnSum: TButton; GroupBox1: TGroupBox; memLog: TMemo; gbChannelOptions: TGroupBox; chkFaultTolerance: TCheckBox; chkLoadBalancing: TCheckBox; Label2: TLabel; lvLocators: TListView; GroupBox2: TGroupBox; Label1: TLabel; chkProbeServers: TCheckBox; edProbeFreequency: TEdit; GroupBox3: TGroupBox; btnProbeAll: TButton; btnProbeSelected: TButton; il: TImageList; udProbeFreequency: TUpDown; CheckBox1: TCheckBox; t: TTimer; Label3: TLabel; procedure FormCreate(Sender: TObject); procedure chkFaultToleranceClick(Sender: TObject); procedure chkLoadBalancingClick(Sender: TObject); procedure chkProbeServersClick(Sender: TObject); procedure udProbeFreequencyChangingEx(Sender: TObject; var AllowChange: Boolean; NewValue: Smallint; Direction: TUpDownDirection); procedure btnProbeAllClick(Sender: TObject); procedure btnProbeSelectedClick(Sender: TObject); procedure btnSumClick(Sender: TObject); procedure btnGetServerTimeClick(Sender: TObject); procedure LogLocatorState(Sender: TROServerLocator); procedure ROChannelBeforeProbingServer(Sender: TROTransportChannel; aServerLocator: TROServerLocator); procedure ROChannelAfterProbingServer(Sender: TROTransportChannel; aServerLocator: TROServerLocator; Failed: Boolean); procedure ROChannelBeforeProbingServers(Sender: TROTransportChannel); procedure ROChannelAfterProbingServers(Sender: TROTransportChannel; ProbedCount, EnabledCount, DisabledCount: Integer); procedure ROChannelServerLocatorAssignment(Sender: TROTransportChannel; aLocator: TROServerLocator; aException: Exception); procedure tTimer(Sender: TObject); procedure CheckBox1Click(Sender: TObject); procedure ROChannelException(Sender: TROTransportChannel; anException: Exception; var aRetry: Boolean); private { Private declarations } procedure Log(aMessage: String); procedure FillLocators(aChannel: TROTransportChannel); procedure UpdateLocator(aLocator: TROServerLocator); procedure ReEnableIfAllDisabled; public { Public declarations } end; var ClientForm: TClientForm; implementation { The unit LoadBalancingLibrary_Intf.pas will be generated by the RemObjects preprocessor the first time you compile your server application. Make sure to do that before trying to compile the client. To invoke your server simply typecast your server to the name of the service interface like this: (RORemoteService as ILoadBalancingService).Sum(1,2) } uses LoadBalancingLibrary_Intf; {$R *.dfm} procedure TClientForm.Log(aMessage: String); begin memLog.Lines.Add(aMessage); end; procedure TClientForm.FillLocators(aChannel: TROTransportChannel); var i: Integer; lLocator: TROServerLocator; lCurrentLocator: TROServerLocator; lItem: TListItem; begin lvLocators.Items.BeginUpdate(); lvLocators.Items.Clear(); try lCurrentLocator := aChannel.CurrentLocator; for i := 0 to aChannel.ServerLocators.Count - 1 do begin lLocator := aChannel.ServerLocators[i]; lItem := lvLocators.Items.Add(); lItem.Data := lLocator; lItem.Caption := lLocator.Name; lItem.SubItems.Add(lLocator.Host); lItem.SubItems.Add(IntToStr(lLocator.Port)); if lLocator.Enabled then begin lItem.SubItems.Add('Enabled'); lItem.ImageIndex := 1; end else begin lItem.SubItems.Add('Disabled'); lItem.ImageIndex := 2; end; if lLocator = lCurrentLocator then lItem.ImageIndex := 0; end; finally lvLocators.Items.EndUpdate(); end; end; procedure TClientForm.UpdateLocator(aLocator: TROServerLocator); var i: Integer; lLocator: TROServerLocator; lListItem: TListItem; begin for i := 0 to lvLocators.Items.Count -1 do begin lListItem := lvLocators.Items[i]; lLocator := TROServerLocator(lListItem.Data); if lLocator = aLocator then begin if lLocator.Enabled then begin lListItem.SubItems[2] := 'Enabled'; lListItem.ImageIndex := 1; end else begin lListItem.SubItems[2] := 'Disabled'; lListItem.ImageIndex := 2; end; if lLocator = ROChannel.ServerLocators[ROChannel.LoadBalancerLocatorIdx] then lListItem.ImageIndex := 0; exit; end; end; end; procedure TClientForm.FormCreate(Sender: TObject); begin FillLocators(ROChannel); end; procedure TClientForm.chkFaultToleranceClick(Sender: TObject); begin if chkFaultTolerance.Checked then ROChannel.DispatchOptions := ROChannel.DispatchOptions + [doFaultTolerant] else ROChannel.DispatchOptions := ROChannel.DispatchOptions - [doFaultTolerant]; end; procedure TClientForm.chkLoadBalancingClick(Sender: TObject); begin if chkLoadBalancing.Checked then ROChannel.DispatchOptions := ROChannel.DispatchOptions + [doLoadBalanced] else ROChannel.DispatchOptions := ROChannel.DispatchOptions - [doLoadBalanced]; end; procedure TClientForm.chkProbeServersClick(Sender: TObject); begin ROChannel.ProbeServers := chkProbeServers.Checked; end; procedure TClientForm.udProbeFreequencyChangingEx(Sender: TObject; var AllowChange: Boolean; NewValue: Smallint; Direction: TUpDownDirection); begin ROChannel.ProbeFrequency := NewValue * 1000; end; procedure TClientForm.btnProbeAllClick(Sender: TObject); begin Log('Probe all servers manully...'); (ROChannel as IROTransportChannel).ProbeAll(); Log('Done'); end; procedure TClientForm.btnProbeSelectedClick(Sender: TObject); begin if (Assigned(lvLocators.Selected) and Assigned(lvLocators.Selected.Data) and Assigned(TROServerLocator(lvLocators.Selected.Data))) then begin (ROChannel as IROTransportChannel).Probe(TROServerLocator(lvLocators.Selected.Data)); FillLocators(ROChannel); end; end; procedure TClientForm.btnSumClick(Sender: TObject); var a, b, r: Integer; begin a := udA.Position; b := udB.Position; Log('Calling Sum function ...'); r := (RORemoteService as ILoadBalancingService).Sum(a, b); Log(Format('%d + %d = %d', [a, b, r])); Log('Sum function executed.'); FillLocators(ROChannel); end; procedure TClientForm.btnGetServerTimeClick(Sender: TObject); var d: TDateTime; begin Log('Calling Get Server Time function ...'); d := (RORemoteService as ILoadBalancingService).GetServerTime(); Log(Format('Server time is: %s', [DateTimeToStr(d)])); Log('Get Server Time function executed.'); FillLocators(ROChannel); end; procedure TClientForm.LogLocatorState(Sender: TROServerLocator); var l: String; begin if (Sender.Enabled) then l := 'enabled' else l:= 'disabled'; Log(Format('Locator "%s" has been %s.', [Sender.Name, l])); end; procedure TClientForm.ROChannelBeforeProbingServer( Sender: TROTransportChannel; aServerLocator: TROServerLocator); var l: String; begin if aServerLocator.Enabled then l := 'enabled' else l:='disabled'; Log(Format('Starting probing server "%s". Current state is "%s"', [aServerLocator.Name, l])); end; procedure TClientForm.ROChannelAfterProbingServer( Sender: TROTransportChannel; aServerLocator: TROServerLocator; Failed: Boolean); var l, s: String; begin if Failed then s:='failed' else s:='was successful'; if aServerLocator.Enabled then l := 'enabled' else l:='disabled'; Log(Format('Probing server "%s" %s. State is "%s".', [aServerLocator.Name, s, l])); //UpdateLocator(aServerLocator); FillLocators(Sender); end; procedure TClientForm.ROChannelBeforeProbingServers( Sender: TROTransportChannel); begin Log('Starting probing available servers...'); end; procedure TClientForm.ROChannelAfterProbingServers( Sender: TROTransportChannel; ProbedCount, EnabledCount, DisabledCount: Integer); begin Log('Probing available servers completed.'); Log(Format('Probed %d servers, %d enabled and %d disabled.', [ProbedCount, EnabledCount, DisabledCount])); end; procedure TClientForm.ROChannelServerLocatorAssignment( Sender: TROTransportChannel; aLocator: TROServerLocator; aException: Exception); begin if Assigned(aException) then Log(Format('Exception: %s.', [aException.Message])); Log(Format('Locator %s (Host=%s; Port=%d) has been assigned.', [aLocator.Name, aLocator.Host, aLocator.Port])); //UpdateLocator(aLocator); FillLocators(Sender); end; procedure TClientForm.tTimer(Sender: TObject); begin btnSum.Click(); end; procedure TClientForm.CheckBox1Click(Sender: TObject); begin t.Enabled := CheckBox1.Checked; end; procedure TClientForm.ReEnableIfAllDisabled; var i: integer; begin for i := 0 to ROChannel.ServerLocators.Count -1 do if ROChannel.ServerLocators[i].Enabled then Exit; Log('All locators are disabled. re-enabling all locators.'); for i := 0 to ROChannel.ServerLocators.Count -1 do ROChannel.ServerLocators[i].Enabled := True; end; procedure TClientForm.ROChannelException(Sender: TROTransportChannel; anException: Exception; var aRetry: Boolean); begin Log(anException.Message); ReEnableIfAllDisabled; aRetry := True; end; end.