Как выполнять действия, когда поток изменений MongoDB Realm Web SDK закрывается или истекает время ожидания?

#mongodb #realm

#mongodb #область

Вопрос:

Я хочу удалить все вставки пользователя в коллекции, когда они перестают просматривать поток изменений из клиента React. Для этого я использую Realm Web SDK.

Вот краткое изложение моего кода с тем, что я хочу сделать в конце:

 import * as Realm from "realm-web";

const realmApp: Realm.App = new Realm.App({ id: realmAppId });
const credentials = Realm.Credentials.anonymous();
const user: Realm.User = await realmApp.logIn(credentials);

const mongodb = realmApp?.currentUser?.mongoClient("mongodb-atlas");
const users = mongodb?.db("users").collection("users");

const changeStream = users.watch();

for await (const change of changeStream) {
  switch (change.operationType) {
    case "insert": {
      ...
      break;
    }
    case ...
  }
}

// This pseudo-code shows what I want to do
changeStream.on("close", () => // delete all user's inserts)

changeStream.on("timeout", () => // delete all user's inserts)

changeStream.on("user closes app thus also closing stream", () => ... )
 

Шаблоны Realm Web SDK, похоже, сильно отличаются от шаблонов NodeJS и, похоже, не включают метод для закрытия потока или для запуска обратного вызова при его закрытии. В любом случае, они не подходят для моего варианта использования.

Эти веб-документы MongoDB Realm ведут к дополнительным документам о Realm. Если я этого не упускаю, в обоих наборах не говорится о том, как отслеживать закрытие и время ожидания наблюдателя потока изменений, созданного из Realm Web SDK, и как что-то делать, когда это происходит.

Я думал, что другой способ сделать это — использовать триггеры Realm. Но из их документов это маловероятно.

Можно ли это сделать даже из клиентского интерфейса? Есть ли способ сделать это на самом MongoDB «бессерверным» способом?

Комментарии:

1. Из любопытства — не могли бы вы поделиться еще несколькими подробностями об использовании?

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

Ответ №1:

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

Если наблюдатель может быть закрыт из-за закрытия приложения / браузера, я бы рекомендовал не запускать логику удаления на вашем клиенте. Вместо этого уведомите сервер (или вызовите функцию Mongodb Realm / конечную точку http), чтобы выполнить удаления.

Вы можете использовать Beacon API для надежной отправки запроса на запуск удаления, даже когда окно выгружается.

 Client side

const inserts = [];
for await (const change of changeStream) {
  switch (change.operationType) {
    case 'insert': inserts.push(change);
  }
}
// This point is only reached if the generator returns / stream closes
navigator.sendBeacon('url/to/endpoint', JSON.stringify(inserts));

// Might also add a handler to catch users closing the app.
window.addEventListener('unload', sendBeacon);
 

Обратите внимание, что unload событие не является надежным MDN. Но есть несколько альтернатив, которые могут быть достаточно хороши для вашего варианта использования.

Внутри функции realm вы можете удалить документы.

При этом, возможно, есть лучший способ сделать то, чего вы хотите достичь. Действительно ли это время ожидания прослушивателя потока изменений, которое должно инициировать удаление или какое-либо другое пользовательское событие?

Комментарии:

1. Я не смог заставить Beacon API и событие «выгрузки» работать в этом случае из-за различных ограничений, в том числе из-за того, что конечные точки MongoDB HTTPS требуют заголовков, я думаю. sendBeacon сбой, но curl работал с заголовками. Так что я думаю, вы правы. Мне придется использовать сервер. Может быть, я просто выполню ежедневное задание cron. Спасибо!

2. Конечные точки Http требуют, чтобы вы добавили домен клиента в раздел «разрешенные источники» в настройках приложения. Да, это вещь CORS.