Czy wydajność jest jedynym powodem, dla którego nie należy używać SignalR (gniazd sieciowych) zamiast tradycyjnego interfejsu API REST?


42

Użyłem SignalRdo osiągnięcia funkcjonalności wiadomości w czasie rzeczywistym, w kilku z moich projektów. Wydaje się, że działa niezawodnie i jest bardzo łatwy do nauczenia się obsługi.

Pokusa, przynajmniej dla mnie, to rezygnacja z rozwijania usługi Web API i używanie jej SignalRdo wszystkiego.

Wydaje mi się, że można to osiągnąć dzięki przemyślanemu projektowi, a gdyby tak było, oznaczałoby to znacznie mniej kodu klienta. Co ważniejsze, oznaczałoby to, że istniałby pojedynczy interfejs do usług, a nie podzielony interfejs, aw najgorszym przypadku można to połączyć bez zastanawiania się, kiedy rzeczy się renderują itp.

Chciałbym wiedzieć:

  1. Czy jest jakiś inny powód, aby nie używać SignalR zamiast wszystkich usług sieciowych oprócz wydajności?
  2. Czy wydajność SignalR w wystarczającym stopniu dotyczy tego, że nie miałoby to sensu?

Od dawna moim marzeniem była możliwość tłumaczenia definicji obiektów i usług po stronie serwera na kod dostępu do usług po stronie klienta bez czegoś niemądrego node.js. Na przykład, jeśli zdefiniuję interesujący obiekt InterestingObjecti usługę do CRUDobiektu InterestingObjectService, mogę zdefiniować standardową trasę URL do usługi - powiedzmy „/ {nazwa_usługi} / {nazwa_metody}” - ale nadal muszę napisać kod klienta, aby uzyskać dostęp usługi. Ponieważ obiekt ma być przekazany od klienta do serwera iz powrotem, nie ma praktycznego powodu, aby miećdo jawnego zdefiniowania obiektu w kodzie klienta, nie powinno też być potrzeby jawnego definiowania tras wykonywania operacji CRUD. Wydaje mi się, że powinien istnieć sposób na ujednolicenie tego wszystkiego, aby można było napisać klienta przy założeniu, że dostęp do usługi działa od klienta do serwera iz powrotem tak transparentnie, jak w przypadku pisania WinForms lub Java Applet lub Native App lub co masz.

Jeśli SignalR jest wystarczająco dobry, aby używać go zamiast tradycyjnej usługi internetowej, może to być realnym sposobem na osiągnięcie tego. SignalR zawiera już funkcjonalność, dzięki której hub może działać tak, jak opisywana usługa, więc mogłem zdefiniować wspólną usługę podstawową (CRUD), która oferowałaby całą tę funkcjonalność od razu po wyjęciu z pudełka z pewnymi refleksjami. Wtedy mógłbym prawie uznać za pewny dostęp do usługi, oszczędzając mi irytujące ponowne pisanie kodu, aby uzyskać dostęp do czegoś, co może być dostępne na podstawie konwencji - a co ważniejsze, czas, który musiałbym poświęcić na pisanie kodu, aby określić, w jaki sposób jest on aktualizowany w DOM.

Po przeczytaniu mojej edycji wydaje mi się, że może to być trochę nonsensowne, więc nie wahaj się zapytać mnie, jeśli masz pytania dotyczące tego, o co mi chodzi. Zasadniczo chcę, aby dostęp do usługi był jak najbardziej przejrzysty.


5
Jeśli masz magiczną kartę sieciową, która może pomieścić nieskończoną liczbę gniazd i magiczną sieć, która może obsłużyć nieskończoną ilość przepustowości, oraz magiczny serwer, który ma nieskończoną ilość pamięci i cykli procesora, to tylko gniazda sieciowe to świetny wybór!

Csla robi to, co chcesz, obiekty biznesowe mogą przenosić się między klientem a serwerem.
Andy

Odpowiedzi:


50

Te dwie technologie mają zupełnie inny cel.

  • REST służy do zwykłych wywołań interfejsu API, przy czym klient jest aktywnym uczestnikiem wymiany. Gdy klient musi znaleźć współrzędne GPS adresu, klient inicjuje połączenie do API i czeka aż otrzyma współrzędne, lub wystąpi błąd, lub upłynie limit czasu.

  • Gniazda sieciowe służą do wszystkiego, co musi robić rzeczy w drugą stronę. Na przykład, gdy korzystam z intranetowej witryny internetowej, która pokazuje mi w czasie rzeczywistym dzienniki i wydajność różnych serwerów, klient może być pasywny i czekać, aż serwer wyśle ​​mu nowo opublikowany komunikat dziennika lub wskaźniki wydajności.

Różnica jest wyraźna: w pierwszym przypadku klient decyduje, kiedy potrzebuje określonej informacji; w drugim przypadku klient po prostu czeka na kontakt i może nie wiedzieć, kiedy to nastąpi.

W pewnym sensie oba są wymienne: możesz zaimplementować gniazda sieciowe, kiedy ich nie potrzebujesz (tj. Klient zadzwoni do serwera przez gniazda sieciowe zamiast wywoływać połączenie REST) ​​i możesz użyć odpytywania lub długiego odpytywania jako zamiennika gniazda sieciowe (biorąc pod uwagę, że było to z powodzeniem używane przez lata, aż gniazda sieciowe stały się tak popularne).

Ale ich zamienność kosztuje:

  • Kiedy używasz odpytywania lub długiego odpytywania zamiast gniazd sieciowych, często marnujesz przepustowość.

  • Gdy używasz gniazd sieciowych do robienia tego, co można zrobić za pomocą interfejsu API, wszystkie połączenia ze wszystkich aktywnych klientów pozostają otwarte, co może nie być tym, czego naprawdę chcesz. W przypadku małej witryny, w której spodziewasz się mieć jednocześnie maksymalnie 5 klientów, nie stanowi to problemu. W przypadku usługi takiej jak Amazon AWS rozwiązanie techniczne nie byłoby łatwe.

Nie używaj gniazd sieciowych, kiedy ich nie potrzebujesz. Aby uzyskać współrzędne GPS adresu, nic nie zyskuję otwierając połączenie z gniazdami internetowymi, wykonując połączenie, czekając na odpowiedź i zamykając połączenie: REST zaspokaja moje potrzeby w takich sytuacjach.

  • Jeśli często i często sprawdzasz informacje za pośrednictwem połączenia REST z usługą, może to być dobry znak, że powinieneś przenieść się do gniazd sieciowych. Podobnie przepełnienie stosu zmniejsza wykorzystanie przepustowości za pomocą gniazd sieciowych, ponieważ pomaga ludziom nie tracić czasu, naciskając F5 na stronie głównej, aby sprawdzić, czy mają nowe wiadomości.

  • Jeśli okaże się, że otwierasz połączenia z gniazdami internetowymi, użyj ich, aby wykonać pojedyncze połączenie, a następnie zamknij je, lub jeśli połączenia pozostają otwarte, ale serwer wysyła coś do klienta tylko na żądanie klienta, przełącz się na REST.

Ponadto gniazda sieciowe mają nadal ograniczone wsparcie i nie zawsze są łatwe do wdrożenia. Chociaż SignalR ułatwia implementację, nie oznacza to, że nie będziesz mieć trudności z implementacją go w innych językach / kontekstach / środowiskach. Dzięki REST jest to łatwe: może to być curlpołączenie lub podobna funkcja dostępna w każdym języku głównego nurtu. Dzięki gniazdom internetowym nie masz pewności, ile czasu zajmie stworzenie klienta przy użyciu [wstaw nazwę nieznanego Ci języka].

Użyłem gniazd sieciowych w kilku projektach w .NET, Python i node.js.

  • W .NET nie było to zbyt trudne, ale wciąż spędziłem kilka dni, próbując rozwiązać niektóre tajemnicze problemy, takie jak połączenie zerwane, gdy tylko zostało otwarte. (To było przed SignalR; nigdy nie próbowałem SignalR). Użyłem również WCF w trybie gniazd sieciowych, co również nie było bez problemów (ale uważam, że WCF zawsze ma problemy).

  • W node.js było to wykonalne, ale musiałem dwukrotnie przełączać biblioteki, aż znalazłem taką, która działa. Wydaje mi się, że spędziłem przynajmniej tydzień na tworzeniu gniazd sieciowych Hello World.

  • W Pythonie spróbowałem raz, spędziłem dwa lub trzy dni i porzuciłem. To nigdy nie działało.

