Является ли производительность единственной причиной не использовать SignalR (websockets) полностью вместо традиционного REST API?

42

Я использовал SignalRдля достижения функциональности обмена сообщениями в реальном времени в нескольких из моих проектов. Кажется, он работает надежно и очень прост в освоении.

Искушение, по крайней мере для меня, состоит в том, чтобы отказаться от разработки сервиса Web API и использовать его SignalRдля всего.

Я чувствую, что это может быть достигнуто продуманным дизайном, и если бы это было так, это означало бы, что гораздо меньше клиентского кода было бы необходимо. Что еще более важно, это будет означать, что будет один интерфейс для служб, а не разделенный интерфейс, и в худшем случае это можно будет подключить, не думая о том, когда что-то будет отображаться и т. Д.

Итак, я хотел бы знать:

  1. Есть ли какая-либо другая причина не использовать SignalR вместо всех веб-сервисов, кроме производительности?
  2. Достаточно ли производительности SignalR, что в этом нет смысла?

Я давно мечтал о том, чтобы иметь возможность переводить определения объектов и сервисов на стороне сервера в код доступа на стороне клиента без каких-либо глупостей node.js. Например, если я определяю интересный объект InterestingObjectи службу для CRUDобъекта InterestingObjectService, я могу определить стандартный URL-маршрут к службе - скажем, "/ {serviceName} / {methodName}" - но мне все еще нужно написать клиентский код для доступа сервис. Поскольку объект будет передаваться от клиента к серверу и обратно, нет практической причины иметьчтобы явно определять объект в коде на стороне клиента, также не должно быть необходимости явно определять маршруты для выполнения операций CRUD. Я чувствую, что должен быть способ стандартизировать все это так, чтобы можно было написать клиента при условии, что доступ к сервису работает от клиента к серверу и обратно так же прозрачно, как если бы я писал WinForms или Java Апплет или родное приложение или что у тебя.

Если SignalR достаточно хорош для использования вместо традиционного веб-сервиса, это может быть жизнеспособным способом для достижения этой цели. SignalR уже включает в себя функциональность, чтобы заставить хаб работать как сервис, который я описываю, поэтому я мог бы определить сервис с общей базой (CRUD), который предлагал бы всю эту функциональность "из коробки" с некоторым отражением. Тогда я мог почти принять как должный доступ к сервису, избавив меня от раздражения переписывания кода, чтобы получить доступ к чему-то, к чему можно получить доступ по соглашению - и что более важно, к тому времени, которое мне пришлось бы потратить на написание кода, чтобы определить, как это обновляется ДОМ.

После прочтения моего редактирования я чувствую, что это может быть немного бессмысленным, поэтому, пожалуйста, не стесняйтесь спрашивать меня, если у вас есть вопросы о том, что я получаю. По сути, я хочу, чтобы доступ к сервису был максимально прозрачным.

tacos_tacos_tacos
источник
5
Если у вас есть волшебная сетевая карта, которая может держать бесконечное количество сокетов, и волшебная сеть, которая может поддерживать бесконечное количество полосы пропускания, и волшебный сервер, имеющий бесконечное количество памяти и циклов ЦП, тогда только веб-сокеты - отличный выбор!
Csla делает то, что вы хотите, бизнес-объекты могут перемещаться между клиентом и сервером.
Энди

Ответы:

50

Эти две технологии имеют совершенно разные цели.

  • REST предназначен для обычных вызовов API, при этом клиент является активным участником обмена. Когда клиент должен найти координаты GPS по адресу, то клиент инициирует вызов к API и ждет , пока он не получит координаты, или в случае возникновения ошибки или тайм - аут истечет.

  • Веб-сокеты предназначены для всего, что нужно сделать противоположным образом. Например, когда я использую веб-сайт интрасети, который показывает мне в режиме реального времени журналы и производительность разных серверов, клиент может быть пассивным и ждать, пока сервер отправит ему недавно опубликованное сообщение журнала или показатели производительности.

Разница очевидна: в первом случае клиент решает, когда ему нужна конкретная часть информации; во втором случае клиент просто ждет, когда с ним свяжутся, и может не знать, когда это произойдет.

В некотором смысле оба они взаимозаменяемы: вы можете реализовать веб-сокеты, когда они вам не нужны (т. Е. Клиент будет вызывать сервер через веб-сокеты вместо вызова REST), и вы можете использовать опрос или длинный опрос в качестве замены веб-сокеты (учитывая, что это успешно использовалось в течение многих лет, пока веб-сокеты не стали настолько популярными).

Но их взаимозаменяемость обходится дорого:

  • Когда вы используете опрос или длинный опрос вместо веб-сокетов, вы часто теряете пропускную способность.

  • Когда вы используете веб-сокеты, чтобы делать то, что можно сделать через веб-интерфейс API, вы сохраняете все соединения со всех активных клиентов открытыми, что может не соответствовать вашим ожиданиям. Для небольшого веб-сайта, на котором вы ожидаете не более 5 клиентов одновременно, это не проблема. Для такой службы, как Amazon AWS, это будет нелегко решить технически.

