3

Essentially, this is what I had in mind :

Client

const Messages = new Mongo.Collection("messages");

Meteor.call("message", { room: "foo", message: "Hello world");
Meteor.subsribe("messages", "foo");

// elsewhere
const messages = Messages.find({ room: "foo" });

Server

Meteor.methods({
  message: ({ room, message }) => {
    // 1. remove old messages in the room
    // 2. add new message to the room
  }
});

Meteor.publish("messages", function (room) {
   // 1. return message collection for room
});

The client, I assume, uses minimongo, which is fine, but the server does not have access to a MongoDB instance whatsoever.

What would be the implementation on the server?

Yanick Rochon
  • 51,409
  • 25
  • 133
  • 214
  • This can be done following the complex `publish` example in the documentation, manually calling `this.added`, etc. But doesn't meteor complain if you try to start it without a mongo connection? Have you already overcome that problem somehow? – Christian Fritz Mar 10 '21 at 19:18
  • @ChristianFritz No, meteor does not complain about a lack of MongoDB. I do not recall what I did exactly, but everything deploys just fine locally. – Yanick Rochon Mar 10 '21 at 20:17
  • what are you setting for `MONGO_URL`? – Christian Fritz Mar 10 '21 at 20:21
  • @ChristianFritz nothing. There are only two env variables : `PORT` and `ROOT_URL`. The app has been running non stop in production since last November without any complain (empty logs). I know I did something to prepare that app so MongoDB would not be a requirement, but I do not recall what. I've been working on many projects since then. The point is, I need to to add this feature :) – Yanick Rochon Mar 10 '21 at 20:25

1 Answers1

1

As mentioned in comments, I think this can be achieved using the manual publication methods described in the documentation. Something like this might work:

// Server:

const rooms = {};

Meteor.publish('manualMessages', function(roomId) {
  check(roomId, String);
  rooms[roomId] = this;
  this.ready();
});

Meteor.methods({
  message: ({ roomId, message }) => {
    // 1. remove old messages in the room
    const room = rooms[roomId];
    if (!room) {
      throw new Meteor.Error('no room', 'that room does not exist');
    }
    room.removed('messages', roomId);
    // 2. add new message to the room
    room.added('messages', roomId, { message });
  }
});



// Client:
const Messages = new Mongo.Collection("messages");

Meteor.call("message", { room: "foo", message: "Hello world");
Meteor.subsribe("manualMessages", "foo");

// elsewhere
const messages = Messages.find({ room: "foo" });

One thing to verify is whether this in the publish function changes per client, in which case rooms should contain arrays, or whether it is the same object for all clients, as assumed here. But hopefully this point you in the right direction.

Christian Fritz
  • 20,641
  • 3
  • 42
  • 71