Skip to content

Commit

Permalink
cleaned up ChatClient / ChatServer sample (#6824)
Browse files Browse the repository at this point in the history
* removed mutable state on messages
* migrated to using record types for all messages
* `await` on `ActorSystem` termination
* cleaned up styles and formatting
  • Loading branch information
Aaronontheweb committed Jul 7, 2023
1 parent 608d9e8 commit 68e0d78
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 133 deletions.
90 changes: 41 additions & 49 deletions src/examples/Chat/ChatClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using System;
using System.Linq;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Configuration;
using ChatMessages;
Expand All @@ -15,7 +16,7 @@ namespace ChatClient
{
class Program
{
static void Main(string[] args)
public static async Task Main(string[] args)
{
var config = ConfigurationFactory.ParseString(@"
akka {
Expand All @@ -31,54 +32,50 @@ static void Main(string[] args)
}
");

using (var system = ActorSystem.Create("MyClient", config))
var system = ActorSystem.Create("MyClient", config);
var chatClient = system.ActorOf(Props.Create<ChatClientActor>());
chatClient.Tell(new ConnectRequest("Roggan"));

while (true)
{
var chatClient = system.ActorOf(Props.Create<ChatClientActor>());
chatClient.Tell(new ConnectRequest()
var input = Console.ReadLine();
if (input.StartsWith('/'))
{
Username = "Roggan",
});
var parts = input.Split(' ');
var cmd = parts[0].ToLowerInvariant();
var rest = string.Join(" ", parts.Skip(1));

while (true)
{
var input = Console.ReadLine();
if (input.StartsWith('/'))
if (cmd == "/nick")
{
var parts = input.Split(' ');
var cmd = parts[0].ToLowerInvariant();
var rest = string.Join(" ", parts.Skip(1));

if (cmd == "/nick")
{
chatClient.Tell(new NickRequest
{
NewUsername = rest
});
}
if (cmd == "/exit")
{
Console.WriteLine("exiting");
break;
}
chatClient.Tell(new ChatClientActor.RequestNewNick(rest));
}
else

if (cmd == "/exit")
{
chatClient.Tell(new SayRequest()
{
Text = input,
});
Console.WriteLine("exiting");
break;
}
}

system.Terminate().Wait();
else
{
chatClient.Tell(new ChatClientActor.PushNewChatMessage(input));
}
}

await system.Terminate();
}
}

class ChatClientActor : ReceiveActor, ILogReceive
internal class ChatClientActor : ReceiveActor, ILogReceive
{
private string _nick = "Roggan";
private readonly ActorSelection _server = Context.ActorSelection("akka.tcp://MyServer@localhost:8081/user/ChatServer");

private readonly ActorSelection _server =
Context.ActorSelection("akka.tcp://MyServer@localhost:8081/user/ChatServer");

public record RequestNewNick(string NewNick);

public record PushNewChatMessage(string Message);

public ChatClientActor()
{
Expand All @@ -94,30 +91,25 @@ public ChatClientActor()
Console.WriteLine(rsp.Message);
});

Receive<NickRequest>(nr =>
Receive<RequestNewNick>(nr =>
{
nr.OldUsername = _nick;
Console.WriteLine("Changing nick to {0}", nr.NewUsername);
_nick = nr.NewUsername;
_server.Tell(nr);
Console.WriteLine("Changing nick to {0}", nr.NewNick);
var request = new NickRequest(_nick, nr.NewNick);
_nick = nr.NewNick;
_server.Tell(request);
});

Receive<NickResponse>(nrsp =>
{
Console.WriteLine("{0} is now known as {1}", nrsp.OldUsername, nrsp.NewUsername);
});

Receive<SayRequest>(sr =>
Receive<PushNewChatMessage>(sr =>
{
sr.Username = _nick;
_server.Tell(sr);
_server.Tell(new SayRequest(_nick, sr.Message));
});

Receive<SayResponse>(srsp =>
{
Console.WriteLine("{0}: {1}", srsp.Username, srsp.Text);
});
Receive<SayResponse>(srsp => { Console.WriteLine("{0}: {1}", srsp.Username, srsp.Text); });
}
}
}

}
6 changes: 1 addition & 5 deletions src/examples/Chat/ChatMessages/ChatMessages.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>$(NetStandardLibVersion)</TargetFramework>
<TargetFramework>$(NetTestVersion)</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\core\Akka\Akka.csproj" />
</ItemGroup>
Expand Down
47 changes: 15 additions & 32 deletions src/examples/Chat/ChatMessages/Messages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,24 @@
// </copyright>
//-----------------------------------------------------------------------

using Akka.Actor;

namespace ChatMessages
{
public class ConnectRequest
{
public string Username { get; set; }
}

public class ConnectResponse
{
public string Message { get; set; }
}

public class NickRequest
{
public string OldUsername { get; set; }
public string NewUsername { get; set; }
}
/// <summary>
/// Marker interface for all chat messages exchanged between client and server
/// </summary>
/// <remarks>
/// Currently not used for anything - can be used in the future for serialization
/// or routing purposes.
/// </remarks>
public interface IChatProtocol { }

public record ConnectRequest(string Username) : IChatProtocol;

public class NickResponse
{
public string OldUsername { get; set; }
public string NewUsername { get; set; }
}
public record ConnectResponse(string Message) : IChatProtocol;

public class SayRequest
{
public string Username { get; set; }
public string Text { get; set; }
}
public record NickRequest(string OldUsername, string NewUsername) : IChatProtocol;
public record NickResponse(string OldUsername, string NewUsername) : IChatProtocol;
public record SayRequest(string Username, string Text) : IChatProtocol;

public class SayResponse
{
public string Username { get; set; }
public string Text { get; set; }
}
public record SayResponse(string Username, string Text) : IChatProtocol;
}
20 changes: 0 additions & 20 deletions src/examples/Chat/ChatServer/App.config

This file was deleted.

4 changes: 0 additions & 4 deletions src/examples/Chat/ChatServer/ChatServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,4 @@
<ProjectReference Include="..\ChatMessages\ChatMessages.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>

</Project>
35 changes: 12 additions & 23 deletions src/examples/Chat/ChatServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Configuration;
using ChatMessages;
Expand All @@ -15,7 +16,7 @@ namespace ChatServer
{
class Program
{
static void Main(string[] args)
public static async Task Main(string[] args)
{
var config = ConfigurationFactory.ParseString(@"
akka {
Expand All @@ -32,51 +33,39 @@ static void Main(string[] args)
}
");

using (var system = ActorSystem.Create("MyServer", config))
{
system.ActorOf(Props.Create(() => new ChatServerActor()), "ChatServer");
var system = ActorSystem.Create("MyServer", config);

system.ActorOf(Props.Create(() => new ChatServerActor()), "ChatServer");

Console.ReadLine();
}
Console.ReadLine();
await system.Terminate();
}
}

class ChatServerActor : ReceiveActor, ILogReceive
internal class ChatServerActor : ReceiveActor, ILogReceive
{
private readonly HashSet<IActorRef> _clients = new();

public ChatServerActor()
{
Receive<SayRequest>(message =>
{
var response = new SayResponse
{
Username = message.Username,
Text = message.Text,
};
var response = new SayResponse(message.Username, message.Text);
foreach (var client in _clients) client.Tell(response, Self);
});

Receive<ConnectRequest>(_ =>
{
_clients.Add(Sender);
Sender.Tell(new ConnectResponse
{
Message = "Hello and welcome to Akka.NET chat example",
}, Self);
Sender.Tell(new ConnectResponse("Hello and welcome to Akka.NET chat example"), Self);
});

Receive<NickRequest>(message =>
{
var response = new NickResponse
{
OldUsername = message.OldUsername,
NewUsername = message.NewUsername,
};
var response = new NickResponse(message.OldUsername, message.NewUsername);
foreach (var client in _clients) client.Tell(response, Self);
});
}
}
}

}

0 comments on commit 68e0d78

Please sign in to comment.