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 () {
|
(function () {
|
||||||
// By default, try to connect back to the same endpoint as the page
|
// By default, try to connect back to the same endpoint as the page
|
||||||
// was served from.
|
// was served from.
|
||||||
var ddp_endpoint = '/';
|
var ddpUrl = '/';
|
||||||
if (typeof __meteor_runtime_config__ !== "undefined" &&
|
if (typeof __meteor_runtime_config__ !== "undefined") {
|
||||||
__meteor_runtime_config__.DEFAULT_DDP_ENDPOINT)
|
if (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL)
|
||||||
ddp_endpoint = __meteor_runtime_config__.DEFAULT_DDP_ENDPOINT;
|
ddpUrl = __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL;
|
||||||
|
}
|
||||||
|
|
||||||
_.extend(Meteor, {
|
_.extend(Meteor, {
|
||||||
default_connection: Meteor.connect(ddp_endpoint,
|
default_connection: Meteor.connect(ddpUrl, true /* restart_on_update */),
|
||||||
true /* restart_on_update */),
|
|
||||||
|
|
||||||
refresh: function (notification) {
|
refresh: function (notification) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ if (Meteor.isServer) {
|
|||||||
// we can't do recursive Meteor.autosubscribe().
|
// we can't do recursive Meteor.autosubscribe().
|
||||||
var captureSubs = null;
|
var captureSubs = null;
|
||||||
|
|
||||||
// @param url {String|Object} URL to Meteor app or sockjs endpoint (deprecated),
|
// @param url {String|Object} URL to Meteor app,
|
||||||
// or an object as a test hook (see code)
|
// or an object as a test hook (see code)
|
||||||
// Options:
|
// Options:
|
||||||
// reloadOnUpdate: should we try to reload when the server says
|
// reloadOnUpdate: should we try to reload when the server says
|
||||||
// there's new code available?
|
// 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.
|
// as a test hook, allow passing a stream instead of a url.
|
||||||
if (typeof url === "object") {
|
if (typeof url === "object") {
|
||||||
self._stream = url;
|
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 {
|
} else {
|
||||||
self._stream = new Meteor._Stream(url);
|
self._stream = new Meteor._Stream(url);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
if (process.env.DEFAULT_DDP_ENDPOINT)
|
if (process.env.DDP_DEFAULT_CONNECTION_URL) {
|
||||||
__meteor_runtime_config__.DEFAULT_DDP_ENDPOINT = process.env.DEFAULT_DDP_ENDPOINT;
|
__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL =
|
||||||
|
process.env.DDP_DEFAULT_CONNECTION_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_.extend(Meteor, {
|
_.extend(Meteor, {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Meteor._Stream = function (url) {
|
Meteor._Stream = function (url) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.url = Meteor._Stream._toSockjsUrl(url);
|
self.rawUrl = url;
|
||||||
self.socket = null;
|
self.socket = null;
|
||||||
self.event_callbacks = {}; // name -> [callback]
|
self.event_callbacks = {}; // name -> [callback]
|
||||||
self.server_id = null;
|
self.server_id = null;
|
||||||
@@ -63,9 +63,12 @@ Meteor._Stream = function (url) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_.extend(Meteor._Stream, {
|
_.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.
|
// @returns {String} URL to the sockjs endpoint, e.g.
|
||||||
// "http://subdomain.meteor.com/sockjs" or "/sockjs"
|
// "http://subdomain.meteor.com/sockjs" or "/sockjs"
|
||||||
|
// or "https://ddp--1234-foo.meteor.com/sockjs"
|
||||||
_toSockjsUrl: function(url) {
|
_toSockjsUrl: function(url) {
|
||||||
// XXX from Underscore.String (http://epeli.github.com/underscore.string/)
|
// XXX from Underscore.String (http://epeli.github.com/underscore.string/)
|
||||||
var startsWith = function(str, starts) {
|
var startsWith = function(str, starts) {
|
||||||
@@ -77,14 +80,32 @@ _.extend(Meteor._Stream, {
|
|||||||
str.substring(str.length - ends.length) === ends;
|
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
|
// Prefix FQDNs but not relative URLs
|
||||||
if (url.indexOf("://") === -1 && !startsWith(url, "/")) {
|
if (url.indexOf("://") === -1 && !startsWith(url, "/")) {
|
||||||
url = "http://" + url;
|
url = "http://" + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endsWith(url, "/sockjs"))
|
if (endsWith(url, "/"))
|
||||||
return url;
|
|
||||||
else if (endsWith(url, "/"))
|
|
||||||
return url + "sockjs";
|
return url + "sockjs";
|
||||||
else
|
else
|
||||||
return url + "/sockjs";
|
return url + "/sockjs";
|
||||||
@@ -311,12 +332,17 @@ _.extend(Meteor._Stream.prototype, {
|
|||||||
var self = this;
|
var self = this;
|
||||||
self._cleanup_socket(); // cleanup the old socket, if there was one.
|
self._cleanup_socket(); // cleanup the old socket, if there was one.
|
||||||
|
|
||||||
self.socket = new SockJS(self.url, undefined, {
|
// Convert raw URL to SockJS URL each time we open a connection, so that we
|
||||||
debug: false, protocols_whitelist: [
|
// can connect to random hostnames and get around browser per-host
|
||||||
// only allow polling protocols. no websockets or streaming.
|
// connection limits.
|
||||||
// streaming makes safari spin, and websockets hurt chrome.
|
self.socket = new SockJS(
|
||||||
'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'
|
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) {
|
self.socket.onmessage = function (data) {
|
||||||
// first message we get when we're connecting goes to _connected,
|
// first message we get when we're connecting goes to _connected,
|
||||||
// which connects us. All subsequent messages (while connected) go to
|
// which connects us. All subsequent messages (while connected) go to
|
||||||
|
|||||||
Reference in New Issue
Block a user