From 86804cf5f8a2cd94675ab6377cbdca71c47ca2f9 Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Tue, 20 May 2025 14:27:14 -0400 Subject: [PATCH] followed docs on server setup --- massive.sln | 26 +++++++++ server/.gitignore | 2 + server/Lib.cs | 116 +++++++++++++++++++++++++++++++++++++++ server/StdbModule.csproj | 14 +++++ server/global.json | 6 ++ 5 files changed, 164 insertions(+) create mode 100644 massive.sln create mode 100644 server/.gitignore create mode 100644 server/Lib.cs create mode 100644 server/StdbModule.csproj create mode 100644 server/global.json diff --git a/massive.sln b/massive.sln new file mode 100644 index 0000000..43f9d10 --- /dev/null +++ b/massive.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StdbModule", "server\StdbModule.csproj", "{25B51793-082D-44ED-A8D2-4A87A11F1882}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BDFCBF69-C44E-4188-A9FC-2CFED6EC2246}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDFCBF69-C44E-4188-A9FC-2CFED6EC2246}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDFCBF69-C44E-4188-A9FC-2CFED6EC2246}.Release|Any CPU.ActiveCfg = Debug|Any CPU + {BDFCBF69-C44E-4188-A9FC-2CFED6EC2246}.Release|Any CPU.Build.0 = Debug|Any CPU + {25B51793-082D-44ED-A8D2-4A87A11F1882}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25B51793-082D-44ED-A8D2-4A87A11F1882}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25B51793-082D-44ED-A8D2-4A87A11F1882}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25B51793-082D-44ED-A8D2-4A87A11F1882}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..1746e32 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/server/Lib.cs b/server/Lib.cs new file mode 100644 index 0000000..044257e --- /dev/null +++ b/server/Lib.cs @@ -0,0 +1,116 @@ +using SpacetimeDB; + +public static partial class Module +{ + [Table(Name = "User", Public = true)] + public partial class User + { + [PrimaryKey] + public Identity Identity; + public string? Name; + public bool Online; + } + + [Table(Name = "Message", Public = true)] + public partial class Message + { + public Identity Sender; + public Timestamp Sent; + public string Text = ""; + } + + [Reducer] + public static void SetName(ReducerContext ctx, string name) + { + name = ValidateName(name); + + var user = ctx.Db.User.Identity.Find(ctx.Sender); + if (user is not null) + { + user.Name = name; + ctx.Db.User.Identity.Update(user); + } + } + + /// Takes a name and checks if it's acceptable as a user's name. + private static string ValidateName(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Names must not be empty"); + } + return name; + } + + [Reducer] + public static void SendMessage(ReducerContext ctx, string text) + { + text = ValidateMessage(text); + Log.Info(text); + ctx.Db.Message.Insert( + new Message + { + Sender = ctx.Sender, + Text = text, + Sent = ctx.Timestamp, + } + ); + } + + /// Takes a message's text and checks if it's acceptable to send. + private static string ValidateMessage(string text) + { + if (string.IsNullOrEmpty(text)) + { + throw new ArgumentException("Messages must not be empty"); + } + return text; + } + + [Reducer(ReducerKind.ClientConnected)] + public static void ClientConnected(ReducerContext ctx) + { + Log.Info($"Connect {ctx.Sender}"); + var user = ctx.Db.User.Identity.Find(ctx.Sender); + + if (user is not null) + { + // If this is a returning user, i.e., we already have a `User` with this `Identity`, + // set `Online: true`, but leave `Name` and `Identity` unchanged. + user.Online = true; + ctx.Db.User.Identity.Update(user); + } + else + { + // If this is a new user, create a `User` object for the `Identity`, + // which is online, but hasn't set a name. + ctx.Db.User.Insert( + new User + { + Name = null, + Identity = ctx.Sender, + Online = true, + } + ); + } + } + + [Reducer(ReducerKind.ClientDisconnected)] + public static void ClientDisconnected(ReducerContext ctx) + { + var user = ctx.Db.User.Identity.Find(ctx.Sender); + + if (user is not null) + { + // This user should exist, so set `Online: false`. + user.Online = false; + ctx.Db.User.Identity.Update(user); + } + else + { + // User does not exist, log warning + Log.Warn("Warning: No user found for disconnected client."); + } + } +} + diff --git a/server/StdbModule.csproj b/server/StdbModule.csproj new file mode 100644 index 0000000..3284863 --- /dev/null +++ b/server/StdbModule.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + wasi-wasm + enable + enable + + + + + + + diff --git a/server/global.json b/server/global.json new file mode 100644 index 0000000..4e550c1 --- /dev/null +++ b/server/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "8.0.400", + "rollForward": "latestMinor" + } +}