Почему веб-сокеты не используют SOAP?

Я знаю, что этот вопрос был задан и другими способами, но у меня более конкретный вопрос к подходу. Учитывая, что веб-сокеты являются клиентскими, клиентский код находится в JavaScript. Действительно ли это намерение построить большой кусок приложения непосредственно в JavaScript? Почему W3C не сделал этого в веб-службах? Не было бы проще, если бы мы могли использовать SOAP для предоставления контракта и определения событий вместе с существующими сообщениями? Просто пока кажется, что это короткий конец палки.

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

вместо

mysocket.send("AFunction|withparameters|segmented");

мы могли бы сказать

myServerObject.AFunction("that", "makessense");

и вместо

...
mysocket.onmessage = function() { alert("yay! an ambiguous message"); }
...

мы могли бы сказать

...
myServerObject.MeaningfulEvent = function(realData) { alert("Since I have realistic data....");  alert("Hello " + realData.FullName); }
...

HTML 5 занял целую вечность, чтобы завладеть....мы потратили много усилий в неправильном направлении? Мысли?

6 ответов


звучит так, как будто вы еще не полностью поняли концепции вокруг Websockets. Например, вы говорите:

учитывая, что веб-сокеты являются клиентскими

это не так, сокеты имеют 2 стороны, вы можете думать о них как о сервере и клиенте, однако, как только соединение установлено, различие размывается - вы также можете думать о клиенте и сервере как о "сверстниках" - каждый может писать или читать в канал, который их соединяет (the соединение гнезда) в любое время. Я подозреваю, что вам будет полезно узнать немного больше о HTTP - работах поверх TCP-WebSockets похож / аналогичен HTTP таким образом.

Что касается SOAP / WSDL, с точки зрения разговора вокруг TCP / WebSocket / HTTP вы можете думать обо всех разговорах SOAP / WSDL как идентичных HTTP (т. е. обычный трафик веб-страницы).

наконец, помните о сложенном характере сетевого программирования, например SOAP/WSDL выглядит так:

SOAP/WSDL
--------- (sits atop)
HTTP
--------- (sits atop)
TCP

и WebSockets выглядят так

WebSocket
--------- (sits atop)
TCP

HTH.


JavaScript позволяет клиентам общаться через HTTP с XMLHttpRequest. WebSockets расширяет эту функциональность, чтобы JavaScript мог делать произвольный сетевой ввод-вывод (а не только HTTP), который является логическим расширением и позволяет переносить на JavaScript все виды приложений, которые должны использовать TCP-трафик (но не могут использовать протокол HTTP). Я думаю, вполне логично, что, поскольку приложения продолжают перемещаться в облако, HTML и JavaScript поддерживают все, что доступно на стол.

хотя сервер может выполнять не HTTP-сетевой ввод-вывод от имени клиента JavaScript и делать эту связь доступной через HTTP, это не всегда наиболее подходящая или эффективная вещь. Например, не имеет смысла добавлять дополнительную стоимость туда и обратно при попытке сделать онлайн-терминал SSH. WebSockets позволяет JavaScript напрямую общаться с сервером SSH.

Что касается синтаксиса, часть его основана на XMLHttpRequest. Как было указано в другой публикации, WebSockets-это довольно низкоуровневый API, который можно обернуть в более понятный. Более важно, чтобы WebSockets поддерживал все необходимые приложения, чем то, что он имеет самый элегантный синтаксис (иногда фокусировка на синтаксисе может привести к более ограничительной функциональности). Авторы библиотеки всегда могут сделать этот очень общий API более управляемым для других разработчиков приложений.


Как вы отметили, WebSockets имеет низкие накладные расходы. Накладные расходы похожи на обычные сокеты TCP: всего на два байта больше на кадр по сравнению с сотнями для AJAX/Comet.

