Getting just enough bound environment to access the database


#1

I’m building a video chat app that uses a JSON-based web RTC server. The app needs to track certain states, like when a user enters/leaves a room, whether they have an open ticket, etc. Initially I tracked this with a combination of client and server state, but that led to some tricky issues where the video server and client might disagree on state and the poor app server was caught in the middle.

So now what I’m attempting is inserting an httpProxy on the API endpoint. By intercepting my web RTC server’s JSON responses, I know exactly what it thinks the state is. The app server can then respond to the state from the web RTC server rather than duplicating it and trying to keep in sync. So I have something like:

WebApp.rawConnectHandlers.use((req, res, next) => {
  if(req.url.startsWith("/janus"))
    return proxy.web(req, res)
  return next()
})

This works, in that it proxies everything to localhost:3000/janus to my other server. Then, on the proxy object, I have:

proxy.on("proxyRes", (proxyRes, req, res) => {
  proxyRes.on("data", (data) => {
    const msg = JSON.parse(data.toString())
...

This gives me the server response. So let’s say the server responds indicating my user successfully joined a room. I want to look up that user by their username according to the web RTC server, look up the task with which the chatroom is associated, and perform some operations based on both. Unfortunately, none of this code is running in the Meteor environment. As such, none of my searches/updates/methods work, and they all tell me to use bindEnvironment.

I’ve tried:

    return Meteor.bindEnvironment(proxy.web(req, res))

But that gives an error about not being able to write to headers twice. Similarly:

    return Meteor.bindEnvironment(() => proxy.web(req, res))

just complains that Meteor code must be run in a fiber. All of these are in the rawConnectHandlers block. I still have to wrap the event handler in the Meteor environment too.

I just want to access Mongo collections and run methods. None of the methods use Meteor.user() or anything specific to the user’s request, and everything needed to look up essential data is included in the JSON requests/responses from the proxy. How do I get enough of a Meteor environment to access the database and I can handle just about everything else? I’m tempted to just switch to the native Mongo driver at this point but I’d really rather not lose the work I put into modeling my data. At the same time, this API-sniffing request is so much more elegant than clients trying to tell the server that they think they’re available that I really want to get it working.

Thanks.


#2

OK, partially figured this out:

const Fiber = Npm.require("fibers")

Fiber(() => {
  // code here
}).run()

Now my collection searches appear to work, but I don’t like that Npm.require in the context of a newer, NPM-friendly Meteor.

Should this work if I npm install fybers and ditch the Npm.require? Or is there something specific to the version Meteor ships that would make it not work?

I suppose I could try myself, but I think the larger question is that, given Meteor is rapidly changing, what would be the best way to implement this in a way that works going forward? I don’t want to have to rewrite this code in Meteor 1.4 or whatever. :slight_smile:

Thanks.