$30 off During Our Annual Pro Sale. View Details »

Quest for serverless WebSockets - an adventure with Azure Functions and Durable Functions

Quest for serverless WebSockets - an adventure with Azure Functions and Durable Functions

Session for dotnetdays Romania at 22 Oct 2022.
GitHub repo: https://github.com/ably-labs/serverless-websockets-quest

Marc Duiker

October 22, 2022
Tweet

More Decks by Marc Duiker

Other Decks in Programming

Transcript

  1. @MarcDuiker

  2. @MarcDuiker 2 Marc Duiker Sr Developer Advocate

  3. @MarcDuiker 3 Marc Duiker Sr Developer Advocate

  4. @MarcDuiker https://quest.ably.dev/

  5. @MarcDuiker 5 Durable Functions Learnings & Alternatives Entity Functions Synchronizing

    State Code Tour WebSockets Solution
  6. @MarcDuiker

  7. @MarcDuiker 7 Client 1 Client 2 Client 3

  8. @MarcDuiker 8 Client 1 Client 2 Client 3 Server

  9. @MarcDuiker 9 Client 1 Client 2 Client 3 Serverless HTTP

    HTTP HTTP WS WS WS
  10. @MarcDuiker 10 Client 1 Client 2 Client 3 HTTP HTTP

    HTTP WS WS WS HTTP Ably
  11. @MarcDuiker

  12. @MarcDuiker 12

  13. @MarcDuiker 13

  14. @MarcDuiker 14

  15. @MarcDuiker 15

  16. @MarcDuiker 16 https://github.com/marcduiker/durable-functions-use-cases

  17. @MarcDuiker

  18. @MarcDuiker 18

  19. @MarcDuiker 19 public class Counter : ICounter { [JsonProperty("value")] public

    int CurrentValue { get; set; } public void Add(int amount) => this.CurrentValue += amount; public void Reset() => this.CurrentValue = 0; [FunctionName(nameof(Counter))] public static Task Run([EntityTrigger] IDurableEntityContext ctx) => ctx.DispatchAsync<Counter>(); }
  20. @MarcDuiker 20 await _durableClient.SignalEntityAsync<ICounter>( counterEntityId, proxy => proxy.Add(1)); var counter

    = await _durableClient.ReadEntityStateAsync<Counter>( counterEntityId); var current = counter.EntityState.CurrentValue; var counterEntityId = new EntityId(nameof(Counter), counterId); https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-dotnet-entities
  21. @MarcDuiker

  22. @MarcDuiker 22 Request Response Connection is terminated

  23. @MarcDuiker 23 Handshake Request Handshake Response Bi-directional Connection remains open

    until client or server terminates
  24. @MarcDuiker 24 let webSocket = new WebSocket(”ws://...”); webSocket.onopen = ()

    => { ... }; webSocket.onmessage = (event) => { ... }; webSocket.send(...);
  25. @MarcDuiker 25 var ablyClient = new AblyRealtime(ABLY_API_KEY); var channel =

    ablyClient.Channels.Get(CHANNEL_NAME); channel.Subscribe(“chat-message”, message => { ... }); await channel.PublishAsync( “chat-message", new { user = "Marc“, message = "Hi there!" }); ablyClient.Connection.On(ConnectionEvent.Connected, args => { ... });
  26. @MarcDuiker 26

  27. @MarcDuiker

  28. @MarcDuiker

  29. @MarcDuiker 29 Client Function App Monster (Player Entity) GameState (Entity)

    GameEngine Ably Signal InitGameState Signal AddPlayerName Publish UpdatePhase Publish AddPlayer CreateQuest Signal InitPlayer CreateQuest
  30. @MarcDuiker https://github.com/ably-labs/serverless-websockets-quest/

  31. @MarcDuiker

  32. @MarcDuiker 33

  33. @MarcDuiker 34

  34. @MarcDuiker

  35. @MarcDuiker 36

  36. @MarcDuiker 37

  37. @MarcDuiker

  38. @MarcDuiker Twitter: @marcduiker GitHub: https://github.com/ably-labs/serverless-websockets-quest/ Ably Discord: http://go.ably.com/discord