Почему низкий уровень вместо какой-то встроенной функциональности RPC? Некоторые мысли:

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

  • поддержка WebSockets-это тривиально добавить несколько языков на стороне сервера. Информационное наполнение-это просто строка UTF-8 и почти каждый язык имеет встроенную эффективную поддержку для этого. Механизм RPC не так много. Как вы обрабатываете преобразования типов данных между Javascript и целевым языком? Вам нужно добавить тип, намекающий на сторону Javascript? Как насчет аргументов переменной длины и / или аргумента списки? Вы строите эти механизмы, если язык не имеет хорошего ответа? Так далее.

  • какой механизм RPC будет смоделирован после? Вы бы выбрали существующий (SOAP, XML-RPC, JSON-RPC, Java RMI, AMF, RPyC, CORBA) или совершенно новый?

  • Как только поддержка клиентов будет достаточно универсальной, многие службы, имеющие обычный сокет TCP, добавят поддержку WebSockets (потому что это довольно тривиально добавить). То же самое не верно, если WebSockets был основан RPC. Некоторые существующие службы могут добавить слой RPC, но по большей части службы WebSockets будут созданы с нуля.

для меня noVNC проект (клиент VNC, использующий только Javascript, Canvas, WebSockets) характер низких накладных расходов WebSockets имеет решающее значение для достижения разумной производительности. Пока серверы VNC не включают поддержку WebSockets, noVNC включает wsproxy, который является общим WebSockets для прокси сокета TCP.

Если вы подумайте о реализации интерактивного веб-приложения, и вы еще не решили на серверном языке, тогда я предлагаю посмотреть на гнездо.ИО которая является библиотекой для узел (серверный Javascript с использованием движка V8 от Google).

в дополнение ко всем преимуществам узла (тот же язык с обеих сторон, очень эффективный, библиотеки питания и т. д.), сокет.IO дает вам несколько вещей:

  • предоставляет как клиент, так и сервер библиотека framework для обработки соединений.

  • обнаруживает лучший транспорт, поддерживаемый как клиентом, так и сервером. Транспорты включают (от лучшего к худшему): собственные WebSockets, WebSockets с использованием эмуляции flash, различные модели AJAX.

  • последовательный интерфейс неважно какой транспорт используется.

  • автоматическое кодирование / декодирование типов данных Javascript.

было бы не так сложно создать Механизм RPC поверх гнезда.IO, так как обе стороны являются одним и тем же языком с одинаковыми родными типами.


WebSocket делает Comet и все другие методы типа HTTP push разборчивыми, позволяя запросам исходить от сервера. Это своего рода изолированный сокет и дает нам ограниченную функциональность.

однако API достаточно общий для авторов фреймворка и библиотеки, чтобы улучшить интерфейс в любом случае, как они хотят. Например, вы можете написать некоторую службу в стиле RPC или RMI поверх WebSockets, которая позволяет отправлять объекты по проводу. Теперь внутренне они сериализован в каком-то неизвестном формате, но пользователю службы не нужно знать и все равно.

так думать из спецификации авторов POV, идя от

mysocket.send("AFunction|withparameters|segmented");

to

myServerObject.AFunction("that", "makessense");

сравнительно легко и требует написания небольшой обертки вокруг WebSockets, чтобы сериализация и десериализация происходили непрозрачно для приложения. Но движение в обратном направлении означает, что авторам спецификаций нужно сделать гораздо более сложный API, который делает более слабым основа для написания кода поверх него.


я столкнулся с той же проблемой, где мне нужно было сделать что-то вроде call('AFunction', 'foo', 'bar') вместо сериализации/де-сериализации каждого взаимодействия. Мои предпочтения также оставить основную часть кода на сервере и просто использовать JavaScript для обработки вид. WebSockets были лучше подходят из-за его естественной поддержки двунаправленной связи. Чтобы упростить разработку приложения, я создаю слой поверх WebSockets для удаленных вызовов методов (например,RPC).

я опубликовал RMI/RPC библиотека в http://sourceforge.net/projects/rmiwebsocket/. После настройки связи между веб-страницей и сервлетом можно выполнять вызовы в любом направлении. Сервер использует отражение для вызова соответствующего метода в объекте на стороне сервера, а клиент использует метод "вызов" Javascript для вызова соответствующей функции в объекте на стороне клиента. Библиотека использует Джексон заботиться о сериализации/десериализации различных типов Java в/из JSON.


WebSocket JSR был согласован рядом сторон (Oracle, Apache, Eclipse и т. д.) с очень разными повестками дня. Хорошо, что они остановились на уровне транспорта сообщений и оставили конструкции более высокого уровня. Если вам нужен Java для JavaScript RMI, проверьте рамки Ферми.