159 lines
5.0 KiB
JavaScript
159 lines
5.0 KiB
JavaScript
"use strict";
|
|
|
|
// Convert querystring name/value pairs into dictionary.
|
|
const QUERY_STRING = (function (a) {
|
|
if (a == '') return {};
|
|
const b = {};
|
|
for (let i = 0; i < a.length; ++i) {
|
|
const p = a[i].split('=', 2);
|
|
if (p.length == 1)
|
|
b[p[0]] = '';
|
|
else
|
|
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, ' '));
|
|
}
|
|
return b;
|
|
})(window.location.search.substr(1).split('&'));
|
|
function onReaderDataReceived(deviceType, data) {
|
|
console.log(data + '\n' + hexView(data));
|
|
}
|
|
|
|
// Name of group that the client will join on connection
|
|
const QSS_GROUP_NAME = 'DeviceUsers';
|
|
|
|
const SIGNALR_CONNECTION_STATE_LABEL = {
|
|
0: 'Connecting',
|
|
1: 'Connected',
|
|
2: 'Reconnecting',
|
|
4: 'Disconnected'
|
|
};
|
|
|
|
// A unified wrapper to handle both Framework and Core SignalR APIs.
|
|
const QSS_API_WRAPPER = {
|
|
connection: null,
|
|
type: null, // 'framework' or 'core'
|
|
deviceHubProxy: null, // only populated in 'framework'
|
|
|
|
// Map a server-side call
|
|
invokeServerMethod: function (methodName, ...args) {
|
|
if (this.type === 'framework') {
|
|
|
|
// Framework API call
|
|
return this.deviceHubProxy.invoke(methodName, ...args);
|
|
} else {
|
|
|
|
// Core API call
|
|
return this.connection.invoke(methodName, ...args);
|
|
}
|
|
},
|
|
|
|
// Map a client-side listener
|
|
onClientMethod: function (methodName, callback) {
|
|
if (this.type === 'framework') {
|
|
|
|
// Framework client-side listener
|
|
this.deviceHubProxy.on(methodName, callback);
|
|
} else {
|
|
|
|
// Core client-side listener
|
|
this.connection.on(methodName, callback);
|
|
}
|
|
}
|
|
};
|
|
|
|
function isNullEmptyOrWhitespace(value) {
|
|
if (value == null) {
|
|
return true;
|
|
}
|
|
if (typeof value === 'string') {
|
|
return value.trim().length === 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
async function startSignalR(callback) {
|
|
if (!('qssUrl' in QUERY_STRING) || isNullEmptyOrWhitespace(QUERY_STRING['qssUrl'])) {
|
|
console.warn('Missing "qssUrl" in query string');
|
|
return;
|
|
}
|
|
console.log('Attempting SignalR ASP.NET Framework connection...');
|
|
|
|
//
|
|
// ASP.NET Framework
|
|
//
|
|
|
|
QSS_API_WRAPPER.connection = $.hubConnection(QUERY_STRING['qssUrl'], { useDefaultPath: false });
|
|
QSS_API_WRAPPER.deviceHubProxy = QSS_API_WRAPPER.connection.createHubProxy('deviceHub');
|
|
|
|
// Redirect Framework events to event handlers provided in callback class
|
|
QSS_API_WRAPPER.connection.starting(function () {
|
|
callback.framework_starting();
|
|
});
|
|
QSS_API_WRAPPER.connection.received(function (data) {
|
|
callback.framework_received(data);
|
|
});
|
|
QSS_API_WRAPPER.connection.connectionSlow(function () {
|
|
callback.framework_connectionSlow();
|
|
});
|
|
QSS_API_WRAPPER.connection.reconnecting(function () {
|
|
callback.framework_reconnecting();
|
|
});
|
|
QSS_API_WRAPPER.connection.reconnected(function () {
|
|
callback.framework_reconnected();
|
|
});
|
|
QSS_API_WRAPPER.connection.stateChanged(function (change) {
|
|
callback.framework_stateChanged(change);
|
|
});
|
|
QSS_API_WRAPPER.connection.disconnected(function () {
|
|
callback.framework_disconnected();
|
|
});
|
|
|
|
try {
|
|
await new Promise((resolve, reject) => {
|
|
QSS_API_WRAPPER.connection.start()
|
|
.done(() => {
|
|
console.log("Connected to ASP.NET Framework SignalR!");
|
|
|
|
QSS_API_WRAPPER.deviceHubProxy.invoke('JoinGroup', QSS_GROUP_NAME)
|
|
.done(function () {
|
|
console.log('Joined group: ' + QSS_GROUP_NAME);
|
|
})
|
|
.fail(function (error) {
|
|
console.error('Invocation of JoinGroup failed. Error:', error);
|
|
});
|
|
|
|
resolve();
|
|
})
|
|
.fail((err) => {
|
|
reject(err);
|
|
});
|
|
});
|
|
QSS_API_WRAPPER.type = 'framework';
|
|
|
|
} catch (frameworkErr) {
|
|
console.warn("Framework connection failed. Trying ASP.NET Core...", frameworkErr);
|
|
|
|
//
|
|
// ASP.NET Core
|
|
//
|
|
|
|
QSS_API_WRAPPER.connection = new signalR.HubConnectionBuilder()
|
|
.withUrl(QUERY_STRING['qssUrl'])
|
|
.withAutomaticReconnect() // Required to perform automatic reconnects
|
|
.build();
|
|
|
|
// Redirect Core events to event handlers provided in callback class
|
|
QSS_API_WRAPPER.connection.onreconnecting(function (error) {
|
|
console.log('onreconnecting');
|
|
callback.core_onreconnecting(error);
|
|
});
|
|
QSS_API_WRAPPER.connection.onreconnected(function (connectionId) {
|
|
console.log('onreconnected');
|
|
callback.core_onreconnected(connectionId);
|
|
});
|
|
QSS_API_WRAPPER.connection.onclose(function (error) {
|
|
console.log('onclose');
|
|
callback.core_onclose(error);
|
|
});
|
|
|
|
try {
|
|
|