Add SignalR extensions sample for JS V4 model (#252)
This commit is contained in:
Родитель
d688eb9693
Коммит
41f8ef74c6
|
@ -0,0 +1,10 @@
|
|||
*.js.map
|
||||
*.ts
|
||||
.git*
|
||||
.vscode
|
||||
local.settings.json
|
||||
test
|
||||
getting_started.md
|
||||
node_modules/@types/
|
||||
node_modules/azure-functions-core-tools/
|
||||
node_modules/typescript/
|
|
@ -0,0 +1,48 @@
|
|||
bin
|
||||
obj
|
||||
csx
|
||||
.vs
|
||||
edge
|
||||
Publish
|
||||
|
||||
*.user
|
||||
*.suo
|
||||
*.cscfg
|
||||
*.Cache
|
||||
project.lock.json
|
||||
|
||||
/packages
|
||||
/TestResults
|
||||
|
||||
/tools/NuGet.exe
|
||||
/App_Data
|
||||
/secrets
|
||||
/data
|
||||
.secrets
|
||||
appsettings.json
|
||||
local.settings.json
|
||||
|
||||
node_modules
|
||||
dist
|
||||
|
||||
# Local python packages
|
||||
.python_packages/
|
||||
|
||||
# Python Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# Azurite artifacts
|
||||
__blobstorage__
|
||||
__queuestorage__
|
||||
__azurite_db*__.json
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"logging": {
|
||||
"applicationInsights": {
|
||||
"samplingSettings": {
|
||||
"isEnabled": true,
|
||||
"excludedTypes": "Request"
|
||||
}
|
||||
},
|
||||
"logLevel": {
|
||||
"default": "Debug"
|
||||
}
|
||||
},
|
||||
"extensionBundle": {
|
||||
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||
"version": "[4.*, 5.0.0)"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Serverless Chat</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css">
|
||||
<script>
|
||||
window.apiBaseUrl = window.location.origin;
|
||||
</script>
|
||||
<style>
|
||||
.slide-fade-enter-active,
|
||||
.slide-fade-leave-active {
|
||||
transition: all 1s ease;
|
||||
}
|
||||
|
||||
.slide-fade-enter,
|
||||
.slide-fade-leave-to {
|
||||
height: 0px;
|
||||
overflow-y: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p> </p>
|
||||
<div id="app" class="container">
|
||||
<h3>Serverless chat</h3>
|
||||
<div class="row" v-if="ready">
|
||||
<div class="signalr-demo col-sm">
|
||||
<hr />
|
||||
<div id='groupchecked'>
|
||||
<input type="checkbox" id="checkbox" v-model="checked">
|
||||
<label for="checkbox">Send To Default Group: {{ this.defaultgroup }}</label>
|
||||
</div>
|
||||
<form v-on:submit.prevent="sendNewMessage(checked)">
|
||||
<input type="text" v-model="newMessage" id="message-box" class="form-control"
|
||||
placeholder="Type message here..." />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="!ready">
|
||||
<div class="col-sm">
|
||||
<div>Loading...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="ready">
|
||||
<transition-group name="slide-fade" tag="div">
|
||||
<div class="row" v-for="message in messages" v-bind:key="message.id">
|
||||
<div class="col-sm">
|
||||
<hr />
|
||||
<div>
|
||||
<div style="display: inline-block; padding-left: 12px;">
|
||||
<div>
|
||||
<a href="#" v-on:click.prevent="sendPrivateMessage(message.Sender)">
|
||||
<span class="text-info small">
|
||||
<strong>{{ message.Sender || message.sender }}</strong>
|
||||
</span>
|
||||
</a>
|
||||
<span v-if="message.ConnectionId || message.connectionId">
|
||||
<a href="#" v-on:click.prevent="sendToConnection(message.ConnectionId || message.connectionId)">
|
||||
<span class="badge badge-primary">Connection: {{ message.ConnectionId || message.connectionId
|
||||
}}</span>
|
||||
</a>
|
||||
<a href="#" v-on:click.prevent="addConnectionToGroup(message.ConnectionId || message.connectionId)">
|
||||
<span v-if="message.ConnectionId || message.connectionId"
|
||||
class="badge badge-primary">AddConnectionToGroup</span>
|
||||
</a>
|
||||
<a href="#"
|
||||
v-on:click.prevent="removeConnectionIdFromGroup(message.ConnectionId || message.connectionId)">
|
||||
<span v-if="message.ConnectionId || message.connectionId"
|
||||
class="badge badge-primary">RemoveConnectionFromGroup</span>
|
||||
</a>
|
||||
</span>
|
||||
<span v-if="message.Sender || message.sender">
|
||||
<a href="#" v-on:click.prevent="addUserToGroup(message.Sender || message.sender)">
|
||||
<span class="badge badge-primary">AddUserToGroup</span>
|
||||
</a>
|
||||
<a href="#" v-on:click.prevent="removeUserFromGroup(message.Sender || message.sender)">
|
||||
<span class="badge badge-primary">RemoveUserFromGroup</span>
|
||||
</a>
|
||||
</span>
|
||||
<span v-if="message.IsPrivate || message.isPrivate" class="badge badge-secondary">private message
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
{{ message.Text || message.text }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@aspnet/signalr@1.0.3/dist/browser/signalr.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/crypto-js@3.1.9-1/crypto-js.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/crypto-js@3.1.9-1/enc-base64.js"></script>
|
||||
<script>
|
||||
const data = {
|
||||
username: '',
|
||||
defaultgroup: 'AzureSignalR',
|
||||
checked: false,
|
||||
newMessage: '',
|
||||
messages: [],
|
||||
myConnectionId: '',
|
||||
ready: false
|
||||
};
|
||||
const app = new Vue({
|
||||
el: '#app',
|
||||
data: data,
|
||||
methods: {
|
||||
sendNewMessage: function (isToGroup) {
|
||||
if (isToGroup) {
|
||||
connection.invoke("sendToGroup", this.defaultgroup, this.newMessage);
|
||||
}
|
||||
else {
|
||||
connection.invoke("broadcast", this.newMessage);
|
||||
}
|
||||
this.newMessage = '';
|
||||
},
|
||||
sendPrivateMessage: function (user) {
|
||||
const messageText = prompt('Send private message to ' + user);
|
||||
|
||||
if (messageText) {
|
||||
connection.invoke("sendToUser", user, messageText);
|
||||
}
|
||||
},
|
||||
sendToConnection: function (connectionId) {
|
||||
const messageText = prompt('Send private message to connection ' + connectionId);
|
||||
|
||||
if (messageText) {
|
||||
connection.invoke("sendToConnection", connectionId, messageText);
|
||||
}
|
||||
},
|
||||
addConnectionToGroup: function (connectionId) {
|
||||
confirm('Add connection ' + connectionId + ' to group: ' + this.defaultgroup);
|
||||
connection.invoke("joinGroup", connectionId, this.defaultgroup);
|
||||
},
|
||||
addUserToGroup: function (user) {
|
||||
r = confirm('Add user ' + user + ' to group: ' + this.defaultgroup);
|
||||
connection.invoke("joinUserToGroup", user, this.defaultgroup);
|
||||
},
|
||||
removeConnectionIdFromGroup: function (connectionId) {
|
||||
confirm('Remove connection ' + connectionId + ' from group: ' + this.defaultgroup);
|
||||
connection.invoke("leaveGroup", connectionId, this.defaultgroup);
|
||||
},
|
||||
removeUserFromGroup: function (user) {
|
||||
confirm('Remove user ' + user + ' from group: ' + this.defaultgroup);
|
||||
connection.invoke("leaveUserFromGroup", user, this.defaultgroup);
|
||||
}
|
||||
}
|
||||
});
|
||||
const apiBaseUrl = window.location.origin;
|
||||
data.username = prompt("Enter your username");
|
||||
if (!data.username) {
|
||||
alert("No username entered. Reload page and try again.");
|
||||
throw "No username entered";
|
||||
}
|
||||
const connection = new signalR.HubConnectionBuilder()
|
||||
.withUrl(apiBaseUrl + `/api?x-ms-signalr-userid=${data.username}`)
|
||||
.configureLogging(signalR.LogLevel.Information)
|
||||
.build();
|
||||
connection.on('newMessage', onNewMessage);
|
||||
connection.on('newConnection', onNewConnection)
|
||||
connection.onclose(() => console.log('disconnected'));
|
||||
console.log('connecting...');
|
||||
connection.start()
|
||||
.then(() => {
|
||||
data.ready = true;
|
||||
console.log('connected!');
|
||||
})
|
||||
.catch(console.error);
|
||||
function getAxiosConfig() {
|
||||
const config = {
|
||||
headers: {
|
||||
'x-ms-signalr-user-id': data.username,
|
||||
}
|
||||
};
|
||||
return config;
|
||||
}
|
||||
let counter = 0;
|
||||
function onNewMessage(message) {
|
||||
message.id = counter++; // vue transitions need an id
|
||||
data.messages.unshift(message);
|
||||
};
|
||||
function onNewConnection(message) {
|
||||
data.myConnectionId = message.ConnectionId;
|
||||
newConnectionMessage = {
|
||||
id: counter++,
|
||||
text: `${message.ConnectionId} has connected.`
|
||||
};
|
||||
data.messages.unshift(newConnectionMessage);
|
||||
}
|
||||
|
||||
function base64url(source) {
|
||||
// Encode in classical base64
|
||||
encodedSource = CryptoJS.enc.Base64.stringify(source);
|
||||
|
||||
// Remove padding equal characters
|
||||
encodedSource = encodedSource.replace(/=+$/, '');
|
||||
|
||||
// Replace characters according to base64url specifications
|
||||
encodedSource = encodedSource.replace(/\+/g, '-');
|
||||
encodedSource = encodedSource.replace(/\//g, '_');
|
||||
|
||||
return encodedSource;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,473 @@
|
|||
{
|
||||
"name": "js",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@azure/functions": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"azure-functions-core-tools": "^4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/functions": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/@azure/functions/-/functions-4.1.0.tgz",
|
||||
"integrity": "sha1-+KGZb84rRk+2mw9lBqhe4GThkHU=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"long": "^4.0.0",
|
||||
"undici": "^5.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/@fastify/busboy/-/busboy-2.1.0.tgz",
|
||||
"integrity": "sha1-Bwnp9MslI1HGCcbm2NZ3mo0l7f8=",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.11.5",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/@types/node/-/node-20.11.5.tgz",
|
||||
"integrity": "sha1-vhDGIsp/yqPPImz4AWarwxOJ2G4=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/yauzl": {
|
||||
"version": "2.10.3",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/@types/yauzl/-/yauzl-2.10.3.tgz",
|
||||
"integrity": "sha1-6bKAi08QlQSgPNqVglmHb2EBeZk=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/azure-functions-core-tools": {
|
||||
"version": "4.0.5455",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/azure-functions-core-tools/-/azure-functions-core-tools-4.0.5455.tgz",
|
||||
"integrity": "sha1-N69rKRXOUPV/di0oShQcyh8e0WY=",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"os": [
|
||||
"win32",
|
||||
"darwin",
|
||||
"linux"
|
||||
],
|
||||
"dependencies": {
|
||||
"chalk": "3.0.0",
|
||||
"extract-zip": "^2.0.1",
|
||||
"https-proxy-agent": "5.0.0",
|
||||
"progress": "2.0.3",
|
||||
"rimraf": "3.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"azfun": "lib/main.js",
|
||||
"azurefunctions": "lib/main.js",
|
||||
"func": "lib/main.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha1-Exn2V5NX8jONMzfSzdSRS7XcyGU=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/extract-zip": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/extract-zip/-/extract-zip-2.0.1.tgz",
|
||||
"integrity": "sha1-Zj3KVv5G34kNXxMe9KBtIruLoTo=",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"get-stream": "^5.1.0",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"bin": {
|
||||
"extract-zip": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.17.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/yauzl": "^2.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha1-SWaheV7lrOZecGxLe+txJX1uItM=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha1-uN8PuAK7+o6JvR2Ti04WV47UTys=",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
|
||||
"integrity": "sha1-4qkFQqu2inYuCghQ9sntrf2FBrI=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.28.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/undici/-/undici-5.28.2.tgz",
|
||||
"integrity": "sha1-/qIA6sZfx+yv+AoCPRoFQ0I7TJE=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha1-vNU5iT0AtW6WT9JlekhmsiGmVhc=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://msazure.pkgs.visualstudio.com/_packaging/AzurePortal/npm/registry/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/functions/*.js",
|
||||
"scripts": {
|
||||
"start": "func start",
|
||||
"test": "echo \"No tests yet...\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/functions": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"azure-functions-core-tools": "^4.x"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
const { app } = require('@azure/functions');
|
||||
const { readFile } = require('fs/promises');
|
||||
|
||||
app.http('index', {
|
||||
methods: ['GET', 'POST'],
|
||||
authLevel: 'anonymous',
|
||||
handler: async (context) => {
|
||||
const content = await readFile('index.html', 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
context.err(err)
|
||||
return
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'text/html'
|
||||
},
|
||||
body: content,
|
||||
};
|
||||
}
|
||||
});
|
|
@ -0,0 +1,147 @@
|
|||
const { app, output } = require('@azure/functions');
|
||||
const newMessageTarget = "newMessage";
|
||||
|
||||
const signalR = output.generic({
|
||||
type: 'signalR',
|
||||
name: 'signalR',
|
||||
hubName: 'hub',
|
||||
connectionStringSetting: 'AzureSignalRConnectionString',
|
||||
});
|
||||
|
||||
app.generic("connected",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "connected", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "connected", "category": "connections" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.log(`Connection ${triggerInput.ConnectionId} is connected.`)
|
||||
context.extraOutputs.set(signalR, {
|
||||
"target": "newConnection",
|
||||
"arguments": [new NewConnection(triggerInput.ConnectionId, "text")],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("disconnected",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "disconnected", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "disconnected", "category": "connections" },
|
||||
handler: (triggerInput, context) => { context.log(`Connection ${triggerInput.ConnectionId} is disconnected.`) }
|
||||
})
|
||||
|
||||
|
||||
class NewConnection {
|
||||
constructor(connectionId, auth) {
|
||||
this.ConnectionId = connectionId;
|
||||
this.auth = auth;
|
||||
}
|
||||
}
|
||||
|
||||
app.generic("broadcast",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "broadcast", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "broadcast", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"target": newMessageTarget,
|
||||
"arguments": [new NewMessage(triggerInput, triggerInput.Arguments[0])]
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("sendToGroup",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "sendToGroup", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "sendToGroup", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"target": newMessageTarget,
|
||||
"groupName": triggerInput.Arguments[0],
|
||||
"arguments": [new NewMessage(triggerInput, triggerInput.Arguments[1])],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("sendToUser",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "sendToUser", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "sendToUser", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"target": newMessageTarget,
|
||||
"userId": triggerInput.Arguments[0],
|
||||
"arguments": [new NewMessage(triggerInput, triggerInput.Arguments[1])],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("sendToConnection",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "sendToConnection", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "sendToConnection", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"target": newMessageTarget,
|
||||
"connectionId": triggerInput.Arguments[0],
|
||||
"arguments": [new NewMessage(triggerInput, triggerInput.Arguments[1])],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("joinGroup",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "joinGroup", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "joinGroup", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"connectionId": triggerInput.Arguments[0],
|
||||
"groupName": triggerInput.Arguments[1],
|
||||
"action": "add",
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("leaveGroup",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "leaveGroup", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "leaveGroup", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"connectionId": triggerInput.Arguments[0],
|
||||
"groupName": triggerInput.Arguments[1],
|
||||
"action": "remove",
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("joinUserToGroup",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "joinUserToGroup", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "joinUserToGroup", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"userId": triggerInput.Arguments[0],
|
||||
"groupName": triggerInput.Arguments[1],
|
||||
"action": "add",
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
app.generic("leaveUserFromGroup",
|
||||
{
|
||||
trigger: { "type": "signalRTrigger", "name": "leaveUserFromGroup", "direction": "in", "hubName": "hub", "connectionStringSetting": "AzureSignalRConnectionString", "event": "leaveUserFromGroup", "category": "messages" },
|
||||
extraOutputs: [signalR],
|
||||
handler: (triggerInput, context) => {
|
||||
context.extraOutputs.set(signalR, {
|
||||
"userId": triggerInput.Arguments[0],
|
||||
"groupName": triggerInput.Arguments[1],
|
||||
"action": "remove",
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
class NewMessage {
|
||||
constructor(invocationContext, message) {
|
||||
this.Sender = invocationContext.UserId ? invocationContext.UserId : '';
|
||||
this.ConnectionId = invocationContext.ConnectionId;
|
||||
this.Text = message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
const { app, input } = require('@azure/functions');
|
||||
|
||||
const inputSignalR = input.generic({
|
||||
type: 'signalRConnectionInfo',
|
||||
name: 'connectionInfo',
|
||||
hubName: 'hub',
|
||||
connectionStringSetting: 'AzureSignalRConnectionString',
|
||||
userId: '{query.x-ms-signalr-userid}'
|
||||
});
|
||||
|
||||
app.post('negotiate', {
|
||||
authLevel: 'function',
|
||||
handler: (request, context) => {
|
||||
return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
|
||||
},
|
||||
route: 'negotiate',
|
||||
extraInputs: [inputSignalR],
|
||||
});
|
Загрузка…
Ссылка в новой задаче