Send message to specific client (socket) only.

668 views
Skip to first unread message

ixti

unread,
May 17, 2012, 1:40:27 PM5/17/12
to faye-...@googlegroups.com
Hi,

I wonder how I can send a message to only one, specific client.
I understand that I can use separate channels and subscriptions,
but I want to have an option to send a message to the exact
client, regardless to the fact if there are other subscribers on that
channel or not.

Here's example of how this could be done with Socket.IO:

``` javascript
sio.sockets.on('connection', function (socket) {
  // ...
  socket.emit('test', {some: 'data'});
  // ...
});
```

James Coglan

unread,
May 17, 2012, 3:14:23 PM5/17/12
to faye-...@googlegroups.com
On 17 May 2012 18:40, ixti <ix...@member.fsf.org> wrote:
I wonder how I can send a message to only one, specific client.
I understand that I can use separate channels and subscriptions,
but I want to have an option to send a message to the exact
client, regardless to the fact if there are other subscribers on that
channel or not.

Faye does not support this, you can only address messages to channels. An easy way to do this is to have the client pick a unique channel using a GUID generator and have it communicate that to the server. 

John Pignata

unread,
May 18, 2012, 2:36:18 PM5/18/12
to Faye users
Hey James,

This works perfectly. I didn't catch that you could advise the server
on what timeout to use in the specification.

Thanks for your help.
-jp

On May 17, 3:14 pm, James Coglan <jcog...@gmail.com> wrote:

ixti

unread,
May 20, 2012, 7:26:52 AM5/20/12
to faye-...@googlegroups.com

Hi,

Thanks for your reply. Got your idea, but I'm kind a paranoid so would like to clarify some more things :)) Here's a situation I'm afraid of:

- Server sends User name of his private secret channel "u-abcdef01"
- User subscribes to secret channel "u-abcdef01"
- Hacker subscribes to any of possible channels "u-abcdef00", "u-abscdef01", etc.
- Server sends sensitive data to User using secret channel

I understand that if my GUIDs of channels will be long and crazzy enough then subscribing for a hacker will become hard task, but it still be possible. So according to above I think I just need a mechanism to deny subscriptions somehow, so I could have a map of 'GUID' <-> 'user'  pairs and allow to subscriptions for channels on that basis... But I can't find in documentation how can I deny subscription.

James Coglan

unread,
May 20, 2012, 3:49:33 PM5/20/12
to faye-...@googlegroups.com
On 20 May 2012 12:26, ixti <ix...@member.fsf.org> wrote:
Thanks for your reply. Got your idea, but I'm kind a paranoid so would like to clarify some more things :)) Here's a situation I'm afraid of:

- Server sends User name of his private secret channel "u-abcdef01"
- User subscribes to secret channel "u-abcdef01"
- Hacker subscribes to any of possible channels "u-abcdef00", "u-abscdef01", etc.
- Server sends sensitive data to User using secret channel

If you use large enough IDs, it's practically impossible. The AES block cipher, one of the most secure encryption tools we have, uses a key-size of 128 bits. To decrypt a document, you need to guess a 128-bit number, which is hard. Bayeux also uses 128-bit client IDs, making it as easy to guess someone's Bayeux ID as to decrypt an AES cipher.

But let's make it easy for ourselves. Let's say everyone one the planet has 1,000 connections open to your Faye server, so there are this many active client IDs:

P = 7_000_000_000_000

Now the entire ID space is this big:

N = 2**128 = 340282366920938463463374607431768211456

To hijack a session, you just need to guess one of these IDs, and you'll need to, on average, try this many IDs before you get in:

N/(2*P) = 24305883351495604533098186

Now let's assume you can try a billion guesses per second, and you work for a billion days (~ 3 million years):

attempts = 1_000_000_000 * 60 * 60 * 24 * 365 * 1000_000_000
= 31536000000000000000000000

This is the order of magnitude of attempts you need to make to guess one client ID. You're going to need a lot of hardware for this, since a typical failed /meta/connect request takes a few milliseconds.

Anyway, I digress but it's worth knowing what the actual risk is.

Here's what I would do: have your client-side code request a unique 128-bit token from the server, and use the user ID from the session to store a user ID <-> token mapping. Then have the Faye client subscribe to a channel based on that token. Use your stored mapping to route messages relevant to the user. There's really no point installing an authorization extension since you'll just need to send additional, easy-to-guess information along with the token to verify it. Just rely on the size of the token to keep the user protected.

Depending on what you're doing, you may want an extension that only lets the server publish messages, but it's not essential.

ixti

unread,
May 20, 2012, 5:27:09 PM5/20/12
to faye-...@googlegroups.com
Hi,

Thanks for your reply. Really persuasive point of view, and I agree with it (in fact I realized that before, but still something's scratching inside of me ;)) Anyway, thanks again for your time. I have just switched Socket.IO to Faye in fontello (https://github.com/fontello/fontello) - not yet finished (it will be once I'll be satisfied with the logic I made), but I'm pretty happy with Faye :))

edino

unread,
May 23, 2012, 2:00:55 PM5/23/12
to Faye users
if i have for instance 6000 thousands user, can i generate 6000
thousands unique channels without any problem?
will it not affect the performance of the server?
if it is possible, it means that i can use a while loop to publish
messages to each unique channel???
Thanks for your feedback


On May 20, 5:27 pm, ixti <i...@member.fsf.org> wrote:
> Hi,
>
> Thanks for your reply. Really persuasive point of view, and I agree with it
> (in fact I realized that before, but still something's scratching inside of
> me ;)) Anyway, thanks again for your time. I have just switched Socket.IO
> to Faye in fontello (https://github.com/fontello/fontello) - not yet
> finished (it will be once I'll be satisfied with the logic I made), but I'm
> pretty happy with Faye :))
>
>
>
>
>
>
>
> On Sunday, May 20, 2012 9:49:33 PM UTC+2, James Coglan wrote:
>

