Есть ли способ отправить ответ от сервера, даже если обратная связь не предоставляется со стороны клиента? - PullRequest
1 голос
/ 17 февраля 2020

Разъяснение проблемы

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

socket.emit('someEvent', payload, callback);

О чем этот вопрос - часть callback. Это отличная вещь, поскольку она позволяет отправлять некоторые данные в ответ без каких-либо дополнительных событий. Все, что нужно серверу - это правильно обработать запрос:

socket.on('someEvent', (payload, callback) => { 
   doSomeStuff(); 
   callback(someData);
);

Это прекрасно работает, когда мы имеем дело с успешным случаем. Но что нам делать в этих случаях:

1) Обратный вызов не был отправлен со стороны клиента / обратный вызов не является функцией, и существует необходимость отвечать со стороны сервера чем-то вроде 'Ошибка: нет обратный звонок предоставляется. Использование: ... '

Пример:

Клиентская сторона - socket.emit('someEvent'); или socket.emit('someEvent', 1);

Серверная сторона - socket.on('someEvent', callback => callback());

или

2) Во время обработки запроса что-то пошло не так (например, неудачный результат проверки), и нам нужно сообщить об этом следующим образом: 'Полезная нагрузка не предоставлена ​​или недействительна'

Пример:

На стороне сервера -

socket.emit('someEvent', payload, callback => { 
   checkPayload(); 
   callback(someData); 
});

На стороне клиента - socket.on('someEvent', invalidPayload, callback);

Вопрос : есть ли механизм для создания пользовательского обратного вызова со стороны респондента?

Мои рабочие и обходные пути

1) Что касается отсутствующего обратного вызова или того, который не является функцией, я пришел к выводу, что я могу только проверить ее и затем вызывать его только в случае его действия. Таким образом, на стороне сервера происходят некоторые изменения:

socket.emit('someEvent', callback => callback instanceof Function && callback()); //check callback correctness

Pros : не будет внутренней ошибки, если обратный вызов не является функцией, как ожидалось.

Минусы : в случае недействительного обратного вызова клиент не будет замечен по этому поводу.

2) Что касается случая, когда нам необходимо отправить некоторую ошибку обратно, я Обнаружен только обходной путь для возврата указанного c заранее согласованного ложного значения, например null, так что это означает, что данные не могут быть возвращены.

socket.emit('someEvent', payload, callback => {  
   checkPayload();
   callback(someData || null); //send falsy, error-like value instead
});

Pros : клиент будет замечен о какой-то ошибке, получив null.

Минусы : со стороны сервера нет простой функции промежуточного программного обеспечения, которая проверяет входные данные и возвращает ошибку до того, как выполняется основной лог c.

Я думал о промежуточном программном обеспечении для достижения необходимой функциональности, но, так сказать, «промежуточного программного обеспечения уровня событий» пока нет, только в целом namespace и socket level. Должен ли я попытаться отфильтровать события по их именам на уровне сокета, чтобы добавить необходимые функции и отправить ошибку, как next(new Error(...));? В этом случае может быть работа с error прослушиванием событий, наверное.


socket.io / socket.io-client используемые версии: 2.3.0

1 Ответ

1 голос
/ 17 февраля 2020

1) Обратный вызов не был отправлен со стороны клиента / обратный вызов не является функцией, и существует необходимость отвечать со стороны сервера что-то вроде «Ошибка: обратный вызов не предоставляется. Использование: ... '

Клиент и сервер должны договориться, как это сделать. Если клиент не предоставляет обратный вызов, то аргумент сервера будет undefined, поэтому вы можете определить это с сервера.

Итак, правильный способ сделать это:

// client 
socket.emit('someMsg', someData, function(response) {
    console.log(`Got ${response} from server`);
});

// server
io.on('connection', socket => {
    socket.on('someMsg', (data, fn) => {
        console.log(`Got data ${data} from client, sending response`);
        // if client wants a response, send the response
        if (fn) {
            fn("got your data");
        }
    });
});

Итак, если клиент не пройдет обратный вызов, то fn на стороне сервера будет undefined. Таким образом, вы можете проверить это перед вызовом.

2) Что касается случая, когда нам нужно отправить некоторую ошибку обратно, я нашел только обходной путь для возврата указанного c , заранее согласовано, ложное значение, такое как null, что означает, что никакие данные не могут быть возвращены.

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

// client 
socket.emit('someMsg', someData, function(response) {
    if (response.error) {
        console.log(`Got error ${response.error} from server`);
    } else {
        console.log(`Got data ${response.data} from server`);
    }
});

// server
io.on('connection', socket => {
    socket.on('someMsg', (data, fn) => {
        console.log(`Got data ${data} from client, sending response`);
        // if client wants a response, send the response
        if (fn) {
            // no error here
            fn({error: null, data: "Got your message"});
        }
    });
});

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

Или, если есть ошибка, вы можете отправить объект ошибки. :

// server
io.on('connection', socket => {
    socket.on('someMsg', (data, fn) => {
        console.log(`Got data ${data} from client, sending response`);
        // if client wants a response, send the response
        if (fn) {
            // send an error here
            fn({error: new Error("xxx Error")});
        }
    });
});

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

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

Попробую отфильтровать события по их именам на уровне сокетов, чтобы добавить необходимые функции и отправить ошибку следующим образом ( новая ошибка (...)) ;? В этом случае может быть работа с прослушиванием события ошибки, я думаю.

Socket.io не работает как Express, и я не понимаю, почему вы пытаетесь сделать это работает таким образом. next() не участвует в получении сообщения socket.io, поэтому я не уверен, что вы пытаетесь сделать там. Существует опция для промежуточного программного обеспечения при первом подключении к socket.io, но не для последующих сообщений, отправляемых по этому соединению.

Существует ли способ отправки ответа с сервера, даже если обратный вызов не предусмотрен со стороны клиента?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...