socket.io - как получить доступ к необработанным сообщениям?
Как определить, что вы получили сообщение по соединению socket.io, для которого у вас нет обработчика?
пример:
// client
socket.emit('test', 'message');
// server
io.on('connection', function (socket) {
console.log('connection received...');
// logs all messages
socket.conn.on('message', function(data) {
console.log('this gets every message.');
console.log('how do I get just the ones without explicit handlers?');
});
socket.on('other' function(data) {
console.log('expected message');
});
}
2 ответа
Получив доступ к внутренним объектам объекта сокета, вы можете определить, какие события он ожидает в данный момент. Вы можете использовать этот код на стороне сервера, чтобы увидеть, обрабатывается ли текущее сообщение.
io.on('connection', (socket) => {
console.log('A user connected.');
socket.on('disconnect', () => {
console.log('A user disconnected.');
});
socket.on('chat', (msg) => {
console.log('message: ' + msg);
io.emit('chat', msg);
});
socket.conn.on('message', (msg) => {
if(!Object.keys(socket._events).includes(msg.split('"')[1])) {
console.log(`WARNING: Unhandled Event: ${msg}`);
}
});
}
После подключения я обрабатываю два события: "отключение" и "чат". После этого я определяю обработчик, который перехватывает все сообщения с помощью socket.conn.on (...).
Полученное сообщение будет строкой, которая выглядит примерно так: '2["myEventName","param1","param2"]'
, Разбивая его по двойным кавычкам, мы можем получить имя события.
Затем мы заглядываем внутрь сокета, чтобы найти все ключи socket._events, которые являются строками имен событий. Если в эту коллекцию строк входит наше имя события, об этом позаботится другой обработчик, а нам это не нужно.
Вы можете проверить это с консоли в браузере. Бежать socket.emit('some other event')
там и вы должны увидеть ваше предупреждение в консоли сервера.
ВАЖНОЕ ПРИМЕЧАНИЕ: как правило, вы не должны пытаться внешне изменить какой-либо элемент объекта, начиная с подчеркивания. Также ожидайте, что любые данные в нем нестабильны. Подчеркивание указывает на то, что оно предназначено для внутреннего использования в этом объекте, классе или функции. Хотя этот объект нестабилен, он должен быть достаточно современным, чтобы мы могли его использовать, и мы не модифицируем его напрямую.
Протестировано с SocketIO версии 2.2.0 на Chrome.
Я не нашел способа сделать это как socket.io, но используя простую функцию js для преобразования сообщения в json, он выполняет ту же работу. Здесь вы можете попробовать это:
function formatMessage(packetType, data) {
var message = {'packetType': packetType, 'data': data}
return JSON.stringify(message)
}
С:
socket.on('message', function(packet){
packet = JSON.parse(packet)
switch (packet.packetType) {
case 'init':
...
а также
socket.send(formatMessage('init', {message}));
Я бы сделал так, конечно, это абстрактный код... вам бы пришлось реализовать все слушатели и логику, чтобы заставить работать идентификаторы пользователей
клиент
var currentUser = {
id: ? // The id of current user
};
var socketMessage = {
idFrom: currentUser.id,
idTo: ?, // Some user id value
message: 'Hello there'
};
socket.emit('message', socketMessage);
socket.on('emitedMessage' + currentUser.id, function(message) {
// TODO: handle message
});
сервер
io.on('connection', function (socket) {
// Handle emit messages
socket.on('message', function(socketMessage) {
// With this line you send the message to a specific user
socket.emit('emitedMessage-' + socketMessage.idTo, {
from: socketMessage.idFrom,
message: socketMessage.message
});
});
});
Больше информации: http://socket.io/docs/