Last active
July 7, 2017 14:18
-
-
Save radu-matei/21595027670b3c7eaad478309075b26f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments)).next()); | |
}); | |
}; | |
(function (factory) { | |
if (typeof module === 'object' && typeof module.exports === 'object') { | |
var v = factory(require, exports); if (v !== undefined) module.exports = v; | |
} | |
else if (typeof define === 'function' && define.amd) { | |
define(["require", "exports", "./Observable", "./Transports", "./HttpConnection", "./JsonHubProtocol", "./Formatters"], factory); | |
} | |
})(function (require, exports) { | |
"use strict"; | |
const Observable_1 = require("./Observable"); | |
var Transports_1 = require("./Transports"); | |
exports.TransportType = Transports_1.TransportType; | |
var HttpConnection_1 = require("./HttpConnection"); | |
exports.HttpConnection = HttpConnection_1.HttpConnection; | |
const JsonHubProtocol_1 = require("./JsonHubProtocol"); | |
const Formatters_1 = require("./Formatters"); | |
class HubConnection { | |
constructor(connection) { | |
this.connection = connection; | |
this.connection.onDataReceived = data => { | |
this.onDataReceived(data); | |
}; | |
this.connection.onClosed = (error) => { | |
this.onConnectionClosed(error); | |
}; | |
this.callbacks = new Map(); | |
this.methods = new Map(); | |
this.id = 0; | |
this.protocol = new JsonHubProtocol_1.JsonHubProtocol(); | |
} | |
onDataReceived(data) { | |
// Parse the messages | |
let messages = this.protocol.parseMessages(data); | |
for (var i = 0; i < messages.length; ++i) { | |
var message = messages[i]; | |
switch (message.type) { | |
case 1 /* Invocation */: | |
this.invokeClientMethod(message); | |
break; | |
case 2 /* Result */: | |
case 3 /* Completion */: | |
let callback = this.callbacks.get(message.invocationId); | |
if (callback != null) { | |
callback(message); | |
if (message.type == 3 /* Completion */) { | |
this.callbacks.delete(message.invocationId); | |
} | |
} | |
break; | |
default: | |
console.log("Invalid message type: " + data); | |
break; | |
} | |
} | |
} | |
invokeClientMethod(invocationMessage) { | |
let method = this.methods.get(invocationMessage.target); | |
if (method) { | |
method.apply(this, invocationMessage.arguments); | |
if (!invocationMessage.nonblocking) { | |
} | |
} | |
else { | |
console.log(`No client method with the name '${invocationMessage.target}' found.`); | |
} | |
} | |
onConnectionClosed(error) { | |
let errorCompletionMessage = { | |
type: 3 /* Completion */, | |
invocationId: "-1", | |
error: error ? error.message : "Invocation cancelled due to connection being closed.", | |
}; | |
this.callbacks.forEach(callback => { | |
callback(errorCompletionMessage); | |
}); | |
this.callbacks.clear(); | |
if (this.connectionClosedCallback) { | |
this.connectionClosedCallback(error); | |
} | |
} | |
start() { | |
return __awaiter(this, void 0, void 0, function* () { | |
yield this.connection.start(); | |
yield this.connection.send(Formatters_1.TextMessageFormat.write(JSON.stringify({ protocol: this.protocol.name() }))); | |
}); | |
} | |
stop() { | |
return this.connection.stop(); | |
} | |
stream(methodName, ...args) { | |
let invocationDescriptor = this.createInvocation(methodName, args, false); | |
let subject = new Observable_1.Subject(); | |
this.callbacks.set(invocationDescriptor.invocationId, (invocationEvent) => { | |
if (invocationEvent.type === 3 /* Completion */) { | |
let completionMessage = invocationEvent; | |
if (completionMessage.error) { | |
subject.error(new Error(completionMessage.error)); | |
} | |
else if (completionMessage.result) { | |
subject.error(new Error("Server provided a result in a completion response to a streamed invocation.")); | |
} | |
else { | |
// TODO: Log a warning if there's a payload? | |
subject.complete(); | |
} | |
} | |
else { | |
subject.next(invocationEvent.item); | |
} | |
}); | |
let message = this.protocol.writeMessage(invocationDescriptor); | |
this.connection.send(message) | |
.catch(e => { | |
subject.error(e); | |
this.callbacks.delete(invocationDescriptor.invocationId); | |
}); | |
return subject; | |
} | |
send(methodName, ...args) { | |
let invocationDescriptor = this.createInvocation(methodName, args, true); | |
let message = this.protocol.writeMessage(invocationDescriptor); | |
return this.connection.send(message); | |
} | |
invoke(methodName, ...args) { | |
let invocationDescriptor = this.createInvocation(methodName, args, false); | |
let p = new Promise((resolve, reject) => { | |
this.callbacks.set(invocationDescriptor.invocationId, (invocationEvent) => { | |
if (invocationEvent.type === 3 /* Completion */) { | |
let completionMessage = invocationEvent; | |
if (completionMessage.error) { | |
reject(new Error(completionMessage.error)); | |
} | |
else { | |
resolve(completionMessage.result); | |
} | |
} | |
else { | |
reject(new Error("Streaming methods must be invoked using HubConnection.stream")); | |
} | |
}); | |
let message = this.protocol.writeMessage(invocationDescriptor); | |
this.connection.send(message) | |
.catch(e => { | |
reject(e); | |
this.callbacks.delete(invocationDescriptor.invocationId); | |
}); | |
}); | |
return p; | |
} | |
on(methodName, method) { | |
this.methods.set(methodName, method); | |
} | |
set onClosed(callback) { | |
this.connectionClosedCallback = callback; | |
} | |
createInvocation(methodName, args, nonblocking) { | |
let id = this.id; | |
this.id++; | |
return { | |
type: 1 /* Invocation */, | |
invocationId: id.toString(), | |
target: methodName, | |
arguments: args, | |
nonblocking: nonblocking | |
}; | |
} | |
} | |
exports.HubConnection = HubConnection; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment