mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Split out 'socket' hosting model into a separate optional NuGet package, since most developers won't need it
This commit is contained in:
@@ -2,6 +2,7 @@ versionSuffix=$1
|
|||||||
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
projects=(
|
projects=(
|
||||||
./src/Microsoft.AspNetCore.NodeServices
|
./src/Microsoft.AspNetCore.NodeServices
|
||||||
|
./src/Microsoft.AspNetCore.NodeServices.Sockets
|
||||||
./src/Microsoft.AspNetCore.SpaServices
|
./src/Microsoft.AspNetCore.SpaServices
|
||||||
./src/Microsoft.AspNetCore.AngularServices
|
./src/Microsoft.AspNetCore.AngularServices
|
||||||
./src/Microsoft.AspNetCore.ReactServices
|
./src/Microsoft.AspNetCore.ReactServices
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.NodeServices;
|
using Microsoft.AspNetCore.NodeServices;
|
||||||
|
using Microsoft.AspNetCore.NodeServices.Sockets;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace ConsoleApplication
|
namespace ConsoleApplication
|
||||||
@@ -16,6 +17,10 @@ namespace ConsoleApplication
|
|||||||
// Set up the DI system
|
// Set up the DI system
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddNodeServices(options => {
|
services.AddNodeServices(options => {
|
||||||
|
// To compare with Socket hosting, uncomment the following line
|
||||||
|
// Since .NET Core 1.1, the HTTP hosting model has become basically as fast as the Socket hosting model
|
||||||
|
//options.UseSocketHosting();
|
||||||
|
|
||||||
options.ProjectPath = Directory.GetCurrentDirectory();
|
options.ProjectPath = Directory.GetCurrentDirectory();
|
||||||
options.WatchFileExtensions = new string[] {}; // Don't watch anything
|
options.WatchFileExtensions = new string[] {}; // Don't watch anything
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"type": "platform"
|
"type": "platform"
|
||||||
},
|
},
|
||||||
"Microsoft.AspNetCore.NodeServices": "1.1.0-*",
|
"Microsoft.AspNetCore.NodeServices": "1.1.0-*",
|
||||||
|
"Microsoft.AspNetCore.NodeServices.Sockets": "1.1.0-*",
|
||||||
"Microsoft.Extensions.DependencyInjection": "1.1.0"
|
"Microsoft.Extensions.DependencyInjection": "1.1.0"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
|
|||||||
3
src/Microsoft.AspNetCore.NodeServices.Sockets/.gitignore
vendored
Normal file
3
src/Microsoft.AspNetCore.NodeServices.Sockets/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/bin/
|
||||||
|
/node_modules/
|
||||||
|
yarn.lock
|
||||||
@@ -44,11 +44,81 @@
|
|||||||
/* 0 */
|
/* 0 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
module.exports = __webpack_require__(7);
|
module.exports = __webpack_require__(1);
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 1 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
||||||
|
// but simplifies things for the consumer of this module.
|
||||||
|
__webpack_require__(2);
|
||||||
|
var net = __webpack_require__(3);
|
||||||
|
var path = __webpack_require__(4);
|
||||||
|
var readline = __webpack_require__(5);
|
||||||
|
var ArgsUtil_1 = __webpack_require__(6);
|
||||||
|
var ExitWhenParentExits_1 = __webpack_require__(7);
|
||||||
|
var virtualConnectionServer = __webpack_require__(8);
|
||||||
|
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
||||||
|
// reference to Node's runtime 'require' function.
|
||||||
|
var dynamicRequire = eval('require');
|
||||||
|
// Signal to the .NET side when we're ready to accept invocations
|
||||||
|
var server = net.createServer().on('listening', function () {
|
||||||
|
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
|
||||||
|
});
|
||||||
|
// Each virtual connection represents a separate invocation
|
||||||
|
virtualConnectionServer.createInterface(server).on('connection', function (connection) {
|
||||||
|
readline.createInterface(connection, null).on('line', function (line) {
|
||||||
|
try {
|
||||||
|
// Get a reference to the function to invoke
|
||||||
|
var invocation = JSON.parse(line);
|
||||||
|
var invokedModule = dynamicRequire(path.resolve(process.cwd(), invocation.moduleName));
|
||||||
|
var invokedFunction = invocation.exportedFunctionName ? invokedModule[invocation.exportedFunctionName] : invokedModule;
|
||||||
|
// Prepare a callback for accepting non-streamed JSON responses
|
||||||
|
var hasInvokedCallback_1 = false;
|
||||||
|
var invocationCallback = function (errorValue, successValue) {
|
||||||
|
if (hasInvokedCallback_1) {
|
||||||
|
throw new Error('Cannot supply more than one result. The callback has already been invoked,'
|
||||||
|
+ ' or the result stream has already been accessed');
|
||||||
|
}
|
||||||
|
hasInvokedCallback_1 = true;
|
||||||
|
connection.end(JSON.stringify({
|
||||||
|
result: successValue,
|
||||||
|
errorMessage: errorValue && (errorValue.message || errorValue),
|
||||||
|
errorDetails: errorValue && (errorValue.stack || null)
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
// Also support streamed binary responses
|
||||||
|
Object.defineProperty(invocationCallback, 'stream', {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
hasInvokedCallback_1 = true;
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Actually invoke it, passing through any supplied args
|
||||||
|
invokedFunction.apply(null, [invocationCallback].concat(invocation.args));
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
connection.end(JSON.stringify({
|
||||||
|
errorMessage: ex.message,
|
||||||
|
errorDetails: ex.stack
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Begin listening now. The underlying transport varies according to the runtime platform.
|
||||||
|
// On Windows it's Named Pipes; on Linux/OSX it's Domain Sockets.
|
||||||
|
var useWindowsNamedPipes = /^win/.test(process.platform);
|
||||||
|
var parsedArgs = ArgsUtil_1.parseArgs(process.argv);
|
||||||
|
var listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.listenAddress;
|
||||||
|
server.listen(listenAddress);
|
||||||
|
ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid));
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 1 */,
|
|
||||||
/* 2 */
|
/* 2 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
@@ -90,7 +160,12 @@
|
|||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 3 */,
|
/* 3 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("net");
|
||||||
|
|
||||||
|
/***/ },
|
||||||
/* 4 */
|
/* 4 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
@@ -98,6 +173,12 @@
|
|||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 5 */
|
/* 5 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("readline");
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 6 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -123,7 +204,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 6 */
|
/* 7 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -189,96 +270,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
|
||||||
/* 7 */
|
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
|
||||||
// but simplifies things for the consumer of this module.
|
|
||||||
__webpack_require__(2);
|
|
||||||
var net = __webpack_require__(8);
|
|
||||||
var path = __webpack_require__(4);
|
|
||||||
var readline = __webpack_require__(9);
|
|
||||||
var ArgsUtil_1 = __webpack_require__(5);
|
|
||||||
var ExitWhenParentExits_1 = __webpack_require__(6);
|
|
||||||
var virtualConnectionServer = __webpack_require__(10);
|
|
||||||
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
|
||||||
// reference to Node's runtime 'require' function.
|
|
||||||
var dynamicRequire = eval('require');
|
|
||||||
// Signal to the .NET side when we're ready to accept invocations
|
|
||||||
var server = net.createServer().on('listening', function () {
|
|
||||||
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
|
|
||||||
});
|
|
||||||
// Each virtual connection represents a separate invocation
|
|
||||||
virtualConnectionServer.createInterface(server).on('connection', function (connection) {
|
|
||||||
readline.createInterface(connection, null).on('line', function (line) {
|
|
||||||
try {
|
|
||||||
// Get a reference to the function to invoke
|
|
||||||
var invocation = JSON.parse(line);
|
|
||||||
var invokedModule = dynamicRequire(path.resolve(process.cwd(), invocation.moduleName));
|
|
||||||
var invokedFunction = invocation.exportedFunctionName ? invokedModule[invocation.exportedFunctionName] : invokedModule;
|
|
||||||
// Prepare a callback for accepting non-streamed JSON responses
|
|
||||||
var hasInvokedCallback_1 = false;
|
|
||||||
var invocationCallback = function (errorValue, successValue) {
|
|
||||||
if (hasInvokedCallback_1) {
|
|
||||||
throw new Error('Cannot supply more than one result. The callback has already been invoked,'
|
|
||||||
+ ' or the result stream has already been accessed');
|
|
||||||
}
|
|
||||||
hasInvokedCallback_1 = true;
|
|
||||||
connection.end(JSON.stringify({
|
|
||||||
result: successValue,
|
|
||||||
errorMessage: errorValue && (errorValue.message || errorValue),
|
|
||||||
errorDetails: errorValue && (errorValue.stack || null)
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
// Also support streamed binary responses
|
|
||||||
Object.defineProperty(invocationCallback, 'stream', {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
hasInvokedCallback_1 = true;
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Actually invoke it, passing through any supplied args
|
|
||||||
invokedFunction.apply(null, [invocationCallback].concat(invocation.args));
|
|
||||||
}
|
|
||||||
catch (ex) {
|
|
||||||
connection.end(JSON.stringify({
|
|
||||||
errorMessage: ex.message,
|
|
||||||
errorDetails: ex.stack
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// Begin listening now. The underlying transport varies according to the runtime platform.
|
|
||||||
// On Windows it's Named Pipes; on Linux/OSX it's Domain Sockets.
|
|
||||||
var useWindowsNamedPipes = /^win/.test(process.platform);
|
|
||||||
var parsedArgs = ArgsUtil_1.parseArgs(process.argv);
|
|
||||||
var listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.listenAddress;
|
|
||||||
server.listen(listenAddress);
|
|
||||||
ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid));
|
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 8 */
|
/* 8 */
|
||||||
/***/ function(module, exports) {
|
|
||||||
|
|
||||||
module.exports = require("net");
|
|
||||||
|
|
||||||
/***/ },
|
|
||||||
/* 9 */
|
|
||||||
/***/ function(module, exports) {
|
|
||||||
|
|
||||||
module.exports = require("readline");
|
|
||||||
|
|
||||||
/***/ },
|
|
||||||
/* 10 */
|
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
var events_1 = __webpack_require__(11);
|
var events_1 = __webpack_require__(9);
|
||||||
var VirtualConnection_1 = __webpack_require__(12);
|
var VirtualConnection_1 = __webpack_require__(10);
|
||||||
// Keep this in sync with the equivalent constant in the .NET code. Both sides split up their transmissions into frames with this max length,
|
// Keep this in sync with the equivalent constant in the .NET code. Both sides split up their transmissions into frames with this max length,
|
||||||
// and both will reject longer frames.
|
// and both will reject longer frames.
|
||||||
var MaxFrameBodyLength = 16 * 1024;
|
var MaxFrameBodyLength = 16 * 1024;
|
||||||
@@ -460,13 +458,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 11 */
|
/* 9 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
module.exports = require("events");
|
module.exports = require("events");
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 12 */
|
/* 10 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -475,17 +473,18 @@
|
|||||||
function __() { this.constructor = d; }
|
function __() { this.constructor = d; }
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
};
|
};
|
||||||
var stream_1 = __webpack_require__(13);
|
var stream_1 = __webpack_require__(11);
|
||||||
/**
|
/**
|
||||||
* Represents a virtual connection. Multiple virtual connections may be multiplexed over a single physical socket connection.
|
* Represents a virtual connection. Multiple virtual connections may be multiplexed over a single physical socket connection.
|
||||||
*/
|
*/
|
||||||
var VirtualConnection = (function (_super) {
|
var VirtualConnection = (function (_super) {
|
||||||
__extends(VirtualConnection, _super);
|
__extends(VirtualConnection, _super);
|
||||||
function VirtualConnection(_beginWriteCallback) {
|
function VirtualConnection(_beginWriteCallback) {
|
||||||
_super.call(this);
|
var _this = _super.call(this) || this;
|
||||||
this._beginWriteCallback = _beginWriteCallback;
|
_this._beginWriteCallback = _beginWriteCallback;
|
||||||
this._flowing = false;
|
_this._flowing = false;
|
||||||
this._receivedDataQueue = [];
|
_this._receivedDataQueue = [];
|
||||||
|
return _this;
|
||||||
}
|
}
|
||||||
VirtualConnection.prototype._read = function () {
|
VirtualConnection.prototype._read = function () {
|
||||||
this._flowing = true;
|
this._flowing = true;
|
||||||
@@ -516,7 +515,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 13 */
|
/* 11 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
module.exports = require("stream");
|
module.exports = require("stream");
|
||||||
@@ -2,7 +2,7 @@ using System.IO;
|
|||||||
using System.IO.Pipes;
|
using System.IO.Pipes;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections
|
namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
||||||
{
|
{
|
||||||
internal class NamedPipeConnection : StreamConnection
|
internal class NamedPipeConnection : StreamConnection
|
||||||
{
|
{
|
||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections
|
namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
||||||
{
|
{
|
||||||
internal abstract class StreamConnection : IDisposable
|
internal abstract class StreamConnection : IDisposable
|
||||||
{
|
{
|
||||||
@@ -2,7 +2,7 @@ using System.IO;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections
|
namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
||||||
{
|
{
|
||||||
internal class UnixDomainSocketConnection : StreamConnection
|
internal class UnixDomainSocketConnection : StreamConnection
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,7 @@ using System.Net;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections
|
namespace Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections
|
||||||
{
|
{
|
||||||
// From System.IO.Pipes/src/System/Net/Sockets/UnixDomainSocketEndPoint.cs (an internal class in System.IO.Pipes)
|
// From System.IO.Pipes/src/System/Net/Sockets/UnixDomainSocketEndPoint.cs (an internal class in System.IO.Pipes)
|
||||||
internal sealed class UnixDomainSocketEndPoint : EndPoint
|
internal sealed class UnixDomainSocketEndPoint : EndPoint
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections;
|
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels.VirtualConnections;
|
using Microsoft.AspNetCore.NodeServices.Sockets.PhysicalConnections;
|
||||||
|
using Microsoft.AspNetCore.NodeServices.Sockets.VirtualConnections;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
namespace Microsoft.AspNetCore.NodeServices.Sockets
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A specialisation of the OutOfProcessNodeInstance base class that uses a lightweight binary streaming protocol
|
/// A specialisation of the OutOfProcessNodeInstance base class that uses a lightweight binary streaming protocol
|
||||||
@@ -77,7 +76,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
// wait for the same connection task. There's no reason why the first caller should have the
|
// wait for the same connection task. There's no reason why the first caller should have the
|
||||||
// special ability to cancel the connection process in a way that would affect subsequent
|
// special ability to cancel the connection process in a way that would affect subsequent
|
||||||
// callers. So, each caller just independently stops awaiting connection if that call is cancelled.
|
// callers. So, each caller just independently stops awaiting connection if that call is cancelled.
|
||||||
await EnsureVirtualConnectionClientCreated().OrThrowOnCancellation(cancellationToken);
|
await ThrowOnCancellation(EnsureVirtualConnectionClientCreated(), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each invocation, we open a new virtual connection. This gives an API equivalent to opening a new
|
// For each invocation, we open a new virtual connection. This gives an API equivalent to opening a new
|
||||||
@@ -213,6 +212,17 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
return $"--listenAddress {listenAddress}";
|
return $"--listenAddress {listenAddress}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Task ThrowOnCancellation(Task task, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return task.IsCompleted
|
||||||
|
? task // If the task is already completed, no need to wrap it in a further layer of task
|
||||||
|
: task.ContinueWith(
|
||||||
|
_ => {}, // If the task completes, allow execution to continue
|
||||||
|
cancellationToken,
|
||||||
|
TaskContinuationOptions.ExecuteSynchronously,
|
||||||
|
TaskScheduler.Default);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma warning disable 649 // These properties are populated via JSON deserialization
|
#pragma warning disable 649 // These properties are populated via JSON deserialization
|
||||||
private class RpcJsonResponse<TResult>
|
private class RpcJsonResponse<TResult>
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.NodeServices.Sockets
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods that help with populating a <see cref="NodeServicesOptions"/> object.
|
||||||
|
/// </summary>
|
||||||
|
public static class NodeServicesOptionsExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Configures the <see cref="INodeServices"/> service so that it will use out-of-process
|
||||||
|
/// Node.js instances and perform RPC calls over binary sockets (on Windows, this is
|
||||||
|
/// implemented as named pipes; on other platforms it uses domain sockets).
|
||||||
|
/// </summary>
|
||||||
|
public static void UseSocketHosting(this NodeServicesOptions options)
|
||||||
|
{
|
||||||
|
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
|
||||||
|
options.NodeInstanceFactory = () => new SocketNodeInstance(options, pipeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
||||||
// but simplifies things for the consumer of this module.
|
// but simplifies things for the consumer of this module.
|
||||||
import './Util/OverrideStdOutputs';
|
import '../../Microsoft.AspNetCore.NodeServices/TypeScript/Util/OverrideStdOutputs';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as readline from 'readline';
|
import * as readline from 'readline';
|
||||||
import { Duplex } from 'stream';
|
import { Duplex } from 'stream';
|
||||||
import { parseArgs } from './Util/ArgsUtil';
|
import { parseArgs } from '../../Microsoft.AspNetCore.NodeServices/TypeScript/Util/ArgsUtil';
|
||||||
import { exitWhenParentExits } from './Util/ExitWhenParentExits';
|
import { exitWhenParentExits } from '../../Microsoft.AspNetCore.NodeServices/TypeScript/Util/ExitWhenParentExits';
|
||||||
import * as virtualConnectionServer from './VirtualConnections/VirtualConnectionServer';
|
import * as virtualConnectionServer from './VirtualConnections/VirtualConnectionServer';
|
||||||
|
|
||||||
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es3",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading.Tasks.Dataflow;
|
using System.Threading.Tasks.Dataflow;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels.VirtualConnections
|
namespace Microsoft.AspNetCore.NodeServices.Sockets.VirtualConnections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A virtual read/write connection, typically to a remote process. Multiple virtual connections can be
|
/// A virtual read/write connection, typically to a remote process. Multiple virtual connections can be
|
||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels.VirtualConnections
|
namespace Microsoft.AspNetCore.NodeServices.Sockets.VirtualConnections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A callback that will be invoked if the <see cref="VirtualConnectionClient"/> encounters a read error.
|
/// A callback that will be invoked if the <see cref="VirtualConnectionClient"/> encounters a read error.
|
||||||
18
src/Microsoft.AspNetCore.NodeServices.Sockets/package.json
Normal file
18
src/Microsoft.AspNetCore.NodeServices.Sockets/package.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "nodeservices.sockets",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "This is not really an NPM package and will not be published. This file exists only to reference compilation tools.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build": "./node_modules/.bin/webpack"
|
||||||
|
},
|
||||||
|
"author": "Microsoft",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^6.0.42",
|
||||||
|
"ts-loader": "^0.8.2",
|
||||||
|
"typescript": "^2.0.0",
|
||||||
|
"webpack": "^1.13.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/Microsoft.AspNetCore.NodeServices.Sockets/project.json
Normal file
39
src/Microsoft.AspNetCore.NodeServices.Sockets/project.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"description": "Socket-based RPC for Microsoft.AspNetCore.NodeServices",
|
||||||
|
"version": "1.1.0-*",
|
||||||
|
"packOptions": {
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/aspnet/javascriptservices"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"aspnetcore",
|
||||||
|
"aspnetcoremvc",
|
||||||
|
"nodeservices"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"buildOptions": {
|
||||||
|
"warningsAsErrors": true,
|
||||||
|
"keyFile": "../../tools/Key.snk",
|
||||||
|
"embed": [
|
||||||
|
"Content/**/*"
|
||||||
|
],
|
||||||
|
"xmlDoc": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNetCore.NodeServices": "1.1.0-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net451": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Tpl.Dataflow": "4.5.24"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"netstandard1.6": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.IO.Pipes": "4.3.0",
|
||||||
|
"System.Threading.Tasks.Dataflow": "4.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
module.exports = {
|
||||||
|
target: 'node',
|
||||||
|
externals: ['fs', 'net', 'events', 'readline', 'stream'],
|
||||||
|
resolve: {
|
||||||
|
extensions: [ '.ts' ]
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{ test: /\.ts$/, loader: 'ts-loader' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
entry: {
|
||||||
|
'entrypoint-socket': ['./TypeScript/SocketNodeInstanceEntryPoint'],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
libraryTarget: 'commonjs',
|
||||||
|
path: './Content/Node',
|
||||||
|
filename: '[name].js'
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
/bin/
|
/bin/
|
||||||
/node_modules/
|
/node_modules/
|
||||||
|
yarn.lock
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -15,16 +13,5 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
{
|
{
|
||||||
options.NodeInstanceFactory = () => new HttpNodeInstance(options);
|
options.NodeInstanceFactory = () => new HttpNodeInstance(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configures the <see cref="INodeServices"/> service so that it will use out-of-process
|
|
||||||
/// Node.js instances and perform RPC calls over binary sockets (on Windows, this is
|
|
||||||
/// implemented as named pipes; on other platforms it uses domain sockets).
|
|
||||||
/// </summary>
|
|
||||||
public static void UseSocketHosting(this NodeServicesOptions options)
|
|
||||||
{
|
|
||||||
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
|
|
||||||
options.NodeInstanceFactory = () => new SocketNodeInstance(options, pipeName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,17 +27,11 @@
|
|||||||
"NETStandard.Library": "1.6.1-*"
|
"NETStandard.Library": "1.6.1-*"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"net451": {
|
"net451": {},
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.Tpl.Dataflow": "4.5.24"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"netstandard1.6": {
|
"netstandard1.6": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Diagnostics.Process": "4.3.0",
|
"System.Diagnostics.Process": "4.3.0",
|
||||||
"System.IO.FileSystem.Watcher": "4.3.0",
|
"System.IO.FileSystem.Watcher": "4.3.0"
|
||||||
"System.IO.Pipes": "4.3.0",
|
|
||||||
"System.Threading.Tasks.Dataflow": "4.7.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
entry: {
|
entry: {
|
||||||
'entrypoint-http': ['./TypeScript/HttpNodeInstanceEntryPoint'],
|
'entrypoint-http': ['./TypeScript/HttpNodeInstanceEntryPoint']
|
||||||
'entrypoint-socket': ['./TypeScript/SocketNodeInstanceEntryPoint'],
|
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
libraryTarget: 'commonjs',
|
libraryTarget: 'commonjs',
|
||||||
|
|||||||
Reference in New Issue
Block a user