Add headers to all DDP calls

Hi everyone,

We’re connecting meteor frontends to a different meteor backend using the DDP_DEFAULT_CONNECTION_URL environment variable.

We’d like to be able to identify each frontend when a meteor method/publication is called on the backend, as well as from which path the call happened, so that we can track activity from each of those frontends separately.

A simple way to do this would be to add a header to each DDP call so that we can get it from the httpHeaders on the meteor connection. But I can’t seem to find out where/how/if I can change that?

Is it possible to change the ClientStream once it has been created at this line (see options.headers), to give it more headers? (it does not appear to work to simply edit it)

Does someone have an other idea?

2 Likes

Just read this in a comment above the code:

//   headers: extra headers to send on the websockets connection, for
//     server-to-server DDP only

So I’ll have to find another way.

1 Like

Headers and WebSockets do not interact well.

If you want to include identifying information on a websocket URL request, put it in the query (?frontend=blah), or really anywhere in the URL.

Thanks, sounds promising!

Do you know of a way to hook into all websocket calls to do this in Meteor? And where to grab it from the URL on the server?

After some hefty digging, I found out that meteor is still using SockJS 0.3.4 (released in 2014) to generate WS URLs, and that version does not support query strings. An update of SockJS could make this possible…

1 Like

I think you can do it with meteor call params:

Meteor.call("method", { frontend: "fr-1" });

And then wrap all meteor methods to catch the params with frontend field.
You will need to intercept meteor methods execution to catch params, see how I am intercepting them in my apm solution.

  1. Wrapping meteor method
    https://github.com/kschingiz/meteor-elastic-apm/blob/master/instrumenting/methods.js
  2. Wrapping meteor processMessage, which allows to intercept ALL(meteor call, pub/sub, ping pongs) messages from client:
    https://github.com/kschingiz/meteor-elastic-apm/blob/master/instrumenting/session.js

What problem are you trying to solve ? Is your goal to achieve sticky sessions between clients and multiple meteor app servers ? If yes tools like nginx can do this routing for you … nginx can cut and stow a hash for the client connection then on subsequent traffic a given client will always get routed to same app server

My bad if it wasn’t very clear, it has nothing to do with sessions, it’s just about identifiying from where a DDP call has been made, for logging and tracking.

The simple thing I want to achieve, is to be able to know in any meteor server-side code, which front-end was the caller of the method/subscription:

// In some deep server-side code
track('someMethod called by ' + getFrontEndId())

We could do it from nginx, but I’d really like to avoid it, as we may easily stop using nginx.

What about my solution above? It’s a little complicated, at least it will work

Yeah, that’s what I’m doing at the moment, but it’s only for methods. I wish it’d work for all DDP calls, including subscriptions.