diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/.gitignore b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/.gitignore new file mode 100644 index 000000000..ff5b00c50 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/.gitignore @@ -0,0 +1,264 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# Azure Functions localsettings file +local.settings.json + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Function.cs b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Function.cs new file mode 100644 index 000000000..362fd2f33 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Function.cs @@ -0,0 +1,82 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO; +using Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO.Trigger.Model; +using Microsoft.Extensions.Logging; +using System.IO; +using System.Threading.Tasks; + +namespace ChatSample; + +public static class Function +{ + [FunctionName("index")] + public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req, ExecutionContext context, ILogger log) + { + var indexFile = Path.Combine(context.FunctionAppDirectory, "public/index.html"); + log.LogInformation($"index.html path: {indexFile}."); + return new ContentResult + { + Content = File.ReadAllText(indexFile), + ContentType = "text/html", + }; + } + + [FunctionName("Negotiate")] + public static IActionResult SocketIONegotiate( + [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req, + [SocketIONegotiation(Hub = "hub", UserId = "{query.userId}")] SocketIONegotiationResult result) + { + return new OkObjectResult(result); + } + + [FunctionName("TriggerBindingForConnect")] + public static SocketIOEventHandlerResponse TriggerBindingForConnect( + [SocketIOTrigger("hub", "connect")] SocketIOConnectRequest request, + string userId, + ILogger log) + { + log.LogInformation($"Running trigger for: connect for {userId}"); + return new SocketIOConnectResponse(); + } + + [FunctionName("TriggerBindingForConnected")] + public static async Task TriggerBindingForConnected( + [SocketIOTrigger("hub", "connected")] SocketIOConnectedRequest request, + [SocketIO(Hub = "hub")] IAsyncCollector collector, + string userId, + ILogger log) + { + log.LogInformation("Running trigger for: connected"); + await collector.AddAsync(SocketIOAction.CreateSendToNamespaceAction("new message", new[] { "system", $"{userId} connected" })); + } + + [FunctionName("TriggerBindingForDisconnected")] + public static async Task TriggerBindingForDisconnected( + [SocketIOTrigger("hub", "disconnected")] SocketIODisconnectedRequest request, + [SocketIO(Hub = "hub")] IAsyncCollector collector, + string userId, + ILogger log) + { + log.LogInformation("Running trigger for: disconnected"); + await collector.AddAsync(SocketIOAction.CreateSendToNamespaceAction("new message", new[] { "system", $"{userId} disconnected" })); + } + + [FunctionName("TriggerBindingForChat")] + public static async Task TriggerBindingForChat( + [SocketIOTrigger("hub", "chat")] SocketIOMessageRequest request, + [SocketIO(Hub = "hub")] IAsyncCollector collector, + SocketIOSocketContext connectionContext, + [SocketIOParameter] string message, + ILogger log) + { + log.LogInformation("Running trigger for: new message"); + log.LogInformation($"Arguments: {string.Join(';', request.Parameters)}"); + + var userId = connectionContext.UserId; + await collector.AddAsync(SocketIOAction.CreateSendToNamespaceAction("new message", new[] { userId, message }, new[] { request.SocketId })); + } +} + diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Properties/launchSettings.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Properties/launchSettings.json new file mode 100644 index 000000000..a97159a51 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "profiles": { + "chat_serverless_dotnet": { + "commandName": "Project", + "commandLineArgs": "--port 7204", + "launchBrowser": false + } + } +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md new file mode 100644 index 000000000..413f20f64 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md @@ -0,0 +1,20 @@ + +# Socket.IO Chat in Serverless Mode (C#) + +This project is an Azure Function-based group chat application that leverages WebPubSub for Socket.IO to enable real-time communication between clients. + +## Setup + +### Update Connection String + +```bash +func settings add WebPubSubForSocketIOConnectionString "" +``` + +## Run the sample + +```bash +func start +``` + +Visit the url pointing to `index` function. diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/chat-serverless-dotnet.csproj b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/chat-serverless-dotnet.csproj new file mode 100644 index 000000000..9a0892def --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/chat-serverless-dotnet.csproj @@ -0,0 +1,23 @@ + + + net6.0 + v4 + chat_serverless_dotnet + + + + + + + + PreserveNewest + + + Always + + + PreserveNewest + Never + + + diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/host.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/host.json new file mode 100644 index 000000000..ee5cf5f83 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/host.json @@ -0,0 +1,12 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + }, + "enableLiveMetricsFilters": true + } + } +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/local.settings.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/local.settings.json new file mode 100644 index 000000000..6a4121e45 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/local.settings.json @@ -0,0 +1,10 @@ +{ + "IsEncrypted": false, + "Values": { + "FUNCTIONS_WORKER_RUNTIME": "dotnet", + "AzureWebJobsFeatureFlags": "EnableWorkerIndexing", + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "WebPubSubForSocketIOConnectionString": "" + }, + "ConnectionStrings": {} +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/public/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/public/index.html new file mode 100644 index 000000000..2c1322fa1 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/public/index.html @@ -0,0 +1,242 @@ + + + + + + + + Group Chat + + + + + + + + + + + + diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.funcignore b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.funcignore new file mode 100644 index 000000000..17bd0f697 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.funcignore @@ -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/ \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.gitignore b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.gitignore new file mode 100644 index 000000000..f15ac3fc6 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.gitignore @@ -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 \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md new file mode 100644 index 000000000..b7646f2fa --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md @@ -0,0 +1,21 @@ + +# Socket.IO Chat in Serverless Mode (JS) + +This project is an Azure Function-based group chat application that leverages WebPubSub for Socket.IO to enable real-time communication between clients. + +## Setup + +### Update Connection String + +```bash +func settings add WebPubSubForSocketIOConnectionString "" +``` + +# How to run + +```bash +func extensions sync +func start +``` + +Visit `http://localhost:7084/api/index` to play with the sample. \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj new file mode 100644 index 000000000..71e8e96ce --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj @@ -0,0 +1,11 @@ + + + netcoreapp3.1 + + ** + + + + + + \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/host.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/host.json new file mode 100644 index 000000000..278b52cde --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/host.json @@ -0,0 +1,11 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + } +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/local.settings.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/local.settings.json new file mode 100644 index 000000000..fdf9a740a --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/local.settings.json @@ -0,0 +1,10 @@ +{ + "IsEncrypted": false, + "Values": { + "FUNCTIONS_WORKER_RUNTIME": "node", + "AzureWebJobsFeatureFlags": "EnableWorkerIndexing", + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "WebPubSubForSocketIOConnectionString": "" + }, + "ConnectionStrings": {} +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json new file mode 100644 index 000000000..8ba10afa6 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json @@ -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" + } +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/index.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/index.js new file mode 100644 index 000000000..f56b95630 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/index.js @@ -0,0 +1,31 @@ +const { app } = require('@azure/functions'); + +const fs = require('fs').promises; +const path = require('path') + +async function index(request, context) { + try { + context.log(`Http function processed request for url "${request.url}"`); + + const filePath = path.join(__dirname,'../public/index.html'); + const html = await fs.readFile(filePath); + return { + body: html, + headers: { + 'Content-Type': 'text/html' + } + }; + } catch (error) { + context.log(error); + return { + status: 500, + jsonBody: error + } + } +}; + +app.http('index', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + handler: index +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/message.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/message.js new file mode 100644 index 000000000..de11a0cdb --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/message.js @@ -0,0 +1,30 @@ +const { app, output, trigger } = require('@azure/functions'); + +const socketio = output.generic({ + type: 'socketio', + hub: 'hub', +}) + +async function chat(request, context) { + context.extraOutputs.set(socketio, { + actionName: 'sendToNamespace', + namespace: '/', + eventName: 'new message', + parameters: [ + context.triggerMetadata.socketId, + context.triggerMetadata.message + ], + }); +} + +// Trigger for new message +app.generic('chat', { + trigger: trigger.generic({ + type: 'socketiotrigger', + hub: 'hub', + eventName: 'chat', + parameterNames: ['message'], + }), + extraOutputs: [socketio], + handler: chat +}); \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/negotiate.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/negotiate.js new file mode 100644 index 000000000..9d893ddcb --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/negotiate.js @@ -0,0 +1,21 @@ +const { app, input } = require('@azure/functions'); + +const socketIONegotiate = input.generic({ + type: 'socketionegotiation', + direction: 'in', + name: 'result', + hub: 'hub' +}); + +async function negotiate(request, context) { + let result = context.extraInputs.get(socketIONegotiate); + return { jsonBody: result }; +}; + +// Negotiation +app.http('negotiate', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + extraInputs: [socketIONegotiate], + handler: negotiate +}); \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/public/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/public/index.html new file mode 100644 index 000000000..da6785d5c --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/public/index.html @@ -0,0 +1,51 @@ + + + +

