Підпротокол WebSocket запит-відповідь


76

WebSocket забезпечує двостороннє спілкування, як людина розмовляє. Клієнт може надсилати дані на сервер, а сервер може надсилати дані клієнту в будь-який час. Але як щодо поведінки запит-відповідь? Клієнт міг щось запитати у сервера і чекати відповіді. Здається, Websocket не надає нічого для прив'язки даних клієнта (запит) до даних сервера (відповідь).

Це, мабуть, робота підпротоколу, і я маю кілька ідей щодо того, як це зробити (надішліть ідентифікатор із запитом і почекайте відповіді з тим самим ідентифікатором протягом періоду очікування).

Щоб не винаходити колесо та економити час, я шукав в Інтернеті існуюче рішення, але не знайшов нічого пов’язаного (можливо, поганих ключових слів).

Отже, хтось знає про такий вид роботи чи мені чогось не вистачає?


WebSockets насправді не призначені для такої класичної поведінки HTTP-запит-відповідь. Вони засновані на подіях, як події JavaScript: вони начебто не вимагаються.
rvighne

Відповіді:


52

Для цього протокол обміну повідомленнями додатків WebSocket (WAMP) https://wamp-proto.org/ надає шаблони обміну повідомленнями RPC (віддалений виклик процедур) та PubSub (публікація та підписка) поверх необробленого WebSocket.

WAMP - належний підпротокол WebSocket, використовує WebSocket як транспорт, а JSON як формат корисного навантаження. RPC реалізується з використанням 3 повідомлень, і ці повідомлення містять "Ідентифікатор виклику" для кореляції асинхронних відповідей сервера RPC на виклики, ініційовані клієнтом.

Застереження: Я автор WAMP та деяких реалізацій WAMP (з відкритим кодом). Це відкрита ініціатива, коли інші вже почали сідати на човен. Зрештою, повинен існувати WAMP RFC, який правильно визначає протокол .. але він все ще знаходиться на ранніх стадіях.


Саме те, що я шукав. Я працюю над Java на обох сторонах, і у вас, схоже, немає реалізацій Java, тому я із задоволенням приєднаюся :)
Ghetolay

Чудово! Приєднайся до нас! До речі: у нас є спеціальна реалізація лише для клієнта Java для Android: github.com/tavendo/AutobahnAndroid Пара ресурсів WAMP: wamp.ws/spec , github.com/tavendo/wamp , список розсилки, згаданий в останньому, і (в основному з історичних причин), список розсилки для Автобану: groups.google.com/group/autobahnws .
oberstet

@oberstet У мене є подібне та подібне запитання щодо веб-сокета та сервера Apache, які постійно надсилають клієнту неодноразову інформацію, а не лише один раз. Розташований за адресою stackoverflow.com/questions/25071639/… будь-які пропозиції?
Саурон

13

Я б використовував JSON-RPC 2.0.

http://www.jsonrpc.org/specification

Кожне повідомлення буде об'єктом JSON. Протокол визначає, чи це виклик, який вимагає відповіді (зв’язок з ідентифікатором), або сповіщення.

Програма, що знає про JSON-RPC, може легко перевірити, чи містить об'єкт повідомлення метод, що означає виклик чи ні, що означає відповідь.

Я збираюся створити javascript lib для обробки json rpc через веб-сокет, з використанням ajax як резервного…


Я планую додати сервер JSON-RPC також у js, щоб серверний сервер міг надсилати запити до браузера таким же чином.
fiddur

1
+1 JSON-RPC насправді дуже підходить для WebSocket, а саме PubSub (незважаючи на твердження про протилежне на сайті WAMP). Найбільшою проблемою прикидання WebSocket проти JSON-RPC є відсутність відповіді, отже, нібито виключаючи використання JSON-RPC і вимагаючи використання режиму "сповіщення" в JSON-RPC через WebSocket. Однак приєднання до викликів JSON-RPC, які містять idелемент (позначення режиму неповідомлення), насправді дозволяє двонаправленим асинхронним відповідям підходити під цим ідентифікатором (просто потрібно передати ідентифікатор зворотного виклику на b / e), і ви можете продовжувати використовувати режим сповіщення для запитів без відповіді.
ddotsenko

3

(надішліть ідентифікатор із запитом і почекайте відповіді з тим самим ідентифікатором до періоду очікування)

Я створив бібліотеку, яка робить саме це, що називається WebSocketR2 (де R2 означає Запит на відповідь): https://github.com/ModernEdgeSoftware/WebSocketR2

Він також обробляє повторне підключення до сервера в разі втрати зв'язку, що може бути корисно, якщо ви робите веб-сокети через балансир навантаження.

Кінцевим результатом є те, що ви можете реалізувати зворотні виклики у функції надсилання веб-сокета таким чином:

var request = {
    action: "login",
    params: {
        username: "test",
        password: "password"
    }
};

ws.send(request, function(response){
    console.log(response)
});

2

Погляньте на msg-rpc , він забезпечує двонаправлену підтримку rpc через простий інтерфейс повідомлень, включаючи WebSocket.

Не тільки простий rpc, який може охоплювати поведінку "запит клієнта / відповідь сервера", він також підтримує поведінку "запит сервера / відповідь клієнта", який здійснюється через службу Rpc.

Для початку є приклади sockjs та socket.io.


2

погляньте на SwaggerSocket , який є протоколом REST over WebSockets, підтримуваним усіма основними Java WebServer.



0

Трохи пізно в цій дискусії, але BrokerJS - це реактивна альтернатива, яку ви можете спробувати в NodeJS. Визначте модель даних і підпишіться на з'єднання через Інтернет із певними ключами моделі. Будь-які зміни змінної на стороні сервера автоматично відображаються на стороні клієнта. Я думаю, це заощадить вам багато типового коду. Ще краще, ви все ще можете використовувати старомодний обмін повідомленнями через веб-сокет, паралельно новому реактивному способу ведення справ. Це далеко не полірований виріб, а масиви - головний біль. Але у поєднанні з чимось на зразок VueJS, React або Svelte, я думаю, це позбавить вас багатьох клопотів.

Застереження: Я є автором BrokerJS.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.