From 09a8752d3dee6f41515a290fd4ee0c79541dd682 Mon Sep 17 00:00:00 2001 From: Chenyang Liu Date: Mon, 24 Jun 2024 13:10:21 +0800 Subject: [PATCH 1/8] init for socketio serverless --- .../examples/chat-serverless/README.md | 27 ++ .../examples/chat-serverless/index.js | 12 + .../examples/chat-serverless/package.json | 15 + .../chat-serverless/public/index.html | 33 ++ .../examples/chat-serverless/public/main.js | 245 ++++++++++++ .../examples/chat-serverless/public/style.css | 150 ++++++++ .../examples/chat-serverless/yarn.lock | 352 ++++++++++++++++++ 7 files changed, 834 insertions(+) create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md new file mode 100644 index 000000000..c20dbb9ae --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md @@ -0,0 +1,27 @@ + +# Socket.IO Chat + +A simple chat demo for Socket.IO with Azure Web PubSub + +## How to use + +### Update endpoint in `public/main.js` + +```js +const webPubSubEndpoint = "https://"; +``` + +### Run the server + +```bash +npm install +npm run start -- "" +``` + +And point your browser to `http://localhost:3000`. + +## Features + +- Multiple users can join a chat room by each entering a unique username on website load. +- Users can type chat messages to send to the chat room. +- A notification is sent to all users when a user joins or leaves the chatroom. \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js new file mode 100644 index 000000000..ec89389c2 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js @@ -0,0 +1,12 @@ +const express = require('express'); +const app = express(); +const path = require('path'); + +async function main() { + app.use(express.static(path.join(__dirname, 'public'))); + app.listen(3000, () => { + console.log('Visit http://localhost:%d', 3000); + }); +} + +main(); \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json new file mode 100644 index 000000000..551330f23 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json @@ -0,0 +1,15 @@ +{ + "name": "socket.io-chat", + "version": "0.0.0", + "description": "A simple chat client using socket.io", + "main": "index.js", + "author": "Grant Timmerman", + "private": true, + "license": "BSD", + "dependencies": { + "express": "~4.17.1" + }, + "scripts": { + "start": "node index.js" + } + } diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html new file mode 100644 index 000000000..053d201e6 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html @@ -0,0 +1,33 @@ + + + + + Socket.IO Chat Example + + + +
    +
  • +
    +
      +
      + +
    • + +
    + + + + + + + \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js new file mode 100644 index 000000000..2d8221850 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js @@ -0,0 +1,245 @@ +async function main() { + const FADE_TIME = 150; // ms + const TYPING_TIMER_LENGTH = 400; // ms + const COLORS = [ + '#e21400', '#91580f', '#f8a700', '#f78b00', + '#58dc00', '#287b00', '#a8f07a', '#4ae8c4', + '#3b88eb', '#3824aa', '#a700ff', '#d300e7' + ]; + + // Initialize variables + const $window = $(window); + const $usernameInput = $('.usernameInput'); // Input for username + const $messages = $('.messages'); // Messages area + const $inputMessage = $('.inputMessage'); // Input message input box + + const $loginPage = $('.login.page'); // The login page + const $chatPage = $('.chat.page'); // The chatroom page + + const webPubSubEndpoint = "http://localhost:8080/"; + var socket = io(webPubSubEndpoint, { + path: "/clients/socketio/hubs/hub", + }); + console.log(socket); + setInterval(() => {console.log(socket);}, 3000); + + // Prompt for setting a username + let username; + let connected = false; + let $currentInput = $usernameInput.focus(); + + const addParticipantsMessage = (data) => { + let message = ''; + if (data.numUsers === 1) { + message += `there's 1 participant`; + } else { + message += `there are ${data.numUsers} participants`; + } + log(message); + } + + // Sets the client's username + const setUsername = () => { + username = cleanInput($usernameInput.val().trim()); + + // If the username is valid + if (username) { + $loginPage.fadeOut(); + $chatPage.show(); + $loginPage.off('click'); + $currentInput = $inputMessage.focus(); + + // Tell the server your username + // socket.emit('add user', username); + } + } + + // Sends a chat message + const sendMessage = () => { + let message = $inputMessage.val(); + // Prevent markup from being injected into the message + message = cleanInput(message); + // if there is a non-empty message and a socket connection + if (message && connected) { + $inputMessage.val(''); + addChatMessage({ username, message }); + // tell server to execute 'new message' and send along one parameter + socket.emit('new message', message); + } + } + + // Log a message + const log = (message, options) => { + const $el = $('
  • ').addClass('log').text(message); + addMessageElement($el, options); + } + + // Adds the visual chat message to the message list + const addChatMessage = (data, options = {}) => { + // Don't fade the message in if there is an 'X was typing' + const $typingMessages = getTypingMessages(data); + if ($typingMessages.length !== 0) { + options.fade = false; + $typingMessages.remove(); + } + + const $usernameDiv = $('') + .text(data.username) + .css('color', getUsernameColor(data.username)); + const $messageBodyDiv = $('') + .text(data.message); + + const typingClass = data.typing ? 'typing' : ''; + const $messageDiv = $('
  • ') + .data('username', data.username) + .addClass(typingClass) + .append($usernameDiv, $messageBodyDiv); + + addMessageElement($messageDiv, options); + } + + // Adds the visual chat typing message + const addChatTyping = (data) => { + data.typing = true; + data.message = 'is typing'; + addChatMessage(data); + } + + // Removes the visual chat typing message + const removeChatTyping = (data) => { + getTypingMessages(data).fadeOut(function () { + $(this).remove(); + }); + } + + // Adds a message element to the messages and scrolls to the bottom + // el - The element to add as a message + // options.fade - If the element should fade-in (default = true) + // options.prepend - If the element should prepend + // all other messages (default = false) + const addMessageElement = (el, options) => { + const $el = $(el); + // Setup default options + if (!options) { + options = {}; + } + if (typeof options.fade === 'undefined') { + options.fade = true; + } + if (typeof options.prepend === 'undefined') { + options.prepend = false; + } + + // Apply options + if (options.fade) { + $el.hide().fadeIn(FADE_TIME); + } + if (options.prepend) { + $messages.prepend($el); + } else { + $messages.append($el); + } + + $messages[0].scrollTop = $messages[0].scrollHeight; + } + + // Prevents input from having injected markup + const cleanInput = (input) => { + return $('
    ').text(input).html(); + } + + // Gets the 'X is typing' messages of a user + const getTypingMessages = (data) => { + return $('.typing.message').filter(function (i) { + return $(this).data('username') === data.username; + }); + } + + // Gets the color of a username through our hash function + const getUsernameColor = (username) => { + // Compute hash code + let hash = 7; + for (let i = 0; i < username.length; i++) { + hash = username.charCodeAt(i) + (hash << 5) - hash; + } + // Calculate color + const index = Math.abs(hash % COLORS.length); + return COLORS[index]; + } + + // Keyboard events + + $window.keydown(event => { + // Auto-focus the current input when a key is typed + if (!(event.ctrlKey || event.metaKey || event.altKey)) { + $currentInput.focus(); + } + // When the client hits ENTER on their keyboard + if (event.which === 13) { + if (username) { + sendMessage(); + } else { + setUsername(); + } + } + }); + + // Click events + + // Focus input when clicking anywhere on login page + $loginPage.click(() => { + $currentInput.focus(); + }); + + // Focus input when clicking on the message input's border + $inputMessage.click(() => { + $inputMessage.focus(); + }); + + // Socket events + + // Whenever the server emits 'login', log the login message + socket.on('login', (data) => { + connected = true; + // Display the welcome message + const message = 'Welcome to Socket.IO Chat – '; + log(message, { + prepend: true + }); + addParticipantsMessage(data); + }); + + // Whenever the server emits 'new message', update the chat body + socket.on('new message', (data) => { + addChatMessage(data); + }); + + // Whenever the server emits 'user joined', log it in the chat body + socket.on('user joined', (data) => { + log(`${data.username} joined`); + addParticipantsMessage(data); + }); + + // Whenever the server emits 'user left', log it in the chat body + socket.on('user left', (data) => { + log(`${data.username} left`); + addParticipantsMessage(data); + removeChatTyping(data); + }); + + socket.on('disconnect', () => { + log('you have been disconnected'); + }); + + socket.io.on('reconnect', () => { + log('you have been reconnected'); + if (username) { + // socket.emit('add user', username); + } + }); + + socket.io.on('reconnect_error', () => { + log('attempt to reconnect has failed'); + }); +} +main(); \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css new file mode 100644 index 000000000..cd0a59a65 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css @@ -0,0 +1,150 @@ +/* Fix user-agent */ + +* { + box-sizing: border-box; +} + +html { + font-weight: 300; + -webkit-font-smoothing: antialiased; + background-color: rgb(62, 62, 62); +} + +html, input { + font-family: + "HelveticaNeue-Light", + "Helvetica Neue Light", + "Helvetica Neue", + Helvetica, + Arial, + "Lucida Grande", + sans-serif; +} + +html, body { + height: 100%; + margin: 0; + padding: 0; +} + +ul { + list-style: none; + word-wrap: break-word; +} + +/* Pages */ + +.pages { + height: 100%; + margin: 0; + padding: 0; + width: 100%; +} + +.page { + height: 100%; + position: absolute; + width: 100%; +} + +/* Login Page */ + +.login.page { + background-color: #000; +} + +.login.page .form { + height: 100px; + margin-top: -100px; + position: absolute; + + text-align: center; + top: 50%; + width: 100%; +} + +.login.page .form .usernameInput { + background-color: transparent; + border: none; + border-bottom: 2px solid #fff; + outline: none; + padding-bottom: 15px; + text-align: center; + width: 400px; +} + +.login.page .title { + font-size: 200%; +} + +.login.page .usernameInput { + font-size: 200%; + letter-spacing: 3px; +} + +.login.page .title, .login.page .usernameInput { + color: #fff; + font-weight: 100; +} + +/* Chat page */ + +.chat.page { + display: none; +} + +/* Font */ + +.messages { + font-size: 150%; +} + +.inputMessage { + font-size: 100%; +} + +.log { + color: gray; + font-size: 70%; + margin: 5px; + text-align: center; +} + +/* Messages */ + +.chatArea { + height: 100%; + padding-bottom: 60px; +} + +.messages { + height: 100%; + margin: 0; + overflow-y: scroll; + padding: 10px 20px 10px 20px; +} + +.message.typing .messageBody { + color: gray; +} + +.username { + font-weight: 700; + overflow: hidden; + padding-right: 15px; + text-align: right; +} + +/* Input */ + +.inputMessage { + border: 10px solid #000; + bottom: 0; + height: 60px; + left: 0; + outline: none; + padding-left: 10px; + position: absolute; + right: 0; + width: 100%; +} diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock b/sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock new file mode 100644 index 000000000..73f334834 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock @@ -0,0 +1,352 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +body-parser@1.19.2: + version "1.19.2" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" + integrity sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +express@~4.17.1: + version "4.17.3" + resolved "https://registry.npmjs.org/express/-/express-4.17.3.tgz" + integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.19.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.2" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.7" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +qs@6.9.7: + version "6.9.7" + resolved "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== + dependencies: + bytes "3.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.17.2: + version "0.17.2" + resolved "https://registry.npmjs.org/send/-/send-0.17.2.tgz" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@~1.0.0, unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== From 87d535c9c98576902279a2f8816463a77409a9de Mon Sep 17 00:00:00 2001 From: Chenyang Liu Date: Fri, 16 Aug 2024 17:13:26 +0800 Subject: [PATCH 2/8] Some updates --- .../examples/chat-serverless/README.md | 2 +- .../examples/chat-serverless/public/main.js | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md index c20dbb9ae..c4195ddf3 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md @@ -15,7 +15,7 @@ const webPubSubEndpoint = "https://"; ```bash npm install -npm run start -- "" +npm run start ``` And point your browser to `http://localhost:3000`. diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js index 2d8221850..c1e497b12 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js @@ -16,9 +16,15 @@ async function main() { const $loginPage = $('.login.page'); // The login page const $chatPage = $('.chat.page'); // The chatroom page - const webPubSubEndpoint = "http://localhost:8080/"; - var socket = io(webPubSubEndpoint, { - path: "/clients/socketio/hubs/hub", + const negotiateResponse = await fetch(`http://localhost:7084/api/negotiate/`); + if (!negotiateResponse.ok) { + console.log("Failed to negotiate, status code =", negotiateResponse.status); + return; + } + const negotiateJson = await negotiateResponse.json(); + var socket = io(negotiateJson.endpoint, { + path: negotiateJson.path, + query: { access_token: negotiateJson.token} }); console.log(socket); setInterval(() => {console.log(socket);}, 3000); @@ -50,7 +56,7 @@ async function main() { $currentInput = $inputMessage.focus(); // Tell the server your username - // socket.emit('add user', username); + socket.emit('add user', username); } } From f87e9a83792af81b1805f0b018c6b86d5fa77e3c Mon Sep 17 00:00:00 2001 From: Chenyang Liu Date: Thu, 29 Aug 2024 16:39:57 +0800 Subject: [PATCH 3/8] Add 2 samples --- .../functions/js/simplechat/extensions.csproj | 10 + samples/functions/js/simplechat/host.json | 4 - .../chat-serverless-dotnet/.gitignore | 264 +++++++++++++ .../chat-serverless-dotnet/Function.cs | 82 ++++ .../Properties/launchSettings.json | 9 + .../examples/chat-serverless-dotnet/README.md | 22 ++ .../chat-serverless-dotnet.csproj | 23 ++ .../examples/chat-serverless-dotnet/host.json | 12 + .../chat-serverless-dotnet/index.html | 242 ++++++++++++ .../chat-serverless-javascript/.funcignore | 10 + .../chat-serverless-javascript/.gitignore | 48 +++ .../chat-serverless-javascript/README.md | 24 ++ .../extensions.csproj | 12 + .../chat-serverless-javascript/host.json | 11 + .../chat-serverless-javascript/package.json | 24 ++ .../src/functions/connect.ts | 17 + .../src/functions/connected.ts | 15 + .../src/functions/disconnected.ts | 15 + .../src/functions/index.ts | 31 ++ .../src/functions/message.ts | 32 ++ .../src/functions/negotiate.ts | 24 ++ .../chat-serverless-javascript/src/index.ts | 5 + .../src/public/index.html | 242 ++++++++++++ .../chat-serverless-javascript/tsconfig.json | 10 + .../examples/chat-serverless/README.md | 27 -- .../examples/chat-serverless/index.js | 12 - .../examples/chat-serverless/package.json | 15 - .../chat-serverless/public/index.html | 33 -- .../examples/chat-serverless/public/main.js | 251 ------------- .../examples/chat-serverless/public/style.css | 150 -------- .../examples/chat-serverless/yarn.lock | 352 ------------------ 31 files changed, 1184 insertions(+), 844 deletions(-) create mode 100644 samples/functions/js/simplechat/extensions.csproj create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/.gitignore create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Function.cs create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/Properties/launchSettings.json create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/chat-serverless-dotnet.csproj create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/host.json create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.funcignore create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/.gitignore create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/host.json create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/connect.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/connected.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/disconnected.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/index.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/message.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/negotiate.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/index.ts create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/public/index.html create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/tsconfig.json delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css delete mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock diff --git a/samples/functions/js/simplechat/extensions.csproj b/samples/functions/js/simplechat/extensions.csproj new file mode 100644 index 000000000..7b592c995 --- /dev/null +++ b/samples/functions/js/simplechat/extensions.csproj @@ -0,0 +1,10 @@ + + + netcoreapp3.1 + + ** + + + + + \ No newline at end of file diff --git a/samples/functions/js/simplechat/host.json b/samples/functions/js/simplechat/host.json index d0dbe645a..8d1d95abe 100644 --- a/samples/functions/js/simplechat/host.json +++ b/samples/functions/js/simplechat/host.json @@ -4,9 +4,5 @@ "http": { "routePrefix": "api" } - }, - "extensionBundle": { - "id": "Microsoft.Azure.Functions.ExtensionBundle", - "version": "[3.3.*, 4.0.0)" } } \ No newline at end of file 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..6e71c037e --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md @@ -0,0 +1,22 @@ + +# 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 in `local.settings.json` + +```json +{ +"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..b28bc4458 --- /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/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html new file mode 100644 index 000000000..e277cbe7b --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/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..8eae59345 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md @@ -0,0 +1,24 @@ + +# 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 in `local.settings.json` + +```json +{ +"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-javascript/extensions.csproj b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj new file mode 100644 index 000000000..e8d3aa2b6 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-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/package.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json new file mode 100644 index 000000000..b7426489b --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/functions/connect.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/connect.ts new file mode 100644 index 000000000..28c298037 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/functions/connected.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/connected.ts new file mode 100644 index 000000000..6302f1432 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/functions/disconnected.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/disconnected.ts new file mode 100644 index 000000000..fdc5a1492 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/functions/index.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/index.ts new file mode 100644 index 000000000..e6e8dea14 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/functions/message.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/message.ts new file mode 100644 index 000000000..0233db425 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/functions/negotiate.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/negotiate.ts new file mode 100644 index 000000000..d20ca8bbc --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/index.ts b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/index.ts new file mode 100644 index 000000000..aa951f82a --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/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-javascript/src/public/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/public/index.html new file mode 100644 index 000000000..7e4b05fb4 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/public/index.html @@ -0,0 +1,242 @@ + + + + + + + + Group Chat + + + + + + + + + + + + diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/tsconfig.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/tsconfig.json new file mode 100644 index 000000000..fe1d76178 --- /dev/null +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "dist", + "rootDir": ".", + "sourceMap": true, + "strict": false + } +} \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md deleted file mode 100644 index c4195ddf3..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/README.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Socket.IO Chat - -A simple chat demo for Socket.IO with Azure Web PubSub - -## How to use - -### Update endpoint in `public/main.js` - -```js -const webPubSubEndpoint = "https://"; -``` - -### Run the server - -```bash -npm install -npm run start -``` - -And point your browser to `http://localhost:3000`. - -## Features - -- Multiple users can join a chat room by each entering a unique username on website load. -- Users can type chat messages to send to the chat room. -- A notification is sent to all users when a user joins or leaves the chatroom. \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js deleted file mode 100644 index ec89389c2..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/index.js +++ /dev/null @@ -1,12 +0,0 @@ -const express = require('express'); -const app = express(); -const path = require('path'); - -async function main() { - app.use(express.static(path.join(__dirname, 'public'))); - app.listen(3000, () => { - console.log('Visit http://localhost:%d', 3000); - }); -} - -main(); \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json b/sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json deleted file mode 100644 index 551330f23..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "socket.io-chat", - "version": "0.0.0", - "description": "A simple chat client using socket.io", - "main": "index.js", - "author": "Grant Timmerman", - "private": true, - "license": "BSD", - "dependencies": { - "express": "~4.17.1" - }, - "scripts": { - "start": "node index.js" - } - } diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html deleted file mode 100644 index 053d201e6..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Socket.IO Chat Example - - - -
      -
    • -
      -
        -
        - -
      • - -
      - - - - - - - \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js deleted file mode 100644 index c1e497b12..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/main.js +++ /dev/null @@ -1,251 +0,0 @@ -async function main() { - const FADE_TIME = 150; // ms - const TYPING_TIMER_LENGTH = 400; // ms - const COLORS = [ - '#e21400', '#91580f', '#f8a700', '#f78b00', - '#58dc00', '#287b00', '#a8f07a', '#4ae8c4', - '#3b88eb', '#3824aa', '#a700ff', '#d300e7' - ]; - - // Initialize variables - const $window = $(window); - const $usernameInput = $('.usernameInput'); // Input for username - const $messages = $('.messages'); // Messages area - const $inputMessage = $('.inputMessage'); // Input message input box - - const $loginPage = $('.login.page'); // The login page - const $chatPage = $('.chat.page'); // The chatroom page - - const negotiateResponse = await fetch(`http://localhost:7084/api/negotiate/`); - if (!negotiateResponse.ok) { - console.log("Failed to negotiate, status code =", negotiateResponse.status); - return; - } - const negotiateJson = await negotiateResponse.json(); - var socket = io(negotiateJson.endpoint, { - path: negotiateJson.path, - query: { access_token: negotiateJson.token} - }); - console.log(socket); - setInterval(() => {console.log(socket);}, 3000); - - // Prompt for setting a username - let username; - let connected = false; - let $currentInput = $usernameInput.focus(); - - const addParticipantsMessage = (data) => { - let message = ''; - if (data.numUsers === 1) { - message += `there's 1 participant`; - } else { - message += `there are ${data.numUsers} participants`; - } - log(message); - } - - // Sets the client's username - const setUsername = () => { - username = cleanInput($usernameInput.val().trim()); - - // If the username is valid - if (username) { - $loginPage.fadeOut(); - $chatPage.show(); - $loginPage.off('click'); - $currentInput = $inputMessage.focus(); - - // Tell the server your username - socket.emit('add user', username); - } - } - - // Sends a chat message - const sendMessage = () => { - let message = $inputMessage.val(); - // Prevent markup from being injected into the message - message = cleanInput(message); - // if there is a non-empty message and a socket connection - if (message && connected) { - $inputMessage.val(''); - addChatMessage({ username, message }); - // tell server to execute 'new message' and send along one parameter - socket.emit('new message', message); - } - } - - // Log a message - const log = (message, options) => { - const $el = $('
    • ').addClass('log').text(message); - addMessageElement($el, options); - } - - // Adds the visual chat message to the message list - const addChatMessage = (data, options = {}) => { - // Don't fade the message in if there is an 'X was typing' - const $typingMessages = getTypingMessages(data); - if ($typingMessages.length !== 0) { - options.fade = false; - $typingMessages.remove(); - } - - const $usernameDiv = $('') - .text(data.username) - .css('color', getUsernameColor(data.username)); - const $messageBodyDiv = $('') - .text(data.message); - - const typingClass = data.typing ? 'typing' : ''; - const $messageDiv = $('
    • ') - .data('username', data.username) - .addClass(typingClass) - .append($usernameDiv, $messageBodyDiv); - - addMessageElement($messageDiv, options); - } - - // Adds the visual chat typing message - const addChatTyping = (data) => { - data.typing = true; - data.message = 'is typing'; - addChatMessage(data); - } - - // Removes the visual chat typing message - const removeChatTyping = (data) => { - getTypingMessages(data).fadeOut(function () { - $(this).remove(); - }); - } - - // Adds a message element to the messages and scrolls to the bottom - // el - The element to add as a message - // options.fade - If the element should fade-in (default = true) - // options.prepend - If the element should prepend - // all other messages (default = false) - const addMessageElement = (el, options) => { - const $el = $(el); - // Setup default options - if (!options) { - options = {}; - } - if (typeof options.fade === 'undefined') { - options.fade = true; - } - if (typeof options.prepend === 'undefined') { - options.prepend = false; - } - - // Apply options - if (options.fade) { - $el.hide().fadeIn(FADE_TIME); - } - if (options.prepend) { - $messages.prepend($el); - } else { - $messages.append($el); - } - - $messages[0].scrollTop = $messages[0].scrollHeight; - } - - // Prevents input from having injected markup - const cleanInput = (input) => { - return $('
      ').text(input).html(); - } - - // Gets the 'X is typing' messages of a user - const getTypingMessages = (data) => { - return $('.typing.message').filter(function (i) { - return $(this).data('username') === data.username; - }); - } - - // Gets the color of a username through our hash function - const getUsernameColor = (username) => { - // Compute hash code - let hash = 7; - for (let i = 0; i < username.length; i++) { - hash = username.charCodeAt(i) + (hash << 5) - hash; - } - // Calculate color - const index = Math.abs(hash % COLORS.length); - return COLORS[index]; - } - - // Keyboard events - - $window.keydown(event => { - // Auto-focus the current input when a key is typed - if (!(event.ctrlKey || event.metaKey || event.altKey)) { - $currentInput.focus(); - } - // When the client hits ENTER on their keyboard - if (event.which === 13) { - if (username) { - sendMessage(); - } else { - setUsername(); - } - } - }); - - // Click events - - // Focus input when clicking anywhere on login page - $loginPage.click(() => { - $currentInput.focus(); - }); - - // Focus input when clicking on the message input's border - $inputMessage.click(() => { - $inputMessage.focus(); - }); - - // Socket events - - // Whenever the server emits 'login', log the login message - socket.on('login', (data) => { - connected = true; - // Display the welcome message - const message = 'Welcome to Socket.IO Chat – '; - log(message, { - prepend: true - }); - addParticipantsMessage(data); - }); - - // Whenever the server emits 'new message', update the chat body - socket.on('new message', (data) => { - addChatMessage(data); - }); - - // Whenever the server emits 'user joined', log it in the chat body - socket.on('user joined', (data) => { - log(`${data.username} joined`); - addParticipantsMessage(data); - }); - - // Whenever the server emits 'user left', log it in the chat body - socket.on('user left', (data) => { - log(`${data.username} left`); - addParticipantsMessage(data); - removeChatTyping(data); - }); - - socket.on('disconnect', () => { - log('you have been disconnected'); - }); - - socket.io.on('reconnect', () => { - log('you have been reconnected'); - if (username) { - // socket.emit('add user', username); - } - }); - - socket.io.on('reconnect_error', () => { - log('attempt to reconnect has failed'); - }); -} -main(); \ No newline at end of file diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css b/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css deleted file mode 100644 index cd0a59a65..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/public/style.css +++ /dev/null @@ -1,150 +0,0 @@ -/* Fix user-agent */ - -* { - box-sizing: border-box; -} - -html { - font-weight: 300; - -webkit-font-smoothing: antialiased; - background-color: rgb(62, 62, 62); -} - -html, input { - font-family: - "HelveticaNeue-Light", - "Helvetica Neue Light", - "Helvetica Neue", - Helvetica, - Arial, - "Lucida Grande", - sans-serif; -} - -html, body { - height: 100%; - margin: 0; - padding: 0; -} - -ul { - list-style: none; - word-wrap: break-word; -} - -/* Pages */ - -.pages { - height: 100%; - margin: 0; - padding: 0; - width: 100%; -} - -.page { - height: 100%; - position: absolute; - width: 100%; -} - -/* Login Page */ - -.login.page { - background-color: #000; -} - -.login.page .form { - height: 100px; - margin-top: -100px; - position: absolute; - - text-align: center; - top: 50%; - width: 100%; -} - -.login.page .form .usernameInput { - background-color: transparent; - border: none; - border-bottom: 2px solid #fff; - outline: none; - padding-bottom: 15px; - text-align: center; - width: 400px; -} - -.login.page .title { - font-size: 200%; -} - -.login.page .usernameInput { - font-size: 200%; - letter-spacing: 3px; -} - -.login.page .title, .login.page .usernameInput { - color: #fff; - font-weight: 100; -} - -/* Chat page */ - -.chat.page { - display: none; -} - -/* Font */ - -.messages { - font-size: 150%; -} - -.inputMessage { - font-size: 100%; -} - -.log { - color: gray; - font-size: 70%; - margin: 5px; - text-align: center; -} - -/* Messages */ - -.chatArea { - height: 100%; - padding-bottom: 60px; -} - -.messages { - height: 100%; - margin: 0; - overflow-y: scroll; - padding: 10px 20px 10px 20px; -} - -.message.typing .messageBody { - color: gray; -} - -.username { - font-weight: 700; - overflow: hidden; - padding-right: 15px; - text-align: right; -} - -/* Input */ - -.inputMessage { - border: 10px solid #000; - bottom: 0; - height: 60px; - left: 0; - outline: none; - padding-left: 10px; - position: absolute; - right: 0; - width: 100%; -} diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock b/sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock deleted file mode 100644 index 73f334834..000000000 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless/yarn.lock +++ /dev/null @@ -1,352 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -body-parser@1.19.2: - version "1.19.2" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz" - integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.7" - raw-body "2.4.3" - type-is "~1.6.18" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.4.2: - version "0.4.2" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" - integrity sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -express@~4.17.1: - version "4.17.3" - resolved "https://registry.npmjs.org/express/-/express-4.17.3.tgz" - integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.19.2" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.4.2" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.9.7" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" - setprototypeof "1.2.0" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -http-errors@1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -inherits@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -qs@6.9.7: - version "6.9.7" - resolved "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz" - integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.3: - version "2.4.3" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz" - integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== - dependencies: - bytes "3.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - unpipe "1.0.0" - -safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -send@0.17.2: - version "0.17.2" - resolved "https://registry.npmjs.org/send/-/send-0.17.2.tgz" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "1.8.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.2" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -unpipe@~1.0.0, unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== From 1a401b23b7c2565c1589270732c5b3e9cfb493a7 Mon Sep 17 00:00:00 2001 From: Chenyang Liu Date: Mon, 2 Sep 2024 11:34:50 +0800 Subject: [PATCH 4/8] Revert --- samples/functions/js/simplechat/extensions.csproj | 10 ---------- samples/functions/js/simplechat/host.json | 4 ++++ 2 files changed, 4 insertions(+), 10 deletions(-) delete mode 100644 samples/functions/js/simplechat/extensions.csproj diff --git a/samples/functions/js/simplechat/extensions.csproj b/samples/functions/js/simplechat/extensions.csproj deleted file mode 100644 index 7b592c995..000000000 --- a/samples/functions/js/simplechat/extensions.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - netcoreapp3.1 - - ** - - - - - \ No newline at end of file diff --git a/samples/functions/js/simplechat/host.json b/samples/functions/js/simplechat/host.json index 8d1d95abe..d0dbe645a 100644 --- a/samples/functions/js/simplechat/host.json +++ b/samples/functions/js/simplechat/host.json @@ -4,5 +4,9 @@ "http": { "routePrefix": "api" } + }, + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle", + "version": "[3.3.*, 4.0.0)" } } \ No newline at end of file From 9d54e0d273ceb199a781096fca918d921eefde5f Mon Sep 17 00:00:00 2001 From: Chenyang Liu Date: Mon, 2 Sep 2024 16:30:51 +0800 Subject: [PATCH 5/8] Update some prompt --- .../examples/chat-serverless-dotnet/index.html | 2 +- .../examples/chat-serverless-javascript/src/public/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html index e277cbe7b..2c1322fa1 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html @@ -154,7 +154,7 @@

      Group Chat

      - +
      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 index 7e4b05fb4..4d4bb26c9 100644 --- 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 @@ -154,7 +154,7 @@

      Group Chat

      - +
      From f0212e9720b648ddd85b354cfb0aed665ee25392 Mon Sep 17 00:00:00 2001 From: Chenyang Liu Date: Tue, 3 Sep 2024 10:53:44 +0800 Subject: [PATCH 6/8] Add a simple js samples --- .../examples/chat-serverless-dotnet/README.md | 8 +- .../chat-serverless-dotnet.csproj | 2 +- .../{ => public}/index.html | 0 .../chat-serverless-javascript/README.md | 11 +- .../extensions.csproj | 7 +- .../chat-serverless-javascript/package.json | 16 +- .../src/functions/index.js | 31 ++ .../src/functions/message.js | 30 ++ .../src/functions/negotiate.js | 21 ++ .../src/public/index.html | 285 +++--------------- .../chat-serverless-typescript/.funcignore | 10 + .../chat-serverless-typescript/.gitignore | 48 +++ .../chat-serverless-typescript/README.md | 22 ++ .../extensions.csproj | 12 + .../chat-serverless-typescript/host.json | 11 + .../chat-serverless-typescript/package.json | 24 ++ .../src/functions/connect.ts | 0 .../src/functions/connected.ts | 0 .../src/functions/disconnected.ts | 0 .../src/functions/index.ts | 0 .../src/functions/message.ts | 0 .../src/functions/negotiate.ts | 0 .../src/index.ts | 0 .../src/public/index.html | 242 +++++++++++++++ .../tsconfig.json | 0 25 files changed, 513 insertions(+), 267 deletions(-) rename sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/{ => public}/index.html (100%) create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/index.js create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/message.js create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/src/functions/negotiate.js create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.funcignore create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/.gitignore create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/README.md create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/extensions.csproj create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/host.json create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/package.json rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/functions/connect.ts (100%) rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/functions/connected.ts (100%) rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/functions/disconnected.ts (100%) rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/functions/index.ts (100%) rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/functions/message.ts (100%) rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/functions/negotiate.ts (100%) rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/src/index.ts (100%) create mode 100644 sdk/webpubsub-socketio-extension/examples/chat-serverless-typescript/src/public/index.html rename sdk/webpubsub-socketio-extension/examples/{chat-serverless-javascript => chat-serverless-typescript}/tsconfig.json (100%) diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md index 6e71c037e..413f20f64 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/README.md @@ -5,12 +5,10 @@ This project is an Azure Function-based group chat application that leverages We ## Setup -### Update Connection String in `local.settings.json` +### Update Connection String -```json -{ -"WebPubSubForSocketIOConnectionString": "" -} +```bash +func settings add WebPubSubForSocketIOConnectionString "" ``` ## Run the sample 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 index b28bc4458..9a0892def 100644 --- 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 @@ -12,7 +12,7 @@ PreserveNewest - + Always diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html b/sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/public/index.html similarity index 100% rename from sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/index.html rename to sdk/webpubsub-socketio-extension/examples/chat-serverless-dotnet/public/index.html diff --git a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md index 8eae59345..b7646f2fa 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/README.md @@ -5,20 +5,17 @@ This project is an Azure Function-based group chat application that leverages We ## Setup -### Update Connection String in `local.settings.json` +### Update Connection String -```json -{ -"WebPubSubForSocketIOConnectionString": "" -} +```bash +func settings add WebPubSubForSocketIOConnectionString "" ``` # How to run ```bash func extensions sync -npm install -npm start +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 index e8d3aa2b6..71e8e96ce 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/extensions.csproj @@ -1,12 +1,11 @@ netcoreapp3.1 - true - - ** + + ** - + \ 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 index b7426489b..8ba10afa6 100644 --- a/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json +++ b/sdk/webpubsub-socketio-extension/examples/chat-serverless-javascript/package.json @@ -1,13 +1,9 @@ { - "name": "sampledev-javascript", + "name": "", "version": "1.0.0", "description": "", + "main": "src/functions/*.js", "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...\"" }, @@ -15,10 +11,6 @@ "@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}" + "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 index 4d4bb26c9..da6785d5c 100644 --- 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 @@ -1,242 +1,51 @@ - - - - - - - - Group Chat - - -