mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Implement "ddp+sockjs://" and "ddpi+sockjs://" URLs for Meteor.connect.
This is not yet documented or fully supported (ie, it may change before 1.0). ddp+sockjs:// URLs are translated into https:// URLs and explicitly contain the "/sockjs" endpoint. Any '*' in the hostname should be changed into a random digit before opening a SockJS connection, to help avoid browser per-hostname connection limits. ddpi+sockjs:// is identical but uses http:// instead. The DEFAULT_DDP_ENDPOINT environment variable has been renamed DDP_DEFAULT_CONNECTION_URL. (For now, 'meteor deploy' will continue to also provide non-"ddp+sockjs://" URLs in the old environment variable so that old apps continue to work).
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
(function () {
|
||||
// By default, try to connect back to the same endpoint as the page
|
||||
// was served from.
|
||||
var ddp_endpoint = '/';
|
||||
if (typeof __meteor_runtime_config__ !== "undefined" &&
|
||||
__meteor_runtime_config__.DEFAULT_DDP_ENDPOINT)
|
||||
ddp_endpoint = __meteor_runtime_config__.DEFAULT_DDP_ENDPOINT;
|
||||
var ddpUrl = '/';
|
||||
if (typeof __meteor_runtime_config__ !== "undefined") {
|
||||
if (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL)
|
||||
ddpUrl = __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL;
|
||||
}
|
||||
|
||||
_.extend(Meteor, {
|
||||
default_connection: Meteor.connect(ddp_endpoint,
|
||||
true /* restart_on_update */),
|
||||
default_connection: Meteor.connect(ddpUrl, true /* restart_on_update */),
|
||||
|
||||
refresh: function (notification) {
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ if (Meteor.isServer) {
|
||||
// we can't do recursive Meteor.autosubscribe().
|
||||
var captureSubs = null;
|
||||
|
||||
// @param url {String|Object} URL to Meteor app or sockjs endpoint (deprecated),
|
||||
// or an object as a test hook (see code)
|
||||
// @param url {String|Object} URL to Meteor app,
|
||||
// or an object as a test hook (see code)
|
||||
// Options:
|
||||
// reloadOnUpdate: should we try to reload when the server says
|
||||
// there's new code available?
|
||||
@@ -30,9 +30,6 @@ Meteor._LivedataConnection = function (url, options) {
|
||||
// as a test hook, allow passing a stream instead of a url.
|
||||
if (typeof url === "object") {
|
||||
self._stream = url;
|
||||
// if we have two test streams, auto reload stuff will break because
|
||||
// the url is used as a key for the migration data.
|
||||
url = "/debug";
|
||||
} else {
|
||||
self._stream = new Meteor._Stream(url);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
if (process.env.DEFAULT_DDP_ENDPOINT)
|
||||
__meteor_runtime_config__.DEFAULT_DDP_ENDPOINT = process.env.DEFAULT_DDP_ENDPOINT;
|
||||
if (process.env.DDP_DEFAULT_CONNECTION_URL) {
|
||||
__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL =
|
||||
process.env.DDP_DEFAULT_CONNECTION_URL;
|
||||
}
|
||||
|
||||
|
||||
_.extend(Meteor, {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Meteor._Stream = function (url) {
|
||||
var self = this;
|
||||
|
||||
self.url = Meteor._Stream._toSockjsUrl(url);
|
||||
self.rawUrl = url;
|
||||
self.socket = null;
|
||||
self.event_callbacks = {}; // name -> [callback]
|
||||
self.server_id = null;
|
||||
@@ -63,9 +63,12 @@ Meteor._Stream = function (url) {
|
||||
};
|
||||
|
||||
_.extend(Meteor._Stream, {
|
||||
// @param url {String} URL to Meteor app, or to sockjs endpoint (deprecated)
|
||||
// @param url {String} URL to Meteor app, eg:
|
||||
// "/" or "madewith.meteor.com" or "https://foo.meteor.com"
|
||||
// or "ddp+sockjs://ddp--****-foo.meteor.com/sockjs"
|
||||
// @returns {String} URL to the sockjs endpoint, e.g.
|
||||
// "http://subdomain.meteor.com/sockjs" or "/sockjs"
|
||||
// or "https://ddp--1234-foo.meteor.com/sockjs"
|
||||
_toSockjsUrl: function(url) {
|
||||
// XXX from Underscore.String (http://epeli.github.com/underscore.string/)
|
||||
var startsWith = function(str, starts) {
|
||||
@@ -77,14 +80,32 @@ _.extend(Meteor._Stream, {
|
||||
str.substring(str.length - ends.length) === ends;
|
||||
};
|
||||
|
||||
var ddpUrlMatch = url.match(/^ddp(i?)\+sockjs:\/\//);
|
||||
if (ddpUrlMatch) {
|
||||
// Remove scheme and split off the host.
|
||||
var urlAfterDDP = url.substr(ddpUrlMatch[0].length);
|
||||
var newScheme = ddpUrlMatch[1] === 'i' ? 'http' : 'https';
|
||||
var slashPos = urlAfterDDP.indexOf('/');
|
||||
var host =
|
||||
slashPos === -1 ? urlAfterDDP : urlAfterDDP.substr(0, slashPos);
|
||||
var rest = slashPos === -1 ? '' : urlAfterDDP.substr(slashPos);
|
||||
|
||||
// In the host (ONLY!), change '*' characters into random digits. This
|
||||
// allows different stream connections to connect to different hostnames
|
||||
// and avoid browser per-hostname connection limits.
|
||||
host = host.replace(/\*/g, function () {
|
||||
return Math.floor(Math.random()*10);
|
||||
});
|
||||
|
||||
return newScheme + '://' + host + rest;
|
||||
}
|
||||
|
||||
// Prefix FQDNs but not relative URLs
|
||||
if (url.indexOf("://") === -1 && !startsWith(url, "/")) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
|
||||
if (endsWith(url, "/sockjs"))
|
||||
return url;
|
||||
else if (endsWith(url, "/"))
|
||||
if (endsWith(url, "/"))
|
||||
return url + "sockjs";
|
||||
else
|
||||
return url + "/sockjs";
|
||||
@@ -311,12 +332,17 @@ _.extend(Meteor._Stream.prototype, {
|
||||
var self = this;
|
||||
self._cleanup_socket(); // cleanup the old socket, if there was one.
|
||||
|
||||
self.socket = new SockJS(self.url, undefined, {
|
||||
debug: false, protocols_whitelist: [
|
||||
// only allow polling protocols. no websockets or streaming.
|
||||
// streaming makes safari spin, and websockets hurt chrome.
|
||||
'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'
|
||||
]});
|
||||
// Convert raw URL to SockJS URL each time we open a connection, so that we
|
||||
// can connect to random hostnames and get around browser per-host
|
||||
// connection limits.
|
||||
self.socket = new SockJS(
|
||||
Meteor._Stream._toSockjsUrl(self.rawUrl),
|
||||
undefined, {
|
||||
debug: false, protocols_whitelist: [
|
||||
// only allow polling protocols. no websockets or streaming.
|
||||
// streaming makes safari spin, and websockets hurt chrome.
|
||||
'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'
|
||||
]});
|
||||
self.socket.onmessage = function (data) {
|
||||
// first message we get when we're connecting goes to _connected,
|
||||
// which connects us. All subsequent messages (while connected) go to
|
||||
|
||||
Reference in New Issue
Block a user