From b181501b1904e7b7aa3ad1c92e4dceb024e02702 Mon Sep 17 00:00:00 2001 From: Roberto Schneiders Date: Fri, 25 Sep 2015 16:36:44 -0300 Subject: [PATCH 1/3] Improves error handling for ComObj callbacks (this methos cannot fail). Changes the params order in Connect. --- README.md | 4 ++-- delphi/PusherClient/PusherClient.pas | 34 ++++++++++++++++++++-------- delphi/example/example.pas | 14 +++++------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index df75f7e..bc9ad97 100644 --- a/README.md +++ b/README.md @@ -56,14 +56,14 @@ end; SSL is enabled by default. You can disable it by passing a empty option list `[]` to the `Connect` method: ``` -PusherClient.Connect('your_pusher_key', []); +PusherClient.Connect('your_pusher_key', '', []); ``` ### Custom Host Address It is possible to use a custom host address: ``` -PusherClient.Connect('your_pusher_key', [], 'localhost'); +PusherClient.Connect('your_pusher_key', 'localhost'); ``` The [default value](https://github.com/pusher-community/pusher-websocket-dotnet/blob/master/PusherClient/Pusher.cs#L43) is `ws.pusherapp.com` which is the pusher.com endpoint, but you can also use it with a [poxa](https://github.com/edgurgel/poxa) server hosted in your own server. diff --git a/delphi/PusherClient/PusherClient.pas b/delphi/PusherClient/PusherClient.pas index 182077d..fc2ab3c 100644 --- a/delphi/PusherClient/PusherClient.pas +++ b/delphi/PusherClient/PusherClient.pas @@ -29,8 +29,7 @@ TPusherClient = class procedure ConnectionStateChange(Message: string); public class function GetInstance(): TPusherClient; - procedure Connect(Key: string; Options: TConnectionOptions = [coUseSSL]; - CustomHost: string = ''); + procedure Connect(Key: string; CustomHost: string = ''; Options: TConnectionOptions = [coUseSSL]); procedure Disconnect(); procedure Subscribe(Channel, EventName: String; Callback: TCallbackProcedure); property OnError: TCallbackProcedure read FOnError write FOnError; @@ -80,7 +79,7 @@ procedure OnConnectionStateChangeStdCall(message: pchar); stdcall; TPusherClient.GetInstance.ConnectionStateChange(StrPas(Message)); end; -procedure TPusherClient.Connect(Key: string; Options: TConnectionOptions; CustomHost: string); +procedure TPusherClient.Connect(Key, CustomHost: string; Options: TConnectionOptions); begin PusherClientNative.InitializePusherClient(Key, coUseSSL in Options, CustomHost); @@ -120,20 +119,37 @@ class function TPusherClient.GetInstance: TPusherClient; procedure TPusherClient.ConnectionStateChange(Message: string); begin - if Assigned(TPusherClient.GetInstance.FOnConnectionStateChange) then - TPusherClient.GetInstance.FOnConnectionStateChange(Message); + try + if Assigned(FOnConnectionStateChange) then + FOnConnectionStateChange(Message); + except + on E:Exception do + Error('An error occurred while calling the event OnConnectionStateChange: ' + e.message) + end; end; procedure TPusherClient.Error(Message: string); begin - if Assigned(TPusherClient.GetInstance.FOnError) then - TPusherClient.GetInstance.FOnError(Message); + try + if Assigned(FOnError) then + FOnError(Message); + except + // This method cannot fail under any circumstances. It is called by the ComObj callback. + // if some of the others callbacks (OnLog, OnConnectionStateChange) fails they will call this + // method to try to inform the client application about the problem, but, if this method + // fails, there are nothing we can do. + end; end; procedure TPusherClient.Log(Message: string); begin - if Assigned(TPusherClient.GetInstance.FOnLog) then - TPusherClient.GetInstance.FOnLog(Message); + try + if Assigned(FOnLog) then + FOnLog(Message); + except + on E:Exception do + Error('An error occurred while calling the event OnLog: ' + e.message) + end; end; class procedure TPusherClient.ReleaseInstance; diff --git a/delphi/example/example.pas b/delphi/example/example.pas index fd7a6da..e1f0a14 100644 --- a/delphi/example/example.pas +++ b/delphi/example/example.pas @@ -33,8 +33,6 @@ TPusherClientExampleForm = class(TForm) procedure ConnectionStatus(Status: string); procedure Connect; procedure Disconnect; - public - { Public declarations } end; var @@ -73,11 +71,11 @@ procedure TPusherClientExampleForm.BtnSubscribeClick(Sender: TObject); if SubscribeList.Items.IndexOf(ListItem) = -1 then SubscribeList.Items.Add(EdtChannel.Text + ' | ' + EdtEvent.Text); - PusherClient.Subscribe(EdtChannel.Text, EdtEvent.Text, - procedure (Message: string) - begin - Log('[EVENT-MESSAGE]: ' + Message) - end) + PusherClient.Subscribe(EdtChannel.Text, EdtEvent.Text, + procedure (Message: string) + begin + Log('[EVENT-MESSAGE]: ' + Message) + end) end; procedure TPusherClientExampleForm.Connect; @@ -88,7 +86,7 @@ procedure TPusherClientExampleForm.Connect; if ChkUseSSL.Checked then Options := [coUseSSL]; - PusherClient.Connect(EdtKey.Text, Options, EdtHost.Text); + PusherClient.Connect(EdtKey.Text, EdtHost.Text, Options); end; procedure TPusherClientExampleForm.ConnectionStatus(Status: string); From 62987fb0413c6c2850603d420f37a2766810dd06 Mon Sep 17 00:00:00 2001 From: Roberto Schneiders Date: Fri, 25 Sep 2015 16:44:18 -0300 Subject: [PATCH 2/3] Adds documentation about the dll registration on the readme --- README.md | 5 +++++ dotnet/PusherClientNative/register_dll.bat | 1 + 2 files changed, 6 insertions(+) create mode 100644 dotnet/PusherClientNative/register_dll.bat diff --git a/README.md b/README.md index bc9ad97..411ba46 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,11 @@ All of them are shipped with this lib releases. Download the [last release](https://github.com/monde-sistemas/pusher-websocket-delphi/releases/latest) zip package and add it to your project. Make sure all the dependencies are on the same folder that your exe. +Register the DLL using RegAsm: +``` +%windir%\Microsoft.NET\Framework\v4.0.30319\regasm.exe /codebase PusherClientNative.dll /tlb:PusherClientNative.tlb +``` + Add `PusherClient` to your unit uses clause. ``` diff --git a/dotnet/PusherClientNative/register_dll.bat b/dotnet/PusherClientNative/register_dll.bat new file mode 100644 index 0000000..4ad2d8c --- /dev/null +++ b/dotnet/PusherClientNative/register_dll.bat @@ -0,0 +1 @@ +%windir%\Microsoft.NET\Framework\v4.0.30319\regasm.exe /codebase PusherClientNative.dll /tlb:PusherClientNative.tlb From 81467ed0f6cee64cffa6916c1db414d68d48e12c Mon Sep 17 00:00:00 2001 From: Roberto Schneiders Date: Fri, 25 Sep 2015 16:51:37 -0300 Subject: [PATCH 3/3] Renames GetInstance to Instance --- delphi/PusherClient/PusherClient.pas | 16 ++++++++-------- delphi/example/example.pas | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/delphi/PusherClient/PusherClient.pas b/delphi/PusherClient/PusherClient.pas index fc2ab3c..3fbf848 100644 --- a/delphi/PusherClient/PusherClient.pas +++ b/delphi/PusherClient/PusherClient.pas @@ -28,7 +28,7 @@ TPusherClient = class procedure Log(Message: string); procedure ConnectionStateChange(Message: string); public - class function GetInstance(): TPusherClient; + class function Instance(): TPusherClient; procedure Connect(Key: string; CustomHost: string = ''; Options: TConnectionOptions = [coUseSSL]); procedure Disconnect(); procedure Subscribe(Channel, EventName: String; Callback: TCallbackProcedure); @@ -46,12 +46,12 @@ implementation procedure OnLogStdCall(Message: pchar); stdcall; begin - TPusherClient.GetInstance.Log(StrPas(Message)); + TPusherClient.Instance.Log(StrPas(Message)); end; procedure OnErrorStdCall(message: pchar); stdcall; begin - TPusherClient.GetInstance.Error(StrPas(Message)); + TPusherClient.Instance.Error(StrPas(Message)); end; procedure OnSubscribeEventStdCall(Channel: pchar; EventName: pchar; Message: pchar); stdcall; @@ -59,7 +59,7 @@ procedure OnSubscribeEventStdCall(Channel: pchar; EventName: pchar; Message: pch ErrorMessage: string; begin try - TPusherClient.GetInstance.FSubscribed[StrPas(Channel)][StrPas(EventName)](StrPas(Message)); + TPusherClient.Instance.FSubscribed[StrPas(Channel)][StrPas(EventName)](StrPas(Message)); except on E:Exception do begin @@ -68,15 +68,15 @@ procedure OnSubscribeEventStdCall(Channel: pchar; EventName: pchar; Message: pch + sLineBreak + '[Channel][Event]: Message: [%s][%s]: [%s]' + sLineBreak + 'Error: [%s]', [StrPas(Channel), StrPas(EventName), StrPas(Message), E.Message]); - TPusherClient.GetInstance.Error(ErrorMessage); - TPusherClient.GetInstance.Log(ErrorMessage); + TPusherClient.Instance.Error(ErrorMessage); + TPusherClient.Instance.Log(ErrorMessage); end; end; end; procedure OnConnectionStateChangeStdCall(message: pchar); stdcall; begin - TPusherClient.GetInstance.ConnectionStateChange(StrPas(Message)); + TPusherClient.Instance.ConnectionStateChange(StrPas(Message)); end; procedure TPusherClient.Connect(Key, CustomHost: string; Options: TConnectionOptions); @@ -110,7 +110,7 @@ procedure TPusherClient.Disconnect; PusherClientNative.Disconnect; end; -class function TPusherClient.GetInstance: TPusherClient; +class function TPusherClient.Instance: TPusherClient; begin if not Assigned(Self.FInstance) then self.FInstance := TPusherClient.Create; diff --git a/delphi/example/example.pas b/delphi/example/example.pas index e1f0a14..3504dc8 100644 --- a/delphi/example/example.pas +++ b/delphi/example/example.pas @@ -113,7 +113,7 @@ procedure TPusherClientExampleForm.Error(Message: string); procedure TPusherClientExampleForm.InitializePusherClient; begin - PusherClient := TPusherClient.GetInstance; + PusherClient := TPusherClient.Instance; PusherClient.OnError := procedure(Message: string) begin Error('[ERROR]: ' + Message);