kotcich
@kotcich
Я скучный.

Есть ли для Vue плагины по работе с websocket'ами, которые позволяют получить ответ сервера после отправки сообщения напрямую?

Я использую vue-native-websocket и только сейчас понял, что для отправки сообщения используется $socket.send(message), а для получения
this.$options.sockets.onmessage = (data) => console.log(data)
.
И как бы все передается, но вот в этот пусть и мизерный, но промежуток успевает выполнится код, который как бы должен выполняться только после получения ответа. setTimeout юзать не вариант, так как никогда не угадаешь хватит ли установленного времени для получения ответа или нет(ведь кол во юзеров подключенных к серверу всегда будет разное), а накидывать времени с запасом на таймаут неправильно, так как если данные загрузились, лишнее время просто ничего не происходит(да и 1 проблема никуда не девается).
В примерах использования на оф репозитории гитхаба ничего про это не нашел.
Если этого можно добиться в vue-native-websocket, скажите как.
  • Вопрос задан
  • 64 просмотра
Пригласить эксперта
Ответы на вопрос 1
@deliro
Что значит "получить ответ напрямую"? Вебсокеты — асинхронное общение. Здесь нет принципа "запрос-ответ". На них можно сделать такое поведение, как и на любом асинхронном общении, используя correlation id.

Например, ты посылаешь сообщение серверу с данными
{"request": {"x": 123, "y": 123.45}, "id": "1234567"}
, где id должен быть достаточно уникальным в пределах вебсокета. Например, последовательность натуральных чисел.

И ты также ожидаешь, что ответ сервер вернёт с этим же id. Например, такой:
{"response": {"x": 321, "y": 45.321}, "id": "1234567"}


В это случае можно сделать что-то вроде такого:

class WSHandler {
    constructor(ws) {
        this.ws = ws;
        this.sequence = 0;
        this.waiters = {};
    }

    onMessage(event) {
        const { data } = event;
        const { id } = data;
        if (!this.waiters[id]) {
            throw new Error(`No waiter for response #${id} was found`);
        }

        this.waiters[id](data.response);
        delete this.waiters[id];
    }

    sendRequest(requestData) {
        const id = this.sequence++
        const msg = {id, request: requestData};
        this.ws.send(msg);
        return new Promise(resolve => {
            this.waiters[id] = resolve;
        });
    }
}

...

const handler = new WSHandler(new WebSocket('wss://...'));
const response = await handler.sendRequest({"hello": "world"});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы