From 2b24e67c280792eb223aa4c047ae81db8c792cc9 Mon Sep 17 00:00:00 2001 From: briandunnington Date: Wed, 16 Jun 2010 19:32:10 +0000 Subject: [PATCH] GrowlConnector API updates (allow user-defined state);improvements to subscription mechanism --- .../NET/libraries/Growl.Connector.dll | Bin 61440 -> 61440 bytes .../NET/libraries/Growl.CoreLibrary.dll | Bin 28672 -> 28672 bytes .../libraries/Growl.CoreLibrary.dll | Bin 28672 -> 28672 bytes .../libraries/Growl.DisplayStyle.dll | Bin 49152 -> 49152 bytes Growl/Growl.Connector/ConnectorBase.cs | 33 +++-- Growl/Growl.Connector/GrowlConnector.cs | 134 +++++++++++++++--- Growl/Growl.Connector/Response.cs | 22 +++ Growl/Growl.Daemon/CallbackInfo.cs | 20 ++- Growl/Growl.Daemon/GrowlServer.cs | 40 +++++- Growl/Growl.Daemon/MessageHandler.cs | 8 +- Growl/Growl.Daemon/Properties/AssemblyInfo.cs | 4 +- Growl/Growl.Daemon/SubscriptionConnector.cs | 8 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- Growl/Growl/Properties/AssemblyInfo.cs | 4 +- Growl/Growl/_source/Controller.cs | 24 ++-- Growl/Growl/_source/Forwarder.cs | 2 +- Growl/Growl/_source/GNTPSubscription.cs | 8 +- .../_source/SubscribedForwardDestination.cs | 4 +- Growl/Growl/release_notes.txt | 4 + Growl/Test App/Form1.cs | 10 +- 26 files changed, 273 insertions(+), 80 deletions(-) diff --git a/Growl Connectors/NET/libraries/Growl.Connector.dll b/Growl Connectors/NET/libraries/Growl.Connector.dll index a0944422a646f0f6804d9ff1f7e49a86feffc54f..ad8c99d5b106ce74df36efec942ce9f4acc2e495 100644 GIT binary patch delta 12069 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 RtF(Slhx5=^_V(V!{{_9l+m!$S delta 11162 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 diff --git a/Growl Connectors/NET/libraries/Growl.CoreLibrary.dll b/Growl Connectors/NET/libraries/Growl.CoreLibrary.dll index 5526ece3027c05b81aef1bdd73af0fa09a9ce741..c3d9ddde62988ed919c95cbef8fee4ca4d4ebd48 100644 GIT binary patch delta 248 zcmV~j8LaS9JE;0V` ztexR^wLK~o5y3Hd*+(!J5TQbiP&$rAK02W6`{`TMK&bxCh2#8_p@|k9`tczJWg{j~ zzw~^;A^*age+v0y#JjFbRmr2>j;>i+E8b(q2GfDtO^28;j(?x(w1)aBHkj(Kg~Ybn z1p$Y%&=4>x5b_HedbaW^L6*#UfAtb(cC!#WVFnH~000aD00%NIFfKGMF_V8m#RCjB y7?VdrDFFhraY7po3jqKG0000200004vzJg^0R=PwE&wsJ`B8%b0W`CHQ-d7U8f6Ut delta 248 zcmVit=2F)3%uY-fvHG_8xr?~G8)hUW{m&78BtkwnlVPs#da-~&g7S~kT z&jG2k&=4>x5Y9bAynK_hOqribfG7${gtHJkVFnH}000aD00%NIFfKDLHIsiq#REbY y0Fy^TDFFeqaY7po3k3iJ0000200003vzJg^0R=MvE&w&N`B8%b0W-6GQ-d72u3+~7 diff --git a/Growl Extras/Growl Display SDK/libraries/Growl.CoreLibrary.dll b/Growl Extras/Growl Display SDK/libraries/Growl.CoreLibrary.dll index 5526ece3027c05b81aef1bdd73af0fa09a9ce741..c3d9ddde62988ed919c95cbef8fee4ca4d4ebd48 100644 GIT binary patch delta 248 zcmV~j8LaS9JE;0V` ztexR^wLK~o5y3Hd*+(!J5TQbiP&$rAK02W6`{`TMK&bxCh2#8_p@|k9`tczJWg{j~ zzw~^;A^*age+v0y#JjFbRmr2>j;>i+E8b(q2GfDtO^28;j(?x(w1)aBHkj(Kg~Ybn z1p$Y%&=4>x5b_HedbaW^L6*#UfAtb(cC!#WVFnH~000aD00%NIFfKGMF_V8m#RCjB y7?VdrDFFhraY7po3jqKG0000200004vzJg^0R=PwE&wsJ`B8%b0W`CHQ-d7U8f6Ut delta 248 zcmVit=2F)3%uY-fvHG_8xr?~G8)hUW{m&78BtkwnlVPs#da-~&g7S~kT z&jG2k&=4>x5Y9bAynK_hOqribfG7${gtHJkVFnH}000aD00%NIFfKDLHIsiq#REbY y0Fy^TDFFeqaY7po3k3iJ0000200003vzJg^0R=MvE&w&N`B8%b0W-6GQ-d72u3+~7 diff --git a/Growl Extras/Growl Display SDK/libraries/Growl.DisplayStyle.dll b/Growl Extras/Growl Display SDK/libraries/Growl.DisplayStyle.dll index 765d555e32bc9bdb5edadb1fd3138c3433d310fd..930b3d9b5592a6e4b2bf9411e054418a07765cc0 100644 GIT binary patch delta 107 zcmZo@U~Xt&p3uR}V}O;& K+1$IhSOx&}M5{Jlp^IZ=UX4_PbnOdo#y`dz^g63=BMs4D3dF z271PNrjx(SJOR=$dH*a;M#jxAXDw#sW@TVzU|?VZV&=`$7bG&W8Z+oIm~Q^Nu%D69 KcysUKVi^F!Um}PA diff --git a/Growl/Growl.Connector/ConnectorBase.cs b/Growl/Growl.Connector/ConnectorBase.cs index 0f97c6b..f404b5a 100644 --- a/Growl/Growl.Connector/ConnectorBase.cs +++ b/Growl/Growl.Connector/ConnectorBase.cs @@ -32,7 +32,8 @@ public abstract class ConnectorBase /// Represents methods that handle the ResponseReceived events /// /// - protected delegate void ResponseReceivedEventHandler(string response); + /// An optional state object that will be passed into the response events associated with this request + protected delegate void ResponseReceivedEventHandler(string response, object state); /// /// The password used for message authentication and/or encryption @@ -170,7 +171,8 @@ protected Key GetKey() /// Parses the response and raises the appropriate event /// /// The raw GNTP response - protected abstract void OnResponseReceived(string responseText); + /// An optional state object that will be passed into the response events associated with this request + protected abstract void OnResponseReceived(string responseText, object state); /// /// Occurs when any of the following network conditions occur: @@ -179,7 +181,8 @@ protected Key GetKey() /// 3. Read request fails /// /// The that contains information about the failure - protected abstract void OnCommunicationFailure(Response response); + /// An optional state object that will be passed into the response events associated with this request + protected abstract void OnCommunicationFailure(Response response, object state); /// /// Fired immediately before the message is constructed and set. @@ -202,7 +205,8 @@ protected virtual bool OnBeforeSend(MessageBuilder mb) /// The used to contruct the request /// The for handling the response /// true to wait for a callback;false otherwise - protected void Send(MessageBuilder mb, ResponseReceivedEventHandler del, bool waitForCallback) + /// An optional state object that will be passed into the response events associated with this request + protected void Send(MessageBuilder mb, ResponseReceivedEventHandler del, bool waitForCallback, object state) { // do some of this *before* we spin up a new thread so we can just throw an exception if the error occurs // *before* we even send the request (like when generating the message bytes) @@ -213,7 +217,7 @@ protected void Send(MessageBuilder mb, ResponseReceivedEventHandler del, bool wa mb = null; // start a new thread for the network connection stuff - ConnectionState cs = new ConnectionState(bytes, del, waitForCallback); + ConnectionState cs = new ConnectionState(bytes, del, waitForCallback, state); ParameterizedThreadStart pts = new ParameterizedThreadStart(SendAsync); Thread t = new Thread(pts); t.Start(cs); @@ -248,7 +252,7 @@ private void SendAsync(object obj) } catch (Exception ex) { - OnCommunicationFailure(new Response(ErrorCode.NETWORK_FAILURE, ErrorDescription.CONNECTION_FAILURE)); + OnCommunicationFailure(new Response(ErrorCode.NETWORK_FAILURE, ErrorDescription.CONNECTION_FAILURE), cs.UserState); } // write @@ -259,7 +263,7 @@ private void SendAsync(object obj) } catch (Exception ex) { - OnCommunicationFailure(new Response(ErrorCode.NETWORK_FAILURE, ErrorDescription.WRITE_FAILURE)); + OnCommunicationFailure(new Response(ErrorCode.NETWORK_FAILURE, ErrorDescription.WRITE_FAILURE), cs.UserState); } // read @@ -279,7 +283,7 @@ private void SendAsync(object obj) break; } } - del(response); + del(response, cs.UserState); // wait for callback if (waitForCallback) @@ -299,12 +303,12 @@ private void SendAsync(object obj) break; } } - del(response); + del(response, cs.UserState); } } catch (Exception ex) { - OnCommunicationFailure(new Response(ErrorCode.NETWORK_FAILURE, ErrorDescription.READ_FAILURE)); + OnCommunicationFailure(new Response(ErrorCode.NETWORK_FAILURE, ErrorDescription.READ_FAILURE), cs.UserState); } } catch (Exception ex) @@ -357,11 +361,13 @@ protected ConnectionState() { } /// The request bytes to be written /// The method to call to handle the response /// true if the connection should wait for a callback;false otherwise - public ConnectionState(byte[] bytes, ResponseReceivedEventHandler del, bool waitForCallback) + /// An optional state object that will be passed into the response events associated with this request + public ConnectionState(byte[] bytes, ResponseReceivedEventHandler del, bool waitForCallback, object state) { this.Bytes = bytes; this.Delegate = del; this.WaitForCallback = waitForCallback; + this.UserState = state; } /// @@ -383,6 +389,11 @@ public ConnectionState(byte[] bytes, ResponseReceivedEventHandler del, bool wait /// Indicates if the connection should wait for a callback after receiving the initial response. /// public bool WaitForCallback = false; + + /// + /// An optional state object that will be passed into the response events associated with this request + /// + public object UserState; } } } diff --git a/Growl/Growl.Connector/GrowlConnector.cs b/Growl/Growl.Connector/GrowlConnector.cs index 1a3e09e..5a0767a 100644 --- a/Growl/Growl.Connector/GrowlConnector.cs +++ b/Growl/Growl.Connector/GrowlConnector.cs @@ -16,14 +16,16 @@ public class GrowlConnector : ConnectorBase /// Represents methods that handle Growl responses /// /// The from Growl - public delegate void ResponseEventHandler(Response response); + /// An optional state object that will be passed into the response events associated with this request + public delegate void ResponseEventHandler(Response response, object state); /// /// Represents methods that handle Growl callbacks /// /// The from Growl /// The - public delegate void CallbackEventHandler(Response response, CallbackData callbackData); + /// An optional state object that will be passed into the response events associated with this request + public delegate void CallbackEventHandler(Response response, CallbackData callbackData, object state); /// /// Occurs when an 'OK' response is received. @@ -78,11 +80,31 @@ public GrowlConnector(string password, string hostname, int port) /// true if Growl is running; /// false if Growl is not running; /// + /// + /// This method is deprecated. Use the static IsGrowlRunningLocally() method instead. + /// + /// This method only detects if Growl is running on the local machine where this assembly is running. + /// It does not detect if Growl is running on a remote client machine, even if the GrowlConnector instance is + /// configured to point to a remote machine. + /// + [Obsolete("This method only detects if Growl is running on the local machine where this assembly is running. It does not detect if Growl is running on a remote client machine, even if the GrowlConnector instance is configured to point to a remote machine. Use the static IsGrowlRunningLocally() method instead.", false)] public bool IsGrowlRunning() { return Growl.CoreLibrary.Detector.DetectIfGrowlIsRunning(); } + /// + /// Detects if Growl is currently running on the local machine. + /// + /// + /// true if Growl is running; + /// false if Growl is not running; + /// + public static bool IsGrowlRunningLocally() + { + return Growl.CoreLibrary.Detector.DetectIfGrowlIsRunning(); + } + /// /// Registers the specified application and notification types. /// @@ -90,7 +112,18 @@ public bool IsGrowlRunning() /// The s to register. public virtual void Register(Application application, NotificationType[] notificationTypes) { - Register(application, notificationTypes, null); + Register(application, notificationTypes, null, null); + } + + /// + /// Registers the specified application and notification types. + /// + /// The to register. + /// The s to register. + /// An optional state object that will be passed into the response events associated with this request + public virtual void Register(Application application, NotificationType[] notificationTypes, object state) + { + Register(application, notificationTypes, null, state); } /// @@ -100,6 +133,18 @@ public virtual void Register(Application application, NotificationType[] notific /// The s to register. /// The containing the additional information. public virtual void Register(Application application, NotificationType[] notificationTypes, RequestData requestData) + { + Register(application, notificationTypes, requestData, null); + } + + /// + /// Registers the specified application and notification types and allows for additional request data. + /// + /// The to register. + /// The s to register. + /// The containing the additional information. + /// An optional state object that will be passed into the response events associated with this request + public virtual void Register(Application application, NotificationType[] notificationTypes, RequestData requestData, object state) { HeaderCollection appHeaders = application.ToHeaders(); List notifications = new List(); @@ -136,7 +181,7 @@ public virtual void Register(Application application, NotificationType[] notific mb.AddMessageSection(ms); } - Send(mb, OnResponseReceived, false); + Send(mb, OnResponseReceived, false, state); } /// @@ -148,6 +193,16 @@ public virtual void Notify(Notification notification) Notify(notification, null, null); } + /// + /// Sends a notification to Growl. + /// + /// The to send. + /// An optional state object that will be passed into the response events associated with this request + public virtual void Notify(Notification notification, object state) + { + Notify(notification, null, null, state); + } + /// /// Sends a notification to Growl and allows for additional request data. /// @@ -155,7 +210,18 @@ public virtual void Notify(Notification notification) /// The containing the additional information. public virtual void Notify(Notification notification, RequestData requestData) { - Notify(notification, null, requestData); + Notify(notification, null, requestData, null); + } + + /// + /// Sends a notification to Growl and allows for additional request data. + /// + /// The to send. + /// The containing the additional information. + /// An optional state object that will be passed into the response events associated with this request + public virtual void Notify(Notification notification, RequestData requestData, object state) + { + Notify(notification, null, requestData, state); } /// @@ -165,16 +231,39 @@ public virtual void Notify(Notification notification, RequestData requestData) /// The containing the callback information. public virtual void Notify(Notification notification, CallbackContext callbackContext) { - Notify(notification, callbackContext, null); + Notify(notification, callbackContext, null, null); } /// - /// Sends a notification to Growl that specifies callback information and allows for additional request data. + /// Sends a notification to Growl that specifies callback information. + /// + /// The to send. + /// The containing the callback information. + /// An optional state object that will be passed into the response events associated with this request + public virtual void Notify(Notification notification, CallbackContext callbackContext, object state) + { + Notify(notification, callbackContext, null, state); + } + + /// + /// Sends a notification to Growl that specifies callback information. /// /// The to send. /// The containing the callback information. /// The containing the additional information. public virtual void Notify(Notification notification, CallbackContext callbackContext, RequestData requestData) + { + Notify(notification, callbackContext, requestData, null); + } + + /// + /// Sends a notification to Growl that specifies callback information and allows for additional request data. + /// + /// The to send. + /// The containing the callback information. + /// The containing the additional information. + /// An optional state object that will be passed into the response events associated with this request + public virtual void Notify(Notification notification, CallbackContext callbackContext, RequestData requestData, object state) { bool waitForCallback = false; HeaderCollection notificationHeaders = notification.ToHeaders(); @@ -209,25 +298,26 @@ public virtual void Notify(Notification notification, CallbackContext callbackCo } } - Send(mb, OnResponseReceived, waitForCallback); + Send(mb, OnResponseReceived, waitForCallback, state); } /// /// Parses the response and raises the appropriate event /// /// The raw GNTP response - protected override void OnResponseReceived(string responseText) + /// An optional state object that will be passed into the response events associated with this request + protected override void OnResponseReceived(string responseText, object state) { CallbackData cd; MessageParser mp = new MessageParser(); Response response = mp.Parse(responseText, out cd); if (response.IsCallback) - this.OnNotificationCallback(response, cd); + this.OnNotificationCallback(response, cd, state); else if (response.IsOK) - this.OnOKResponse(response); + this.OnOKResponse(response, state); else - this.OnErrorResponse(response); + this.OnErrorResponse(response, state); } /// @@ -237,20 +327,22 @@ protected override void OnResponseReceived(string responseText) /// 3. Read request fails /// /// The that contains information about the failure - protected override void OnCommunicationFailure(Response response) + /// An optional state object that will be passed into the response events associated with this request + protected override void OnCommunicationFailure(Response response, object state) { - this.OnErrorResponse(response); + this.OnErrorResponse(response, state); } /// /// Called when an 'OK' response occurs. /// /// The - protected void OnOKResponse(Response response) + /// An optional state object that will be passed into the response events associated with this request + protected void OnOKResponse(Response response, object state) { if (this.OKResponse != null) { - this.OKResponse(response); + this.OKResponse(response, state); } } @@ -258,11 +350,12 @@ protected void OnOKResponse(Response response) /// Called when an 'ERROR' response occurs. /// /// The - protected void OnErrorResponse(Response response) + /// An optional state object that will be passed into the response events associated with this request + protected void OnErrorResponse(Response response, object state) { if (this.ErrorResponse != null) { - this.ErrorResponse(response); + this.ErrorResponse(response, state); } } @@ -271,11 +364,12 @@ protected void OnErrorResponse(Response response) /// /// The /// The - protected void OnNotificationCallback(Response response, CallbackData callbackData) + /// An optional state object that will be passed into the response events associated with this request + protected void OnNotificationCallback(Response response, CallbackData callbackData, object state) { if (callbackData != null && callbackData.Data != null && this.NotificationCallback != null) { - this.NotificationCallback(response, callbackData); + this.NotificationCallback(response, callbackData, state); } } } diff --git a/Growl/Growl.Connector/Response.cs b/Growl/Growl.Connector/Response.cs index 2772750..11e3277 100644 --- a/Growl/Growl.Connector/Response.cs +++ b/Growl/Growl.Connector/Response.cs @@ -14,6 +14,9 @@ public class Response : Error /// private bool isOK; + /// + /// Indicates what type of request this is in response to + /// private string inResponseTo; /// @@ -21,6 +24,11 @@ public class Response : Error /// private CallbackData callbackData; + /// + /// Contains the returned + /// + private RequestData requestData; + /// /// Creates a new instance of the class, /// setting the IsOK property to true. @@ -120,6 +128,18 @@ public string InResponseTo } } + /// + /// Gets the associated with this transaction + /// + /// + public RequestData RequestData + { + get + { + return this.requestData; + } + } + /// /// Sets the for this response /// @@ -207,6 +227,8 @@ internal void SetAttributesFromHeaders(HeaderCollection headers, bool isCallback this.callbackData = callbackData; } + this.requestData = RequestData.FromHeaders(headers); + SetInhertiedAttributesFromHeaders(this, headers); } } diff --git a/Growl/Growl.Daemon/CallbackInfo.cs b/Growl/Growl.Daemon/CallbackInfo.cs index 4285b36..c264b7e 100644 --- a/Growl/Growl.Daemon/CallbackInfo.cs +++ b/Growl/Growl.Daemon/CallbackInfo.cs @@ -48,7 +48,9 @@ public class CallbackInfo /// private Dictionary additionalInfo; - // TODO: see below + /// + /// Represents metadata about a received request such as when it was received, by whom, etc. + /// private RequestInfo requestInfo; @@ -130,8 +132,20 @@ internal Dictionary AdditionalInfo } } - // TODO: figure out if this really should be in here or not - public RequestInfo RequestInfo; + /// + /// Represents metadata about a received request such as when it was received, by whom, etc. + /// + public RequestInfo RequestInfo + { + get + { + return this.requestInfo; + } + set + { + this.requestInfo = value; + } + } /// /// Indicates if the server should keep the connection open to perform the callback diff --git a/Growl/Growl.Daemon/GrowlServer.cs b/Growl/Growl.Daemon/GrowlServer.cs index aa00607..d97b0ba 100644 --- a/Growl/Growl.Daemon/GrowlServer.cs +++ b/Growl/Growl.Daemon/GrowlServer.cs @@ -866,27 +866,45 @@ void mh_SocketUsageComplete(AsyncSocket socket) } } - // ------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------- + #region Logging + + /// + /// Log an informational message + /// + /// The format string. + /// The values to log. private void LogInfo(String format, params Object[] args) { String msg = String.Format(format, args); Log(LogMessageType.Information, msg); } + /// + /// Log an error message + /// + /// The format string. + /// The values to log. private void LogError(String format, params Object[] args) { String msg = String.Format(format, args); Log(LogMessageType.Error, msg); } + /// + /// Log data received or sent + /// + /// The data to log private void LogData(String msg) { Log(LogMessageType.Data, msg); } + /// + /// Fires the event so calling code can handle the logging events + /// + /// The type of message being logged. + /// The log message. private void Log(LogMessageType type, string message) { if (this.ServerMessage != null) @@ -895,13 +913,29 @@ private void Log(LogMessageType type, string message) } } + /// + /// The type of log message + /// public enum LogMessageType { + /// + /// Informational + /// Information, + + /// + /// Raw data sent or received + /// Data, + + /// + /// Error + /// Error } + #endregion Logging + #region IDisposable Members /// diff --git a/Growl/Growl.Daemon/MessageHandler.cs b/Growl/Growl.Daemon/MessageHandler.cs index 5e206db..ff6681a 100644 --- a/Growl/Growl.Daemon/MessageHandler.cs +++ b/Growl/Growl.Daemon/MessageHandler.cs @@ -122,11 +122,6 @@ public class MessageHandler /// private bool loggingEnabled; - /// - /// Indicates if local requests must supply a password - /// - private bool requireLocalPassword; - /// /// Indicates if remote notifications are allowed /// @@ -291,7 +286,7 @@ static MessageHandler() /// /// Name of the server /// A list of valid passwords - /// Indicates if the request must contain a password + /// Indicates if the request must contain a password /// The path to the folder where log files are written /// Indicates if logging is enabled or not /// Indicates if notifications from remote machines are allowed @@ -304,7 +299,6 @@ public MessageHandler(string serverName, PasswordManager passwordManager, bool p this.passwordRequired = passwordRequired; this.logFolder = logFolder; this.loggingEnabled = loggingEnabled; - this.requireLocalPassword = requireLocalPassword; this.allowNetworkNotifications = allowNetworkNotifications; this.allowFlash = allowFlash; this.allowSubscriptions = allowSubscriptions; diff --git a/Growl/Growl.Daemon/Properties/AssemblyInfo.cs b/Growl/Growl.Daemon/Properties/AssemblyInfo.cs index 771f718..88e7b61 100644 --- a/Growl/Growl.Daemon/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Daemon/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl.Daemon/SubscriptionConnector.cs b/Growl/Growl.Daemon/SubscriptionConnector.cs index 77a0946..0784702 100644 --- a/Growl/Growl.Daemon/SubscriptionConnector.cs +++ b/Growl/Growl.Daemon/SubscriptionConnector.cs @@ -135,14 +135,15 @@ private void RenewSubscription() mb.AddHeader(header); } - Send(mb, OnResponseReceived, false); + Send(mb, OnResponseReceived, false, null); } /// /// Parses the response and raises the appropriate event /// /// The raw GNTP response - protected override void OnResponseReceived(string responseText) + /// An optional state object that will be passed into the response events associated with this request + protected override void OnResponseReceived(string responseText, object state) { CallbackData cd; HeaderCollection headers; @@ -180,7 +181,8 @@ private void ResetTimerBasedOnResponse(SubscriptionResponse sr) /// 3. Read request fails /// /// The that contains information about the failure - protected override void OnCommunicationFailure(Response response) + /// An optional state object that will be passed into the response events associated with this request + protected override void OnCommunicationFailure(Response response, object state) { SubscriptionResponse sr = SubscriptionResponse.FromResponse(response, null); ResetTimerBasedOnResponse(sr); diff --git a/Growl/Growl.Destinations/Properties/AssemblyInfo.cs b/Growl/Growl.Destinations/Properties/AssemblyInfo.cs index 0d393b2..3798e94 100644 --- a/Growl/Growl.Destinations/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Destinations/Properties/AssemblyInfo.cs @@ -33,6 +33,6 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] [assembly: NeutralResourcesLanguageAttribute("en-US")] \ No newline at end of file diff --git a/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs b/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs index 8b10d7a..69913e3 100644 --- a/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs +++ b/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs index 36baa28..37dd981 100644 --- a/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs index 62bba65..b8370f3 100644 --- a/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs index b8caa65..89064f0 100644 --- a/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs index b959546..ce3c012 100644 --- a/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs b/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs index 1c50a19..de97695 100644 --- a/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs +++ b/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] diff --git a/Growl/Growl/Properties/AssemblyInfo.cs b/Growl/Growl/Properties/AssemblyInfo.cs index d703b39..b8a02c8 100644 --- a/Growl/Growl/Properties/AssemblyInfo.cs +++ b/Growl/Growl/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ // Revision // [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.3.5")] -[assembly: AssemblyInformationalVersion("2.0.3")] +[assembly: AssemblyFileVersion("2.0.4.1")] +[assembly: AssemblyInformationalVersion("2.0.4")] [assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/Growl/Growl/_source/Controller.cs b/Growl/Growl/_source/Controller.cs index 51f19cc..18f9d04 100644 --- a/Growl/Growl/_source/Controller.cs +++ b/Growl/Growl/_source/Controller.cs @@ -812,19 +812,26 @@ Growl.Daemon.SubscriptionResponse gntpListener_SubscribeReceived(Growl.Daemon.Su { bool alertUser = true; int ttl = Properties.Settings.Default.SubscriptionTTL; - SubscribedForwardDestination subscribedComputer = new SubscribedForwardDestination(subscriber, ttl); - subscribedComputer.Unsubscribed += new SubscribedForwardDestination.SubscribingComputerUnscubscribedEventHandler(sfc_Unsubscribed); - if (this.forwards.ContainsKey(subscribedComputer.Key)) + + SubscribedForwardDestination subscribedComputer = null; + if (this.forwards.ContainsKey(subscriber.ID)) { - ForwardDestination fc = this.forwards[subscribedComputer.Key]; - SubscribedForwardDestination sfc = fc as SubscribedForwardDestination; - if (sfc != null) + ForwardDestination fc = this.forwards[subscriber.ID]; + subscribedComputer = fc as SubscribedForwardDestination; + if (subscribedComputer != null) { - subscribedComputer.Enabled = sfc.Enabled; alertUser = false; } } - AddForwardDestination(subscribedComputer); + + if (subscribedComputer == null) + { + subscribedComputer = new SubscribedForwardDestination(subscriber, ttl); + subscribedComputer.Unsubscribed += new SubscribedForwardDestination.SubscribingComputerUnscubscribedEventHandler(sfc_Unsubscribed); + AddForwardDestination(subscribedComputer); + } + + subscribedComputer.Renew(); if (alertUser) { @@ -1304,6 +1311,7 @@ void subscription_StatusChanged(Subscription subscription) void sfc_Unsubscribed(SubscribedForwardDestination sfc) { + RemoveForwardDestination(sfc); OnForwardDestinationsUpdated(); } diff --git a/Growl/Growl/_source/Forwarder.cs b/Growl/Growl/_source/Forwarder.cs index 72fee19..2773be7 100644 --- a/Growl/Growl/_source/Forwarder.cs +++ b/Growl/Growl/_source/Forwarder.cs @@ -45,7 +45,7 @@ protected void OnForwardedNotificationCallback(Growl.Connector.Response response } } - void Forwarder_NotificationCallback(Response response, CallbackData callbackData) + void Forwarder_NotificationCallback(Response response, CallbackData callbackData, object state) { this.OnForwardedNotificationCallback(response, callbackData); } diff --git a/Growl/Growl/_source/GNTPSubscription.cs b/Growl/Growl/_source/GNTPSubscription.cs index 07b6e0e..ff84b55 100644 --- a/Growl/Growl/_source/GNTPSubscription.cs +++ b/Growl/Growl/_source/GNTPSubscription.cs @@ -19,6 +19,9 @@ public class GNTPSubscription : Subscription, IDisposable [NonSerialized] private string subscriberID; + [NonSerialized] + private bool isSubscribing = false; + [NonSerialized] private bool disposed; @@ -129,8 +132,9 @@ public string SubscriptionPassword public override void Subscribe() { - if (this.Enabled) + if (this.Enabled && !this.isSubscribing) { + this.isSubscribing = true; if (this.subscriberID == null) this.subscriberID = Utility.MachineID; this.AdditionalDisplayInfo = "connecting..."; if (this.sc == null) @@ -159,6 +163,7 @@ public override void Kill() void sc_OKResponse(Growl.Daemon.SubscriptionResponse response) { + this.isSubscribing = false; string additionalInfo = (this.Enabled ? String.Format("TTL: {0}", response.TTL) : null); this.Platform = KnownDestinationPlatformType.FromString(response.PlatformName); ChangeStatus(true, additionalInfo); @@ -168,6 +173,7 @@ void sc_OKResponse(Growl.Daemon.SubscriptionResponse response) void sc_ErrorResponse(Growl.Daemon.SubscriptionResponse response) { + this.isSubscribing = false; string additionalInfo = (this.Enabled ? (response.ErrorCode == Growl.Connector.ErrorCode.NOT_AUTHORIZED ? "invalid password" : "server unavailable") : null); ChangeStatus(false, additionalInfo); diff --git a/Growl/Growl/_source/SubscribedForwardDestination.cs b/Growl/Growl/_source/SubscribedForwardDestination.cs index f740e57..5905408 100644 --- a/Growl/Growl/_source/SubscribedForwardDestination.cs +++ b/Growl/Growl/_source/SubscribedForwardDestination.cs @@ -51,7 +51,7 @@ private SubscribedForwardDestination(string name, bool enabled, string ipAddress this.ttl = ttl; base.AdditionalDisplayInfo = "subscribed"; - this.Renew(); + //this.Renew(); } public int TTL @@ -101,6 +101,8 @@ public void Renew() void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // if the timer ticks, then we did not renew in time + this.timer.Stop(); + this.available = false; this.IPAddress = null; // this makes the computer unavailable diff --git a/Growl/Growl/release_notes.txt b/Growl/Growl/release_notes.txt index e652244..e7ea6e1 100644 --- a/Growl/Growl/release_notes.txt +++ b/Growl/Growl/release_notes.txt @@ -1,6 +1,10 @@ 2.0.4 changes (v2.0.4.x) ------------------------------ - fixed a bug in GrowlConnector that could cause a hang if the connection was lost in the middle of receiving a response +- deprecated instance method GrowlConnector.IsGrowlRunning(); replaced with static GrowlConnector.IsGrowlRunningLocally() +- updated GrowlConnector Register and Notify methods to accept a user-defined 'state' object that will get passed back in the response events (used to associate responses with requests) +- updated Growl.Connector.Response class to include RequestData property (that data was formerly inaccessible from the response) +- improvements to subscriptions to reduce number of renewal requests and updates of the UI 2.0.3v2 changes (v2.0.3.5) diff --git a/Growl/Test App/Form1.cs b/Growl/Test App/Form1.cs index c709b7e..30b19ba 100644 --- a/Growl/Test App/Form1.cs +++ b/Growl/Test App/Form1.cs @@ -62,17 +62,19 @@ public Form1() } } - void growl_ErrorResponse(Response response) + void growl_ErrorResponse(Response response, object state) { InvokeWrite("Error - " + response.ErrorCode + " : " + response.ErrorDescription); } - void growl_OKResponse(Response response) + void growl_OKResponse(Response response, object state) { + if (state != null) InvokeWrite(state.ToString()); + InvokeWrite("OK - " + response.MachineName); } - void growl_NotificationCallback(Response response, CallbackData callbackContext) + void growl_NotificationCallback(Response response, CallbackData callbackContext, object state) { string s = String.Format("CALLBACK RECEIVED: {0} - {1} - {2} - {3}", callbackContext.NotificationID, callbackContext.Data, callbackContext.Type, callbackContext.Result); InvokeWrite(s); @@ -134,7 +136,7 @@ private void button1_Click(object sender, EventArgs e) try { - growl.Register(this.app, types, rd); + growl.Register(this.app, types, rd, "some_user_state_data"); this.textBox1.Text = "REGISTER sent"; } catch (Exception ex)