Slide 1

Slide 1 text

@MarcDuiker

Slide 2

Slide 2 text

@MarcDuiker 2 Marc Duiker Sr Developer Advocate

Slide 3

Slide 3 text

@MarcDuiker 3 Marc Duiker Sr Developer Advocate

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

@MarcDuiker 5 Durable Functions Learnings & Alternatives Entity Functions Synchronizing State Code Tour WebSockets Solution

Slide 6

Slide 6 text

@MarcDuiker

Slide 7

Slide 7 text

@MarcDuiker 7 Client 1 Client 2 Client 3

Slide 8

Slide 8 text

@MarcDuiker 8 Client 1 Client 2 Client 3 Server

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

@MarcDuiker

Slide 12

Slide 12 text

@MarcDuiker 12

Slide 13

Slide 13 text

@MarcDuiker 13

Slide 14

Slide 14 text

@MarcDuiker 14

Slide 15

Slide 15 text

@MarcDuiker 15

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

@MarcDuiker

Slide 18

Slide 18 text

@MarcDuiker 18

Slide 19

Slide 19 text

@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(); }

Slide 20

Slide 20 text

@MarcDuiker 20 await _durableClient.SignalEntityAsync( counterEntityId, proxy => proxy.Add(1)); var counter = await _durableClient.ReadEntityStateAsync( 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

Slide 21

Slide 21 text

@MarcDuiker

Slide 22

Slide 22 text

@MarcDuiker 22 Request Response Connection is terminated

Slide 23

Slide 23 text

@MarcDuiker 23 Handshake Request Handshake Response Bi-directional Connection remains open until client or server terminates

Slide 24

Slide 24 text

@MarcDuiker 24 let webSocket = new WebSocket(”ws://...”); webSocket.onopen = () => { ... }; webSocket.onmessage = (event) => { ... }; webSocket.send(...);

Slide 25

Slide 25 text

@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 => { ... });

Slide 26

Slide 26 text

@MarcDuiker 26

Slide 27

Slide 27 text

@MarcDuiker

Slide 28

Slide 28 text

@MarcDuiker

Slide 29

Slide 29 text

@MarcDuiker 29 Client Function App Monster (Player Entity) GameState (Entity) GameEngine Ably Signal InitGameState Signal AddPlayerName Publish UpdatePhase Publish AddPlayer CreateQuest Signal InitPlayer CreateQuest

Slide 30

Slide 30 text

@MarcDuiker https://github.com/ably-labs/serverless-websockets-quest/

Slide 31

Slide 31 text

@MarcDuiker

Slide 32

Slide 32 text

@MarcDuiker 33

Slide 33

Slide 33 text

@MarcDuiker 34

Slide 34

Slide 34 text

@MarcDuiker

Slide 35

Slide 35 text

@MarcDuiker 36

Slide 36

Slide 36 text

@MarcDuiker 37

Slide 37

Slide 37 text

@MarcDuiker

Slide 38

Slide 38 text

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