2015-06-15 25 views
7

Czytając here i patrząc na przykład here:Owin WebSockets - Zrozumienie IOwinContext i WebSocketAccept

Próbuję zrozumieć, co właściwie robi. WebSocketAccept faktycznie Wiem, że WebSocketAccept jest:

using WebSocketAccept = 
    Action 
    < 
     IDictionary<string, object>, // WebSocket Accept parameters 
     Func // WebSocketFunc callback 
     < 
      IDictionary<string, object>, // WebSocket environment 
      Task // Complete 
     > 
    >; 

i jest używany w ten sposób:

public void Configuration(IAppBuilder app) 
    { 
     app.Use(UpgradeToWebSockets); 
     app.UseWelcomePage(); 
    } 

    // Run once per request 
    private Task UpgradeToWebSockets(IOwinContext context, Func<Task> next) 
    { 
     WebSocketAccept accept = context.Get<WebSocketAccept>("websocket.Accept"); 
     if (accept == null) 
     { 
      // Not a websocket request 
      return next(); 
     } 

     accept(null, WebSocketEcho); 

     return Task.FromResult<object>(null); 
    } 

Więc co jest zaakceptować() actuallyt robi? Czy nazywa się właściwością WebConcaptor i czy jest zdefiniowana metoda WebSocketEcho? WebSocketEcho jest zdefiniowane jako:

private async Task WebSocketEcho(IDictionary<string, object> websocketContext) 

Skąd pochodzi websocketContext? Co jeśli chcielibyśmy przekazać to dalej w dół, gdy stwierdzimy, że jest to żądanie gniazda sieci?

Odpowiedz

3

Co to jest WebSocketAccept?

WebSocketAccept jest using alias

Przykład:

... 
using Foo.Bar 
using MyBar = Fee.Bar 
... 

Tutaj używamy barze od 2 różnych nazw, ale alias 2 jeden z „MyBar” więc możemy rozróżnić dwa.

Dlaczego używać aliasu jako WebSocketAccept?

Alias ​​w tym przypadku jest po prostu wygodą, więc nie trzeba pisać wszystkiego, co oznacza, że ​​zamiast pisać całą nazwę podczas używania, można zamiast tego użyć aliasu.

Zrozumienie WebSocketAccept

Jeśli spojrzymy bliżej widzimy, że jest to typ:

Action<A, B> 

Oznacza to, że zasadniczo jest to funkcja, która nie wraca i trwa 2 argumenty, w C# lambda:

(A, B) => { } 

Widzimy, że pierwszy argument (A) to: IDictionary<string, object>, który jest również znany jako środowisko Owin.

Drugi argument to (B) to: Func<C, D>, co oznacza, że ​​jest to funkcja, która pobiera C i zwraca D. W C# lambda:

(C) => { return D; } 

Następnie musimy zanurkować do pierwszego argumentu (C) drugiego argumentu (B). I widzimy, że to wymaga środowiska Owin i zwraca Task.

Co to jest akceptować?

accept próbuje wyodrębnić parametry z IOwinContext i zamapować je na typ WebSocketAccept.

Jeśli nie może ich wyodrębnić, jest to null i przechodzimy do następnego oprogramowania pośredniego.

W przeciwnym razie był to żądanie websocket i wywołujemy funkcję, która przyjmuje 2 parametry (WebSocketAccept), jak omówiliśmy powyżej (Action<A, B>).

Pierwszym parametrem jest zwykły słownik, który zawiera parametry akceptujące websocket.

Drugi parametr będący funkcją, która pobiera słownik i zwraca zadanie.

Ta funkcja jest wywoływana przez inną osobę, co oznacza kod przekazujący funkcję wywołania zwrotnego do wywołującego.

Wywołanie następnie wywołuje funkcję z poprawnym argumentem. Ponieważ dzwoniący zna sygnaturę funkcji. Funkcja nazywa się PO zaakceptowaniu żądania połączenia z Websocket. Stąd wywołanie zwrotne komentarza.

Co, jeśli chcielibyśmy przekazać to dalej w dół, gdy stwierdzimy, że jest to żądanie gniazda sieci Web?

Również w tym przykładzie, funkcja zwrotna jest WebSocketEcho ale zasadniczo można przejść w dowolnej funkcji, które spełnia funkcję podpis:

Task MyCallbackFunction(IDictionary<string, object> context) 
{ 
    // Do something 
    return Task.FromResult(0); 
} 

wynos jest to, że nie wywołać funkcji, funkcja jest dla ciebie wezwana. Określasz, że po negocjowaniu połączenia z gniazdem sieciowym decydujesz, co się stanie.

Funkcja WebSocketEcho jest wywoływana raz dla każdego klienta i wykonuje pętle, dopóki klient nie zdecyduje się zamknąć połączenia. Tymczasem odbija się echem, co otrzymuje.

Nota prawna: Ja też staram się tylko owijać głowę wokół gniazd internetowych i powiedzieć, że tak, ale chciałem podzielić się swoimi odkryciami dla potomności, ponieważ nikt nie odpowiedział na twoje pytanie. Z zadowoleniem przyjmuję wszelkie poprawki.

EDIT
zauważyłem z mojego własnego doświadczenia, że ​​jeśli wrócisz z funkcji zwrotnej, że połączenie websocketContext będzie Abort ed. Oznacza to, że nie można wysyłać/odbierać wiadomości na połączeniu, jeśli przekażemy numer websocketContext po zakończeniu wywołania zwrotnego.

UPDATE
Ostatnio starałem się to wykorzystać na R2 IIS 7.5 serwera Windows 2008 nie mogłem dostać websocket do pracy. Następnie zgodnie z tym: https://stackoverflow.com/a/14130152/1640121 - Serwer IIS 7.5 nie obsługuje gniazd internetowych.
Co oznacza, że ​​jeśli twoja aplikacja jest hostowana w IIS 7.5, nie będzie mogła mieć stron internetowych.

Następnie, że o możliwe rozwiązania

  1. pomocą oddzielnego stosowania, np program usługowy (spoza IIS), który obsługuje żądania websocket.
  2. Użyj reverse proxy mapować żądania do aplikacji usługowej

ten odczuwał zbyt uciążliwe dla mnie, co sprawiło mi odłożyć wdrożenie websocket do teraz ...

+1

otrzymuję 400 Bad Request podczas próby tego samego kodu. – Jigar