Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix accounts package using wrong server #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,55 @@
Meteor Remote DDP
=================

When building apps with decoupled client-code and server-code (say mobile apps, for example), your client tries to connect to its own DDP server by default. And performs all the Meteor methods (Meteor.call, Meteor.subscribe, etc.) to this endpoint.
This package just allows you to specify a remote DDP server for all of that.
When building apps with decoupled client-code and server-code (say mobile apps, for example), your client connects via DDP to its own server by default.

This package allows you to specify a remote DDP server for Accounts, subscriptions and Meteor methods.

This package is quite brittle. It relies heavily on private APIs and monkey patching.

Installation
------------

``` sh
meteor add gwendall:remote-ddp
```
git clone https://github.com/BudgieInWA/meteor-remote-ddp.git packages/meteor-ddp
meteor add budgie:remote-ddp
```

How-to
----------
If you use accounts-base, or any dependant package, you must edit `.meteor/packages` to move `budgie:remote-ddp` above any such packages.

Usage
-----

Add the remote to your settings JSON file:

``` json
{
"public": {
"remoteDdpUrl": "http://localhost:5000"
}
}
```

In your client code, before doing anything that uses DDP, initialise RemoteDDP:

**RemoteDDP(url)**
``` javascript
RemoteDDP("http://localhost:5000");
// You can now call any Meteor method (call, subscribe, etc.) and it will all point to this server
RemoteDDP.monkeyPatch();
```

Launch Meteor using your settings file:

``` sh
meteor --settings settings.json
```

Notes
-----

- Based on [gwendall:remote-ddp](https://github.com/gwendall/meteor-remote-ddp).
- Does not work in Cordova. To access a different server, use the --mobile-server flag instead.
- Inspired by @jamgold's [solution](https://github.com/meteor/meteor/issues/3852#issuecomment-78699162).
- I don't know about Mongo.Collection support.

To do
To Do
-----
- Implement patch for OAUTH login (right now, accounts-facebook, accounts-twitter, etc point to client's server by default)
- Maybe monkey-patch Mongo.Collection so that it automatically picks the new Meteor.connection

- Publish to atmosphere?
33 changes: 23 additions & 10 deletions lib.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
RemoteDDP = function(url) {
RemoteDDP = {};

var connection = DDP.connect(url);
if (typeof Accounts !== 'undefined') {
throw new Error("remote-ddp is loaded after accounts-base. Make remote-ddp load before " +
"accounts-base by placing it earlier in your .meteor/packages file.");
}

/**
* Monkey-patch everything that we can think of with the new connection.
*
* @returns {Connection} - The DDP connection.
*/
RemoteDDP.monkeyPatch = function() {

// If accounts-base is loaded, then we told it to use our URL and it created a connection
// that we should use.
var connection;
if (typeof Accounts === 'undefined') {
connection = DDP.connect(Meteor.settings.public.remoteDdpUrl);
} else {
connection = Accounts.connection;
}

// Replace base connections
// Replace base connection.
Meteor.connection = connection;
Accounts.connection = connection;

// Patch methods
// Patch methods.
var methods = ["subscribe", "call", "apply", "methods", "status", "reconnect", "disconnect", "onReconnect"];
methods.forEach(function(method) {
Meteor[method] = function() {
return connection[method].apply(connection, arguments);
};
});

// Reset the users collection
Meteor.users = new Mongo.Collection("users", { connection: connection });

// Return the connection
return connection;

}
12 changes: 8 additions & 4 deletions package.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
Package.describe({
name: "gwendall:remote-ddp",
summary: "Get your client point to any DDP server",
summary: "Make your client seamlessly connect to a different server",
git: "https://github.com/gwendall/meteor-remote-ddp.git",
version: "0.1.0"
version: "0.2.0",
});

Package.onUse(function (api, where) {
Package.onUse(function(api) {

api.use([
"ddp",
"mongo@1.1.0",
"underscore@1.0.3",
"accounts-base@1.2.0"
], "client");

api.addFiles([
"lib.js",
], "client");

api.addFiles([
"server.js",
], "server");

api.export("RemoteDDP", "client");

});
11 changes: 11 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Monkey patch the accounts-base package so that it uses the right connection URL from the
// beginning. This object is sent to the client. This is needed because a connection is made
// at package load time to attempt a "resume" login. Without this, that attempt gets sent to
// this server's connection, instead of the remote connection.
if (Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.remoteDdpUrl) {
__meteor_runtime_config__.ACCOUNTS_CONNECTION_URL = Meteor.settings.public.remoteDdpUrl;
} else {
throw new Error("remote-ddp: Meteor.settings.public.remoteDdpUrl is missing.");
}