3

Introduction

I'm building a private messaging system using sails, but this question can apply to pretty much anything. I'll be using the messaging system as an example to make the question more clear. As a bit of background info, I'm working with the latest sails 0.10 RC.

The problem

Sails allows you to use redis for sessions and pubsub, which allows you to scale over multiple servers. This is all very neat and works brilliantly, but it leaves me with the question of how to publish events to specific connected sockets (clients).

Sometimes you wish to only publish events to participants, as is the case with a private messaging system. Only the author and recipient should be notified of new messages in the thread. How would you accomplish this? I know you can subscribe a client to a specific model instance, notifying the client of changes in said model; I also know it's possible to subscribe a client to a model, notifying them of newly created (saved) model instances. It's the latter, the create verb that's causing me a bit of trouble. I don't want everyone that's using the messaging system to receive updates for new messages in threads they're not in. This would be a privacy issue.

TL;DR

How can I filter which clients receive the create verb event based on the value of a property (author and recipient) on the model in question? Is there any other way to make sure only these clients receive updates for the model?

Wesley Overdijk
  • 1,176
  • 10
  • 18
  • possible duplicate of [Personalized chat using Sails.js](http://stackoverflow.com/questions/23511887/personalized-chat-using-sails-js) – sgress454 Jun 23 '14 at 19:41
  • @ScottGress I don't think it is. I want the create verb for specific users. I think I can handle that with my own emit, but I'd rather find a solution using blueprints. – Wesley Overdijk Jun 23 '14 at 19:47

1 Answers1

5

You have a few options here, but all of them involve not really using the default publishCreate method, which will just blast out the created message to everyone who was subscribed to it via .watch().

The first option is to use associations to link your Message model to the users who should know about it, and then listen for the publishAdd message instead of publishCreate. For example, if there's an association between a Message instance and the User instances who represent the sender and recipient, then the default publishCreate logic will also trigger a publishAdd for the related users, indicating that a new Message has been added to their messages (or whatever you name it) collection.

The second option is to override the default publishCreate for Message, to have it send only to the correct users. For example, if only the recipient should be notified, then in api/models/Message.js you could do:

attributes: {...},
publishCreate: function (values, req, options) {
    User.publish(values.recipient, {
        verb: "created",
        data: values, 
        id: values.id
    }, req);
}

As a slight alternative, you can place your custom code in the model's afterPublishCreate method instead, which the default publishCreate will then call. This has the benefit of maintaining the default code that handles calling publishAdd for associated models; the trick would be just to make sure that no one was subscribed to the model classroom via .watch(), so that the default publishCreate doesn't send out created messages to users who shouldn't see them.

sgress454
  • 24,870
  • 4
  • 74
  • 92
  • I've solved it differently, by pushing out events myself. I like your (second) solution a lot more and will be implementing it accordingly. Thanks! – Wesley Overdijk Jul 10 '14 at 12:30