отправка websocket указанному c пользователю nodejs - PullRequest
0 голосов
/ 23 января 2020

В настоящее время я создаю сервер веб-сокетов для мобильного интерфейса. и в некоторых случаях мне нужно отправить json только указанному пользователю c, и после нескольких попыток мне все еще не удалось заставить Websocket работать, поэтому я могу отправить json одному клиенту за раз.

Я использую эту библиотеку: github.com/websockets/ws

Чтобы объяснить мою проблему, у меня есть несколько продуктов, которые содержат несколько переменных, которые необходимо обновить в режиме реального времени. когда пользователь подключается к продукту, он получает только json этого продукта, а другие пользователи получают json других продуктов, на которых он работает. вот почему я хочу отправить спецификацию c json пользователю, чтобы включить эту

Я хотел бы знать, если кто-нибудь из вас знает, как решить проблему, так как я начинаю блокировать ее .

Большое спасибо.

const opp = new WebSocket.Server({port: 10001});
let user = 0;
let lookup = [];

opp.on('connection', function connection(op) {
    lookup.push(op.id);
    let id = "";
    op.on('message', function incoming(message) {
        console.log('received: %s', message);
        id = message;
        query = {
            text: "SELECT id,state,users_list_name,user_win,timer_stamp FROM products WHERE id = " + parseInt(id) + " AND circle = 1 ORDER BY CASE WHEN state = \'available\' THEN \'1\' WHEN state = \'soon\' THEN \'2\' WHEN state = \'expired\' THEN \'3\' END",
        };
    });
    client.connect();
    const interval = setInterval(function ping() {
        client.query(query, (err, res) => {
            if (err) {
                console.log(err.toString());
                console.log(query);
            } else {
                console.log(lookup);
               for (let i = 0; i < lookup.length; i++){
                    console.log("########################");
                    lookup[i].send(JSON.stringify(res.rows));
                }
            }
        });
    }, 300);
});``` 

1 Ответ

1 голос
/ 23 января 2020

OK. Все еще пытаешься понять фактическое значение c, за которое ты стреляешь. Но, если предположить следующее (основываясь на ваших ответах на мои предыдущие вопросы):

  1. Клиент подключается с помощью webSocket.
  2. Когда они отправляют сообщение через этот webSocket, это сообщение id чего-то, что можно найти в вашей базе данных и для которого нужны регулярные обновления.
  3. Эти обновления для этого конкретного id следует отправлять только указанному клиенту c, который его запросил .
  4. Если другой клиент подключается и указывает некоторые id, они должны получать обновления только для этого id.
  5. Когда клиент отправляет новое сообщение, в котором указывается другой id теперь их обновления должны быть только для этих новых id.
  6. Обновлений для id, запрошенных одним клиентом, отправляются только этому одному клиенту (но не другим клиентам).

Если это то, что вы действительно хотите, вот способ структурировать это.

const wss = new WebSocket.Server({port: 10001});

// make database connection that all users share
client.connect();

wss.on('connection', function connection(ws) {
    // these variables are unique to each ws connection
    let interval, query;

    // when webSocket closes, stop any current interval timer associated with this webSocket
    ws.on('close', function() {
        if (interval) {
            clearInterval(interval);
        }
    });

    // when we get an id, start querying for updates on that id
    ws.on('message', function incoming(id) {
        console.log(`received: ${id}`);
        query = {
            text: "SELECT id,state,users_list_name,user_win,timer_stamp FROM products WHERE id = " + parseInt(id) + " AND circle = 1 ORDER BY CASE WHEN state = \'available\' THEN \'1\' WHEN state = \'soon\' THEN \'2\' WHEN state = \'expired\' THEN \'3\' END",
        };
        // if interval is not already going, start it
        if (!interval) {
            interval = setInterval(function() {
                client.query(query, (err, res) => {
                    if (err) {
                        console.log(err);
                        console.log(query);
                    } else {
                        // send data to just the one client that this timer is for
                        ws.send(JSON.stringify(res.rows));
                    }
                });
            }, 300);
        }
    });
});

Теперь несколько комментариев:

  1. Опрос базы данных по короткому интервал времени с отдельный опрос l oop для каждого клиента просто не будет масштабироваться вообще. У вас будут серьезные проблемы с масштабом базы данных. Здесь вам действительно нужен лучший дизайн, но, поскольку мы не знаем общих требований и архитектуры вашего приложения, у нас недостаточно информации, чтобы знать, что предложить. Возможно, вы хотите использовать уведомления в базе данных, которые сообщают вам, когда данные изменились, а не опрашивать их за короткий промежуток времени от имени каждого отдельного клиента.

  2. Я не смог найти причину для lookup структура данных. В ваших комментариях говорится, что вы хотите отправлять обновления ОДНОМУ клиенту c, который запрашивал этот идентификатор. Это можно сделать с помощью ws.send().

  3. . В этом коде предполагается, что переменная client представляет соединение с вашей базой данных, которое каждый из setIntervals для каждого подключенного клиента может совместно использовать. Вот почему этот код был удален из обработчика событий wss.on('connection', ...).

  4. Я перешел к более общей терминологии: wss для ссылки на экземпляр сервера и ws для ссылки в webSocket для конкретного подключенного клиента.

  5. ws.send() - это способ отправки подключенному клиенту. Я до сих пор не знаю, что ты делал с op.id. Если посмотреть на do c для библиотеки ws, это не то, что вы можете использовать для отправки.

  6. Ваш код (и этот код) создает Отдельный таймер setInterval() для каждого подключаемого клиента webSocket, который использует очень короткий интервал времени. Это не будет масштабироваться. В худшем случае, интервал времени должен быть увеличен до нескольких секунд (в зависимости от желаемой целевой шкалы). В лучшем случае вам нужно полностью прекратить опрос базы данных и использовать какой-либо другой механизм в базе данных для получения уведомлений об изменении данных.

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