Socket.IO Serverless Sample

+
+
+ + +
+
+
+ + + + + \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.funcignore b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.funcignore new file mode 100644 index 000000000..17bd0f697 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.funcignore @@ -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/ \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.gitignore b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.gitignore new file mode 100644 index 000000000..f15ac3fc6 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.gitignore @@ -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 \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/README.md new file mode 100644 index 000000000..2507cedf8 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/README.md @@ -0,0 +1,22 @@ + +# Socket.IO Chat in Serverless Mode (TS) + +This project is an Azure Function-based group chat application that leverages WebPubSub for Socket.IO to enable real-time communication between clients. + +## Setup + +### Update Connection String + +```bash +func settings add WebPubSubForSocketIOConnectionString "" +``` + +# How to run + +```bash +func extensions sync +npm install +npm start +``` + +Visit `http://localhost:7084/api/index` to play with the sample. \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/extensions.csproj b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/extensions.csproj new file mode 100644 index 000000000..e8d3aa2b6 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/extensions.csproj @@ -0,0 +1,12 @@ + + + netcoreapp3.1 + true + + ** + + + + + + \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/host.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/host.json new file mode 100644 index 000000000..278b52cde --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/host.json @@ -0,0 +1,11 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + } +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/local.settings.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/local.settings.json new file mode 100644 index 000000000..fdf9a740a --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/local.settings.json @@ -0,0 +1,10 @@ +{ + "IsEncrypted": false, + "Values": { + "FUNCTIONS_WORKER_RUNTIME": "node", + "AzureWebJobsFeatureFlags": "EnableWorkerIndexing", + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "WebPubSubForSocketIOConnectionString": "" + }, + "ConnectionStrings": {} +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/package.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/package.json new file mode 100644 index 000000000..b7426489b --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/package.json @@ -0,0 +1,24 @@ +{ + "name": "sampledev-javascript", + "version": "1.0.0", + "description": "", + "scripts": { + "copy-public": "copyfiles -a src/public/* dist", + "build": "tsc && npm run copy-public", + "watch": "tsc -w", + "clean": "rimraf dist", + "prestart": "npm run clean && npm run build", + "start": "func start", + "test": "echo \"No tests yet...\"" + }, + "dependencies": { + "@azure/functions": "^4.0.0" + }, + "devDependencies": { + "@types/node": "^20.x", + "typescript": "^4.0.0", + "rimraf": "^5.0.0", + "copyfiles": "2.4.1" + }, + "main": "dist/src/{index.js,functions/*.js}" +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/connect.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/connect.ts new file mode 100644 index 000000000..28c298037 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/connect.ts @@ -0,0 +1,17 @@ +import { app, InvocationContext, input, trigger } from "@azure/functions"; + + +export async function connect(request: any, context: InvocationContext): Promise { + context.log(`SocketIO trigger for connect`); + return {}; +} + +// Trigger for connect +app.generic('connect', { + trigger: trigger.generic({ + type: 'socketiotrigger', + hub: 'hub', + eventName: 'connect' + }), + handler: connect +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/connected.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/connected.ts new file mode 100644 index 000000000..6302f1432 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/connected.ts @@ -0,0 +1,15 @@ +import { app, InvocationContext, trigger } from "@azure/functions"; + +export async function connected(request: any, context: InvocationContext): Promise { + context.log(`SocketIO trigger for connected`); +} + +// Trigger for connected +app.generic('connected', { + trigger: trigger.generic({ + type: 'socketiotrigger', + hub: 'hub', + eventName: 'connected' + }), + handler: connected +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/disconnected.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/disconnected.ts new file mode 100644 index 000000000..fdc5a1492 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/disconnected.ts @@ -0,0 +1,15 @@ +import { app, InvocationContext, trigger } from "@azure/functions"; + +export async function disconnected(request: any, context: InvocationContext): Promise { + context.log(`SocketIO trigger for disconnected`); +} + +// Trigger for disconnected +app.generic('disconnected', { + trigger: trigger.generic({ + type: 'socketiotrigger', + hub: 'hub', + eventName: 'disconnected' + }), + handler: disconnected +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/index.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/index.ts new file mode 100644 index 000000000..e6e8dea14 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/index.ts @@ -0,0 +1,31 @@ +import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; + +const fs = require('fs').promises; +const path = require('path') + +export async function index(request: HttpRequest, context: InvocationContext): Promise { + try { + context.log(`Http function processed request for url "${request.url}"`); + + const filePath = path.join(__dirname,'../public/index.html'); + const html = await fs.readFile(filePath); + return { + body: html, + headers: { + 'Content-Type': 'text/html' + } + }; + } catch (error) { + context.log(error); + return { + status: 500, + jsonBody: error + } + } +}; + +app.http('index', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + handler: index +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/message.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/message.ts new file mode 100644 index 000000000..0233db425 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/message.ts @@ -0,0 +1,32 @@ +import { app, InvocationContext, trigger, output } from "@azure/functions"; + +const socketio = output.generic({ + type: 'socketio', + hub: 'hub', +}) + +export async function chat(request: any, context: InvocationContext): Promise { + context.log(`SocketIO trigger for newMessage`); + context.extraOutputs.set(socketio, { + actionName: 'sendToNamespace', + namespace: '/', + eventName: 'new message', + parameters: [ + context.triggerMetadata.userId, + context.triggerMetadata.message + ], + exceptRooms: [request.socketId], + }); +} + +// Trigger for new message +app.generic('chat', { + trigger: trigger.generic({ + type: 'socketiotrigger', + hub: 'hub', + eventName: 'chat', + parameterNames: ['message'], + }), + extraOutputs: [socketio], + handler: chat +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/negotiate.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/negotiate.ts new file mode 100644 index 000000000..d20ca8bbc --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/functions/negotiate.ts @@ -0,0 +1,24 @@ +import { app, HttpRequest, HttpResponseInit, InvocationContext, input, } from "@azure/functions"; + +const socketIONegotiate = input.generic({ + type: 'socketionegotiation', + direction: 'in', + name: 'result', + hub: 'hub', + userId: '{query.userId}' +}); + +export async function negotiate(request: HttpRequest, context: InvocationContext): Promise { + context.log(`Http function processed request for url "${request.url}"`); + + let result = context.extraInputs.get(socketIONegotiate); + return { jsonBody: result }; +}; + +// Negotiation +app.http('negotiate', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + extraInputs: [socketIONegotiate], + handler: negotiate +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/index.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/index.ts new file mode 100644 index 000000000..aa951f82a --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/index.ts @@ -0,0 +1,5 @@ +import { app } from '@azure/functions'; + +app.setup({ + enableHttpStream: true, +}); diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/public/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/public/index.html new file mode 100644 index 000000000..4d4bb26c9 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/public/index.html @@ -0,0 +1,242 @@ + + + + + + + + Group Chat + + + + + + + + + + + + diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/tsconfig.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/tsconfig.json new file mode 100644 index 000000000..fe1d76178 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "dist", + "rootDir": ".", + "sourceMap": true, + "strict": false + } +} \ No newline at end of file