TJ Singleton

unread,
May 23, 2012, 4:02:05 PM5/23/12
to faye-...@googlegroups.com
ixti, I switched from Socket.IO in Nov/Dec last year. I have not looked back. You shouldn't be disappointed. :)

James, what about wildcard subscriptions? Such as subscribing to '/**'.

ixti

unread,
May 23, 2012, 4:05:34 PM5/23/12
to faye-...@googlegroups.com
As far as I can see it depends on how do you implement it
on the server side.

ixti

unread,
May 23, 2012, 4:08:36 PM5/23/12
to faye-...@googlegroups.com
On Wednesday, May 23, 2012 10:02:05 PM UTC+2, TJ Singleton wrote:
ixti, I switched from Socket.IO in Nov/Dec last year. I have not looked back. You shouldn't be disappointed. :)

Yes, I'm pretty sure it was good turn for us to switch to faye.
Basically I'm going to finish all necessary changes in fontello.com
today, so really soon I guess we'll become another "success"
story of switching to faye ;))

James, what about wildcard subscriptions? Such as subscribing to '/**'.

As fr as I can see in the documentation, faye supports both `/*` (one
level depth) and `/**` (deep nested) subscriptions.

TJ Singleton

unread,
May 23, 2012, 4:11:57 PM5/23/12
to faye-...@googlegroups.com

On May 23, 2012, at 4:08 PM, ixti wrote:


James, what about wildcard subscriptions? Such as subscribing to '/**'.

As fr as I can see in the documentation, faye supports both `/*` (one
level depth) and `/**` (deep nested) subscriptions.

I should have left some of the response, I was referring to the following:

Aleksey Zapparov

unread,
May 23, 2012, 4:15:49 PM5/23/12
to faye-...@googlegroups.com
Ah. Now I got your idea. Basically you can simply reject such subscriptions
on the server fromo any client but server's own one. At least that's the way
I'm going implement it. :))

--
Sincerely yours,
Aleksey V. Zapparov A.K.A. ixti
FSF Member #7118
Mobile Phone: +34 677 990 688
Homepage: http://www.ixti.net
JID: zapp...@jabber.ru

*Origin: Happy Hacking!

TJ Singleton

unread,
May 23, 2012, 4:38:46 PM5/23/12
to faye-...@googlegroups.com

On May 23, 2012, at 4:15 PM, Aleksey Zapparov wrote:

> Ah. Now I got your idea. Basically you can simply reject such subscriptions
> on the server fromo any client but server's own one. At least that's the way
> I'm going implement it. :))

Awesome. That's pretty much what I did. I just wanted to make sure you didn't overlook that.

James Coglan

unread,
May 23, 2012, 7:01:49 PM5/23/12
to faye-...@googlegroups.com
On 23 May 2012 21:08, ixti <ix...@member.fsf.org> wrote:
James, what about wildcard subscriptions? Such as subscribing to '/**'.

As fr as I can see in the documentation, faye supports both `/*` (one
level depth) and `/**` (deep nested) subscriptions.

It does, although due to some problems with meta channels you cannot subscribe to the top-level /**. This is on my to-do list. TJ, what context were you asking your question in?

James Coglan

unread,
May 23, 2012, 7:08:28 PM5/23/12
to faye-...@googlegroups.com
On 23 May 2012 21:11, TJ Singleton <inawe...@gmail.com> wrote:
As fr as I can see in the documentation, faye supports both `/*` (one
level depth) and `/**` (deep nested) subscriptions.

I should have left some of the response, I was referring to the following:

If you use large enough IDs, it's practically impossible.
Ah, I should have spotted this, thanks for pointing it out. There's a couple of solutions you could apply:

* If you're not using wildcards in your app, just disallow any subscription to them
* If you *are* using them, make tailored access control extensions.

As an example, a message published to /foo/bar/qux will be routed to subscriptions on:

    /foo/bar/qux    /foo/bar/*    /foo/bar/**    /foo/**    /**

Protect your app accordingly.

It occurs to me that this is a common problem I've overlooked -- asking people to remember this, and duplicate some of Bayeux's routing semantics, is not ideal. I could supply a way to generate robust access control extensions (something I've considered for ages but not a good concrete idea for) or just some helpers, e.g. a function to expand a channel into a pattern list as shown above. 

James Coglan

unread,
May 23, 2012, 7:16:06 PM5/23/12
to faye-...@googlegroups.com
On 23 May 2012 19:00, edino <edinal...@gmail.com> wrote:
if i have for instance 6000 thousands user, can i generate 6000
thousands unique channels without any problem?
will it not affect the performance of the server?
if it is possible, it means that i can use a while loop to publish
messages to each unique channel???


As for the while loop -- it depends on the transport. Remember a while loop is blocking, so if you're using a request-response transport those messages will be batched into one request, which might, for example, overflow the URI length limit if using JSON-P (callback-polling). If the client has a socket connection, they'll be delivered one by one over the socket, but again not until the whole loop has finished. It might be worth using setTimeout() to break the loop up -- try implementing a large batch send and scale up the client count to see if you need to be careful about blocking for too long.

This blog post might help you with the iteration:

TJ Singleton

unread,
May 23, 2012, 8:15:56 PM5/23/12
to faye-...@googlegroups.com
Nevermind. I missed the fact it was a meta channel. 
Reply all
Reply to author
Forward
0 new messages