diff --git a/SignalR/Connection.cs b/SignalR/Connection.cs index 5da405fb55..36dd9e7b8c 100644 --- a/SignalR/Connection.cs +++ b/SignalR/Connection.cs @@ -100,14 +100,14 @@ private List ProcessResults(IList source) var messageValues = new List(); foreach (var message in source) { - SignalCommand command; - if (SignalCommand.TryGetCommand(message, _serializer, out command)) + if (SignalCommand.IsCommand(message)) { + var command = WrappedValue.Unwrap(message.Value, _serializer); ProcessCommand(command); } else { - messageValues.Add(message.Value); + messageValues.Add(WrappedValue.Unwrap(message.Value, _serializer)); } } return messageValues; @@ -131,7 +131,7 @@ private void ProcessCommand(SignalCommand command) private Task SendMessage(string key, object value) { - return _messageBus.Send(key, value).Catch(); + return _messageBus.Send(key, new WrappedValue(value, _serializer)).Catch(); } private void PopulateResponseState(PersistentResponse response) diff --git a/SignalR/MessageBus/WrappedValue.cs b/SignalR/MessageBus/WrappedValue.cs new file mode 100644 index 0000000000..026e67f221 --- /dev/null +++ b/SignalR/MessageBus/WrappedValue.cs @@ -0,0 +1,54 @@ +namespace SignalR.MessageBus +{ + /// + /// All values saved to the messages store are wrapped by this type. + /// If a store needs to save values in a serializable way then it just needs to call + /// ToString() and we'll unwrap it when it comes back (if needed). + /// + internal class WrappedValue + { + private readonly IJsonSerializer _serializer; + private readonly object _value; + + public WrappedValue(object value, IJsonSerializer serializer) + { + _value = value; + _serializer = serializer; + } + + public object Value + { + get + { + return _value; + } + } + + public static T Unwrap(object value, IJsonSerializer serializer) + { + var wrappedValue = value as WrappedValue; + if (wrappedValue != null) + { + return (T)wrappedValue.Value; + } + + return serializer.Parse((string)value); + } + + public static object Unwrap(object value, IJsonSerializer serializer) + { + var wrappedValue = value as WrappedValue; + if (wrappedValue != null) + { + return wrappedValue.Value; + } + + return serializer.Parse((string)value); + } + + public override string ToString() + { + return _serializer.Stringify(_value); + } + } +} diff --git a/SignalR/SignalCommand.cs b/SignalR/SignalCommand.cs index 92df7e65e8..b1af7ebf31 100644 --- a/SignalR/SignalCommand.cs +++ b/SignalR/SignalCommand.cs @@ -1,4 +1,5 @@ using System; +using SignalR.MessageBus; namespace SignalR { @@ -11,31 +12,9 @@ internal static string AddCommandSuffix(string eventKey) return eventKey + "." + SignalrCommand; } - internal static bool TryGetCommand(Message message, IJsonSerializer serializer, out SignalCommand command) + public static bool IsCommand(Message message) { - command = null; - if (!message.SignalKey.EndsWith(SignalrCommand, StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - command = message.Value as SignalCommand; - - // Optimization for in memory message store - if (command != null) - { - return true; - } - - // Otherwise deserialize the message value - string rawValue = message.Value as string; - if (rawValue == null) - { - return false; - } - - command = serializer.Parse(rawValue); - return true; + return message.SignalKey.EndsWith(SignalrCommand, StringComparison.OrdinalIgnoreCase); } public CommandType Type { get; set; } diff --git a/SignalR/SignalR.csproj b/SignalR/SignalR.csproj index 2bd4a2ea00..e5a9243f0d 100644 --- a/SignalR/SignalR.csproj +++ b/SignalR/SignalR.csproj @@ -59,6 +59,7 @@ +