mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Support streamed response from SocketNodeInstance
This commit is contained in:
@@ -78,14 +78,29 @@
|
||||
var invocation = JSON.parse(line);
|
||||
var invokedModule = dynamicRequire(path.resolve(process.cwd(), invocation.moduleName));
|
||||
var invokedFunction = invocation.exportedFunctionName ? invokedModule[invocation.exportedFunctionName] : invokedModule;
|
||||
// Actually invoke it, passing the callback followed by any supplied args
|
||||
// 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) {
|
||||
|
||||
@@ -37,19 +37,41 @@ namespace Microsoft.AspNetCore.NodeServices
|
||||
await EnsureReady();
|
||||
var virtualConnectionClient = await GetOrCreateVirtualConnectionClientAsync();
|
||||
|
||||
using (var virtualConnection = _currentVirtualConnectionClient.OpenVirtualConnection())
|
||||
bool shouldDisposeVirtualConnection = true;
|
||||
Stream virtualConnection = null;
|
||||
try
|
||||
{
|
||||
virtualConnection = _currentVirtualConnectionClient.OpenVirtualConnection();
|
||||
|
||||
// Send request
|
||||
await WriteJsonLineAsync(virtualConnection, invocationInfo);
|
||||
|
||||
// Receive response
|
||||
var response = await ReadJsonAsync<RpcResponse<T>>(virtualConnection);
|
||||
if (response.ErrorMessage != null)
|
||||
// Determine what kind of response format is expected
|
||||
if (typeof(T) == typeof(Stream))
|
||||
{
|
||||
throw new NodeInvocationException(response.ErrorMessage, response.ErrorDetails);
|
||||
// Pass through streamed binary response
|
||||
// It is up to the consumer to dispose this stream, so don't do so here
|
||||
shouldDisposeVirtualConnection = false;
|
||||
return (T)(object)virtualConnection;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse and return non-streamed JSON response
|
||||
var response = await ReadJsonAsync<RpcJsonResponse<T>>(virtualConnection);
|
||||
if (response.ErrorMessage != null)
|
||||
{
|
||||
throw new NodeInvocationException(response.ErrorMessage, response.ErrorDetails);
|
||||
}
|
||||
|
||||
return response.Result;
|
||||
return response.Result;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (shouldDisposeVirtualConnection)
|
||||
{
|
||||
virtualConnection.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +202,7 @@ namespace Microsoft.AspNetCore.NodeServices
|
||||
}
|
||||
|
||||
#pragma warning disable 649 // These properties are populated via JSON deserialization
|
||||
private class RpcResponse<TResult>
|
||||
private class RpcJsonResponse<TResult>
|
||||
{
|
||||
public TResult Result { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
@@ -29,14 +29,32 @@ virtualConnectionServer.createInterface(server).on('connection', (connection: Du
|
||||
const invokedModule = dynamicRequire(path.resolve(process.cwd(), invocation.moduleName));
|
||||
const invokedFunction = invocation.exportedFunctionName ? invokedModule[invocation.exportedFunctionName] : invokedModule;
|
||||
|
||||
// Actually invoke it, passing the callback followed by any supplied args
|
||||
// Prepare a callback for accepting non-streamed JSON responses
|
||||
let hasInvokedCallback = false;
|
||||
const invocationCallback = (errorValue, successValue) => {
|
||||
if (hasInvokedCallback) {
|
||||
throw new Error('Cannot supply more than one result. The callback has already been invoked,'
|
||||
+ ' or the result stream has already been accessed');
|
||||
}
|
||||
|
||||
hasInvokedCallback = 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: (): Duplex => {
|
||||
hasInvokedCallback = true;
|
||||
return connection;
|
||||
}
|
||||
});
|
||||
|
||||
// Actually invoke it, passing through any supplied args
|
||||
invokedFunction.apply(null, [invocationCallback].concat(invocation.args));
|
||||
} catch (ex) {
|
||||
connection.end(JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user