2017-11-23 1 views
1

Verwendung der Server-Ereignisse-Funktion von ServiceStack Ich kann zwei Browser synchronisieren, wenn keine herkunftsübergreifenden HTTP-Anfragen beteiligt sind. Es funktioniert so einfach wie dokumentiert:ServiceStack SSE gibt ERR_INVALID_CHUNKED_ENCODING in Chrome, wenn CORS

(1) Plugins.Add (new ServerEventsFeature());

(2) Ein SyncRequest Endpunkt:

[Route("/channels/{Channel}/sync", "POST")] 
    public class SyncRequest : IReturnVoid 
    { 
     public string From { get; set; } 
     public string ToUserId { get; set; } 
     public string Channel { get; set; } 
     public string Message { get; set; } 
     public string Selector { get; set; } 
    } 
    public class SyncService : Service 
    { 
     public IServerEvents ServerEvents { get; set; } 

     public void Any(SyncRequest request) 
     { 
      ServerEvents.NotifyChannel(request.Channel, "sync", request.From); 
     } 
    } 

(3) Im Browser:

var mychannel = 'example'; 
    var source= new EventSource(`${serviceUrl}/event-stream?channel={mychannel}`); 
    source.onmessage = (m) => {}; // etc. 

Damit ich den Browser durch den Aufruf den SyncRequest Endpunkts (in einem Browser) und die Verarbeitung synchronisieren die Nachricht, die im anderen Browser aus der EventSource kommt.

jedoch, wenn der Sync-Server in einer anderen Domäne ist und Cross-Origin-HTTP-Anforderungen benötigt, versagt es. Plugins.Add(new CorsFeature(...)) scheint nach einer Weile zu funktionieren, aber in Chrome (unter Linux) sehe ich zuerst ERR_INVALID_CHUNKED_ENCODING Fehler in der Konsole.

Im Internet sehe ich Ansprüche, dass Chrome streng wr.t. Chunked-Codierung und das kann diese Fehler ERR_INVALID_CHUNKED_ENCODING verursachen. Ich sehe auch, dass die Antwort auf die/Event-Stream-Anruf hat eine Transfer-Encoding:chunked Header, aber ich weiß nicht, ob dies tatsächlich die Ursache ist und wenn ja, wie man es loswerden.

In another question on ServiceStack's SSE plus CORSmythz legt nahe, dass Response-Header wie so geändert werden können:

Plugins.Add(new ServerEventsFeature { 
     OnInit = request => { 
      request.Response.AddHeader("Transfer-Encoding", "identity"); 
     }, 
     OnHeartbeatInit = request => { 
      request.Response.AddHeader("Transfer-Encoding", "identity"); 
     } 
    }); 

aber dies hat keinen Einfluss auf die /event-stream?channel=example Anruf - seine Antwort-Header enthalten Transfer-Encoding:chunked (und der Herzschlag hat Transfer-Encoding:identity Standard).

Jetzt versucht der Browser, die Verbindung wiederherzustellen /event-stream?channel=example und das erste Mal, wenn es gelingt, sind wir gut - die EventSource-Objekte funktionieren, die Herzschläge passieren, und die Synchronisierung ist möglich.

Ich verwende ServiceStack/4.512 NET45 Unix/Mono.

Die Frage ist also: Gibt es eine Möglichkeit, sofort eine SSE-Verbindung ohne die ERR_INVALID_CHUNKED_ENCODING Fehler zu etablieren? Vielleicht hat ServiceStack die common error referred to in another question?

Antwort

1

Chunked Transfer-Encoding ist normal für die lange laufende HTTP-Antwort von Server Sent Events, bei der die Länge nicht bekannt ist. Das Problem ist wahrscheinlich in Monos HTTP-Implementierung zu suchen. Wenn Sie unter Linux/OSX laufen, wird empfohlen, stattdessen run ServiceStack on .NET Core zu verwenden, was die unterstützte Option ist.

+0

Ein neuer Browser, der sich auf den Kanal einstellt, löst eine Nachricht auf dem Kanal aus, die fälschlicherweise unterbrochen wird und andere eingestellte Browser stört. Im Falle mehrerer Browser, die auf denselben Kanal eingestellt sind, kann ich sehen, wie sie kämpfen zurück auf ihren Füßen, potenziell stören andere, nicht in der Lage, eine Sync-Anfrage zu senden/zu empfangen. Es gibt jedoch Hoffnung, da die Synchronisierung POST-Anforderung, die NotifyChannel aufruft, die ganze Zeit einwandfrei funktioniert. Irgendwie schafft es NotifyChannel, eine richtig chunked Nachricht zu senden, während onConnect das nicht tut. Sicherlich muss es einen Weg geben, das zu beheben! –

+0

@AlexZubrinsky Transfer-Encoding-Antworten werden nicht vom Framework generiert. Sie werden implizit von der zugrunde liegenden Webplattform hinzugefügt, wenn die Request-Länge nicht ermittelt werden kann. Die Lösung ist, wenn Sie Mono verwenden, um zu .NET Core zu migrieren. Monos ASP.NET-Implementierung ist fehlerhaft und niemand hat sie unterstützt. – mythz

+0

Danke! Wir werden sicher irgendwann auf .NET Core landen. –