Porównaj to z REST: jedynymi problemami, jakie można napotkać w nowym języku / frameworku, jest wiedza na temat POST plików lub otrzymania bardzo dużej odpowiedzi binarnej. Pamiętam, jak spędziłem kilka godzin na poszukiwaniu rozwiązań dla niektórych języków. Jednak kilka godzin na specjalną skrzynkę to nic w porównaniu z dniami lub tygodniami dla prostego Hello World.


2
Poprosiłem o odpowiedź, MainMa, ponieważ uznałem ją za interesującą / pomocną. Jest jednak jeden punkt, którego nie rozumiem. Wspominasz, że niewielka liczba klientów jest w stanie obsłużyć gniazda sieciowe (np. Maksymalnie 5 jednocześnie). Następnie wspominasz, że StackOverflow używa gniazd sieciowych na swojej stronie głównej. Jak sobie radzą z tak dużą liczbą użytkowników? Pytam, ponieważ próbuję ponad 20 połączeń SignalR i stwierdzam, że opóźnienia wiadomości powoli zaczynają się powiększać, zanim cała sprawa się zawiesi (wszystko nie odpowiada).
gnychis

1
@gnychis: istnieje na to wiele rozwiązań, ale wiele z nich jest bardziej związanych z samą infrastrukturą (po to jest serwerfault.com ). Ogólnie rzecz biorąc, rzuć więcej sprzętu i podziel użytkowników między domeny, aby niektóre połączenia były obsługiwane przez sockets1.example.com, inne przez sockets2.example.com itp. Dość skuteczny, ale również dość drogi pod względem sprzętu i przepustowości.
Arseni Mourzenko,

3
Ta odpowiedź jest doskonała, ale chciałbym zawęzić pierwotne pytanie. Jeśli aplikacja wymaga ciągłego połączenia websocket, to dlaczego nie używać websockets zamiast API REST? Ponieważ websocket jest otwarty, być może należy go w pełni wykorzystać.
HappyNomad

Właśnie znalazłem odpowiedź na moje własne pytanie.
HappyNomad

1

Tylko moje 2 centy ...

Myślę, że tak naprawdę nie chodzi o wydajność ani o cokolwiek innego. Chodzi o standardy. REST jest standardem, a IMHO ma następujące zalety:

  • Żądania HTTP są proste w użyciu. Każdy może szybko korzystać z interfejsu API REST. Cholera, możesz nawet otworzyć przeglądarkę i wpisać adres URL, aby zobaczyć dane. Jak bardziej możesz być interaktywny?
  • (Prawie) każdy język programowania może go używać. To rodzaj uniwersalnego interfejsu. Interakcja z SignalR z egzotycznego języka wydaje się mniej oczywista.
  • Ma ładne wsparcie narzędziowe, takie jak http://petstore.swagger.wordnik.com/
  • To ładny „interfejs” do debugowania. Możesz łatwo monitorować wiadomości przychodzące i wychodzące bezpośrednio w przeglądarce, przeglądać dane itp. Dzięki gniazdom internetowym i niestandardowym bibliotekom nie jest to tak oczywiste, że musisz jawnie rejestrować wszystko.

1
Podczas gdy podajesz kilka dobrych argumentów na temat tego, że interfejsy API REST są nieco prostsze i prawdopodobnie mają lepsze narzędzia, ta odpowiedź zawiera kilka rzeczy, które po prostu nie są prawdziwe. REST nie jest standardem , podczas gdy WebSockets jest .
StriplingWarrior

1
Wydaje mi się, że z mojej strony było to złe sformułowanie. To, co miałem na myśli przez „standard”, to powszechność, powszechność, domyślny sposób robienia rzeczy… a nie „bycie standardem RFC”.
Dagnelies

Dobre wyjaśnienie. Co więcej, Chrome przynajmniej pozwala zobaczyć ruch WebSockets w jego narzędziach programistycznych. Wyobrażam sobie, że prawdopodobnie także inne przeglądarki.
StriplingWarrior
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.