2013-08-02 13 views
15

Potrzebowałbym kilku wskazówek od programistów SignalR, jaki jest najlepszy sposób na ulepszenie serializacji parametrów HUB.Serializacja parametrów metody SignalR piasta

Rozpocząłem migrację mojego projektu z dupleksu odpytywania WCF (Silverlight 5 - ASP.NET 4.5) do SignalR (1.1.2). Komunikat (umowa danych) jest polimorficzny w oparciu o interfejsy. (Tak jak IMessage, MessageA: IMessage itp. - w rzeczywistości istnieje hierarchia interfejsów zaimplementowana przez klasy, ale nie ma ona większego znaczenia dla pytania). (Wiem, że obiekty polimorficzne nie są dobre dla klientów, ale klient będzie obsługiwał je jako JSON, a mapowanie do obiektów odbywa się tylko po stronie serwera lub klienta, jeśli jest .NET/Silverlight)

Na hoście zdefiniowałem taką metodę :

public void SendMessage(IMessage data) { .. } 

Stworzyłem niestandardowe JsonConverters i zweryfikowałem, że wiadomości mogą być serializowane/deserializowane za pomocą Json.NET. Następnie zastąpiłem JsonNetSerializer w DependencyResolver odpowiednimi ustawieniami. Podobnie po stronie klienta Silverlight. Jak na razie dobrze.

Ale kiedy wysłałem wiadomość od klienta do serwera (komunikat został spersonalizowany do JSON poprawnie - zweryfikowano w Fiddler), serwer zwrócił błąd, że parametru nie można przekształcić z postaci szeregowej. Z pomocą debuggera znalazłem błąd w SignalR (klasa JRawValue odpowiedzialna za deserializację parametru tworzy wewnętrznie własną instancję JsonSerializer ignorując podaną). Wydawało się, że dość łatwo naprawić poprzez zastąpienie

var settings = new JsonSerializerSettings 
{ 
    MaxDepth = 20 
}; 
var serializer = JsonSerializer.Create(settings); 
return serializer.Deserialize(jsonReader, type); 

z

var serializer = GlobalHost.DependencyResolver.Resolve<IJsonSerializer>(); 
return serializer.Parse(jsonReader, type); 

ale również, że Interfejs IJsonSerializer zostanie usunięta w przyszłej wersji SignalR. W zasadzie potrzebuję uzyskać surowy strumień JSON (lub strumień bajtów) z metody HUB, aby móc go przekształcić osobno lub możliwość modyfikacji serializatora przez określenie konwerterów itp.

Na razie skończyłem z określanie sposobu z JObject typu parametru:

public void SendMessage(JObject data) 

następnie ręczne deserializacji danych przez

JObject.ToObject<IMessage>(JsonSerializer) 

metody. Ale wolałbym zmodyfikować serializer i mieć typ/interfejs w metodzie piasty. Co to jest "właściwa droga", aby to zrobić w odniesieniu do projektowania następnego SignalR?

Okazało się również przydatna możliwość wysyłania do klientów surowego JSON z mojego kodu, tj. Aby obiekt nie był ponownie serializowany przez SignalR ponownie. Jak mogę to osiągnąć?

+0

dobre pytanie. Smutno, że nie widzę odpowiedzi. Interesuje mnie również wdrażanie polimorficznych umów na wiadomości. –

+0

Czy to pytanie jest nadal istotne w przypadku wersji 2.x? Przy wersji 2.x powinieneś być w stanie przekazać zaktualizowany 'DependencyResolver' do' HubConfiguration' dla wywołania 'app.MapSignalR (config)' –

Odpowiedz

0

Jeśli używasz interfejsu API połączenia zamiast interfejsu API, możesz obsłużyć zdarzenie OnReceive i otrzymać żądanie jako surowy JSON (ciąg). Spójrz na this example.

Możliwość wysyłania danych sprzed odcinkach do klientów korzystających Hub API została dodana w wersji 2.x, a ja nie wiem o żadnym to zrobić w 1.x (patrz github issue)