Не используйте веб-сокеты, когда они вам не нужны. Чтобы получить GPS-координаты адреса, я ничего не получаю, открывая соединение через веб-сокеты, совершая звонок, ожидая ответа и закрывая соединение: REST удовлетворяет мои потребности в таких сценариях.

  • Если вы обнаружите, что регулярно и часто проверяете информацию через вызов REST в службу, это может быть хорошим признаком того, что вам следует перейти к веб-сокетам. Аналогично, переполнение стека уменьшает использование полосы пропускания за счет использования веб-сокетов, поскольку помогает людям не тратить свое время, нажимая клавишу F5 на домашней странице, чтобы узнать, есть ли у них новые сообщения.

  • Если вы обнаружите, что открываете соединения через веб-сокеты, используйте их для совершения одного вызова, а затем закройте их, или если ваши соединения остаются открытыми, но сервер отправляет что-то клиенту только по запросу клиента, переключитесь на REST.

Кроме того, веб-сокеты все еще имеют ограниченную поддержку и не всегда просты в реализации. Хотя SignalR облегчает реализацию, это не означает, что у вас не возникнет трудностей с ее реализацией в других языках / контекстах / средах. С REST это легко: это может быть curlзвонок или аналогичная функция, доступная на любом основном языке. С веб-сокетами вы не можете быть уверены, сколько времени потребуется, чтобы сделать клиента с помощью [введите название языка, который вы еще не знаете здесь].

Я использовал веб-сокеты в нескольких проектах в .NET, Python и node.js.

  • В .NET это было не слишком сложно, но все же я потратил несколько дней, пытаясь выяснить некоторые загадочные проблемы, такие как обрыв соединения при его открытии. (Это было до SignalR; я никогда не пробовал SignalR). Я также использовал WCF в режиме веб-сокетов, что тоже не обошлось без проблем (но я считаю, что WCF всегда идет с проблемами).

  • В node.js это было выполнимо, но мне пришлось дважды переключать библиотеки, пока я не нашел ту, которая работает. Я считаю, что я потратил хотя бы неделю, пытаясь сделать веб-сокеты Hello World.

  • В Python я попробовал один раз, провел два или три дня и забросил. Это никогда не работало.

Сравните это с REST: единственные проблемы, с которыми можно столкнуться с новым языком / фреймворком, - это знать, как POST-файлы или получать очень большой двоичный ответ. Я помню, как провел несколько часов в поисках решений для некоторых языков. Тем не менее, несколько часов для особого случая - ничто по сравнению с днями или неделями для простого Hello World.

Арсений Мурзенко
источник
2
Подчеркнул ваш ответ, MainMa, так как я нашел его интересным / полезным. Есть один момент, который я не понимаю, хотя. Вы упомянули, что небольшое количество клиентов может работать с веб-сокетами (например, не более 5 одновременно). Затем вы упоминаете, что StackOverflow использует веб-сокеты на своей домашней странице. Как они справляются с таким большим количеством пользователей? Я спрашиваю, потому что я пытаюсь подключиться к 20+ SignalR, и я нахожу, что задержки сообщений медленно начинают увеличиваться, прежде чем все это рушится (все не отвечает).
gnychis
1
@gnychis: есть много решений для этого, но многие из них больше связаны с самой инфраструктурой (для этого и предназначен serverfault.com ). В общем, выделите больше оборудования и разделите пользователей между доменами, чтобы некоторые соединения обрабатывались sockets1.example.com, другие - sockets2.example.com и т. Д. Довольно эффективными, но также довольно дорогими с точки зрения оборудования и пропускной способности.
Арсений Мурзенко
3
Этот ответ превосходен, но я хотел бы сузить исходный вопрос. Если приложению требуется постоянное соединение с веб-сокетом, то почему бы не использовать веб-сокеты полностью вместо REST API? Поскольку веб-розетка открыта, возможно, ее следует использовать полностью.
HappyNomad
Я только что нашел ответ на свой вопрос.
HappyNomad
1

Просто мои 2 цента ...

Я думаю, что дело не в производительности или чем-то еще. Это о стандартах. REST - это стандарт, и IMHO имеет следующие преимущества:

  • HTTP-запросы просты в использовании. Каждый может быстро использовать REST API. Черт возьми, вы даже можете открыть браузер и ввести URL-адрес, чтобы увидеть данные, насколько вы можете быть более интерактивным?
  • (Почти) любой язык программирования может использовать его. Это своего рода универсальный интерфейс. Взаимодействие с SignalR с экзотического языка кажется менее очевидным.
  • У этого есть хорошая поддержка инструмента, как http://petstore.swagger.wordnik.com/
  • Это хороший «интерфейс» для отладки. Вы можете легко отслеживать входящие и исходящие сообщения прямо в браузере, просматривать данные и т. Д. С помощью веб-сокетов и пользовательских библиотек это не так очевидно, вам необходимо явно регистрировать все.
dagnelies
источник
1
В то время как вы делаете некоторые хорошие замечания о том, что API-интерфейсы REST немного более просты и, возможно, имеют лучший инструментарий, этот ответ говорит о нескольких вещах, которые просто не соответствуют действительности. REST не является стандартом , в то время как WebSockets есть .
StriplingWarrior
1
Я думаю, это была плохая формулировка с моей стороны. То, что я имел в виду под «стандартом», является обычным, широко используемым, стандартным способом ведения дел ... а не «стандартом RFC».
dagnelies
Хорошее уточнение. И, между прочим, Chrome по крайней мере позволяет вам видеть трафик WebSockets в его инструментах разработки. Я думаю, что другие браузеры, вероятно, тоже.
StriplingWarrior