Quest for serverless WebSockets, an adventure with Azure Functions & Durable Entities

This page summarizes the projects mentioned and recommended in the original post on dev.to

Our great sponsors
  • SurveyJS - Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App
  • WorkOS - The modern identity platform for B2B SaaS
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • serverless-websockets-quest

    An ADND style web-based game that combines serverless with websockets to achieve a realtime experience

  • [JsonObject(MemberSerialization.OptIn)] public class GameState : IGameState { // Only showing the class members relevant for this blog section. // For the full implementation see https://github.com/ably-labs/serverless-websockets-quest/blob/main/api/Models/GameState.cs [JsonProperty("questId")] public string QuestId { get; set; } [JsonProperty("phase")] public string Phase { get; set; } public async Task InitGameState(string[] gameStateFields) { QuestId = gameStateFields[0]; Phase = gameStateFields[1]; await _publisher.PublishUpdatePhase(QuestId, Phase); } [JsonProperty("players")] public List PlayerNames { get; set; } public async Task AddPlayerName(string playerName) { if (PlayerNames == null) { PlayerNames = new List { playerName }; } else { PlayerNames.Add(playerName); } if (IsPartyComplete) { await UpdatePhase(GamePhases.Play); await Task.Delay(2000); await AttackByMonster(); } } public async Task UpdatePhase(string phase) { Phase = phase; await _publisher.PublishUpdatePhase(QuestId, Phase); } private async Task AttackByMonster() { var playerAttacking = CharacterClassDefinitions.Monster.Name; var playerUnderAttack = GetRandomPlayerName(); var damage = CharacterClassDefinitions.GetDamageFor(CharacterClassDefinitions.Monster.CharacterClass); await _publisher.PublishPlayerAttacking(QuestId, playerAttacking, playerUnderAttack, damage); await Task.Delay(1000); var playerEntityId = new EntityId(nameof(Player), Player.GetEntityId(QuestId, playerUnderAttack)); Entity.Current.SignalEntity(playerEntityId, proxy => proxy.ApplyDamage(damage)); await Task.Delay(1000); var nextPlayerName = GetNextPlayerName(CharacterClassDefinitions.Monster.Name); await _publisher.PublishPlayerTurnAsync(QuestId, $"Next turn: {nextPlayerName}", nextPlayerName); } }

  • static-web-apps-cli

    Azure Static Web Apps CLI ✨

  • Azure Static Web Apps CLI. This is the command line interface to develop and deploy Azure Static Web Apps. Install this tool globally by running this command in the terminal: npm install -g @azure/static-web-apps-cli.

  • SurveyJS

    Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.

    SurveyJS logo
  • Vue.js

    This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

  • VueJS, a well-known front-end framework.

  • Puts Debuggerer

    Ruby library for improved puts debugging, automatically displaying bonus useful information such as source line number and source code.

  • [JsonObject(MemberSerialization.OptIn)] public class GameState : IGameState { // Only showing the class members relevant for this blog section. // For the full implementation see https://github.com/ably-labs/serverless-websockets-quest/blob/main/api/Models/GameState.cs [JsonProperty("questId")] public string QuestId { get; set; } [JsonProperty("phase")] public string Phase { get; set; } public async Task InitGameState(string[] gameStateFields) { QuestId = gameStateFields[0]; Phase = gameStateFields[1]; await _publisher.PublishUpdatePhase(QuestId, Phase); } [JsonProperty("players")] public List PlayerNames { get; set; } public async Task AddPlayerName(string playerName) { if (PlayerNames == null) { PlayerNames = new List { playerName }; } else { PlayerNames.Add(playerName); } if (IsPartyComplete) { await UpdatePhase(GamePhases.Play); await Task.Delay(2000); await AttackByMonster(); } } public async Task UpdatePhase(string phase) { Phase = phase; await _publisher.PublishUpdatePhase(QuestId, Phase); } private async Task AttackByMonster() { var playerAttacking = CharacterClassDefinitions.Monster.Name; var playerUnderAttack = GetRandomPlayerName(); var damage = CharacterClassDefinitions.GetDamageFor(CharacterClassDefinitions.Monster.CharacterClass); await _publisher.PublishPlayerAttacking(QuestId, playerAttacking, playerUnderAttack, damage); await Task.Delay(1000); var playerEntityId = new EntityId(nameof(Player), Player.GetEntityId(QuestId, playerUnderAttack)); Entity.Current.SignalEntity(playerEntityId, proxy => proxy.ApplyDamage(damage)); await Task.Delay(1000); var nextPlayerName = GetNextPlayerName(CharacterClassDefinitions.Monster.Name); await _publisher.PublishPlayerTurnAsync(QuestId, $"Next turn: {nextPlayerName}", nextPlayerName); } }

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts