diff --git a/Lab1/.vscode/launch.json b/Lab1/.vscode/launch.json
new file mode 100644
index 0000000..54b90be
--- /dev/null
+++ b/Lab1/.vscode/launch.json
@@ -0,0 +1,38 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "ChatRoom",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build-ChatRoom",
+ "program": "${workspaceFolder}/ChatRoom/bin/Debug/net6.0/ChatRoom.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}/ChatRoom",
+ "console": "externalTerminal",
+ "stopAtEntry": false
+ },
+ {
+ "name": "Moderator",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build-Moderator",
+ "program": "${workspaceFolder}/Moderator/bin/Debug/net6.0/Moderator.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}/Moderator",
+ "console": "externalTerminal",
+ "stopAtEntry": false
+ },
+ {
+ "name": "Participant",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build-Participant",
+ "program": "${workspaceFolder}/Participant/bin/Debug/net6.0/Participant.dll",
+ "args": [],
+ "cwd": "${workspaceFolder}/Participant",
+ "console": "externalTerminal",
+ "stopAtEntry": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Lab1/.vscode/tasks.json b/Lab1/.vscode/tasks.json
new file mode 100644
index 0000000..cf312c1
--- /dev/null
+++ b/Lab1/.vscode/tasks.json
@@ -0,0 +1,41 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build-ChatRoom",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "build",
+ "${workspaceFolder}/ChatRoom/ChatRoom.csproj",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "build-Moderator",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "build",
+ "${workspaceFolder}/Moderator/Moderator.csproj",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "build-Participant",
+ "command": "dotnet",
+ "type": "process",
+ "args": [
+ "build",
+ "${workspaceFolder}/Participant/Participant.csproj",
+ "/property:GenerateFullPaths=true",
+ "/consoleloggerparameters:NoSummary"
+ ],
+ "problemMatcher": "$msCompile"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Lab1/ChatRoom/ChatRoomLogic.cs b/Lab1/ChatRoom/ChatRoomLogic.cs
index d431007..2c6b4bd 100644
--- a/Lab1/ChatRoom/ChatRoomLogic.cs
+++ b/Lab1/ChatRoom/ChatRoomLogic.cs
@@ -1,16 +1,13 @@
-namespace ChatRoom;
+using NLog;
+
+namespace ChatRoom;
public class ChatRoomLogic
{
- ///
- /// Background task thread.
- ///
private Thread thread;
-
- ///
- /// State descriptor.
- ///
private ChatRoomState state = new ChatRoomState();
+ private Logger log = LogManager.GetCurrentClassLogger();
+
public ChatRoomLogic()
{
@@ -18,6 +15,20 @@ public class ChatRoomLogic
thread.Start();
}
+ public int RegisterClient(string name)
+ {
+ lock (state.accessLock)
+ {
+ int clientId = state.lastUniqueId;
+ state.clients.Add(new Client{
+ id = clientId,
+ name = name
+ });
+ log.Info($"Registered with client '{name}' with id {clientId}");
+ return clientId;
+ }
+ }
+
public void BackgroundTask()
{
while (true)
diff --git a/Lab1/ChatRoom/ChatRoomService.cs b/Lab1/ChatRoom/ChatRoomService.cs
index bd2527a..7997fb2 100644
--- a/Lab1/ChatRoom/ChatRoomService.cs
+++ b/Lab1/ChatRoom/ChatRoomService.cs
@@ -7,12 +7,12 @@ public class ChatRoomService : IChatRoomService
//NOTE: instance-per-request service would need logic to be static or injected from a singleton instance
private readonly ChatRoomLogic logic = new ChatRoomLogic();
- public void ApproveMessage(int messageId)
+ public int RegisterClient(string name)
{
- throw new NotImplementedException();
+ return logic.RegisterClient(name);
}
- public int GetClientId()
+ public void ApproveMessage(int messageId)
{
throw new NotImplementedException();
}
@@ -22,7 +22,7 @@ public class ChatRoomService : IChatRoomService
throw new NotImplementedException();
}
- public int GetStrikes()
+ public int GetStrikes(int clientId)
{
throw new NotImplementedException();
}
@@ -32,12 +32,7 @@ public class ChatRoomService : IChatRoomService
throw new NotImplementedException();
}
- public bool SendMessage(string contents)
- {
- throw new NotImplementedException();
- }
-
- public void SetClientName(string name)
+ public bool SendMessage(int clientId, string contents)
{
throw new NotImplementedException();
}
diff --git a/Lab1/ChatRoom/ChatRoomState.cs b/Lab1/ChatRoom/ChatRoomState.cs
index 8ef5695..f175d8a 100644
--- a/Lab1/ChatRoom/ChatRoomState.cs
+++ b/Lab1/ChatRoom/ChatRoomState.cs
@@ -1,14 +1,23 @@
namespace ChatRoom;
+public class Client
+{
+ public int id;
+ public string name;
+ public int strikes = 0;
+}
+
public class ChatRoomState
{
///
/// Access lock.
///
- public readonly object AccessLock = new object();
+ public readonly object accessLock = new object();
///
/// Last unique ID value generated.
///
- public int LastUniqueId;
+ public int lastUniqueId;
+
+ public List clients = new List();
}
diff --git a/Lab1/ChatRoomContract/IChatRoomService.cs b/Lab1/ChatRoomContract/IChatRoomService.cs
index eed2760..8c1f03f 100644
--- a/Lab1/ChatRoomContract/IChatRoomService.cs
+++ b/Lab1/ChatRoomContract/IChatRoomService.cs
@@ -9,13 +9,11 @@ public class Message
public interface IChatRoomService
{
- int GetClientId();
+ int RegisterClient(string name);
- void SetClientName(string name);
+ int GetStrikes(int clientId);
- int GetStrikes();
-
- bool SendMessage(string contents);
+ bool SendMessage(int clientId, string contents);
Message? GetNewMessage();
diff --git a/Lab1/Lab1.sln b/Lab1/Lab1.sln
index 65b65e6..0147fab 100644
--- a/Lab1/Lab1.sln
+++ b/Lab1/Lab1.sln
@@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35208.52
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatRoom", "ChatRoom\ChatRoom.csproj", "{BA24D5FC-9D95-4E0B-8A0C-47CDAD181ADF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatRoom", "ChatRoom\ChatRoom.csproj", "{BA24D5FC-9D95-4E0B-8A0C-47CDAD181ADF}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatRoomContract", "ChatRoomContract\ChatRoomContract.csproj", "{22CBCBA6-8B72-474F-95F5-D07F1A59114F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatRoomContract", "ChatRoomContract\ChatRoomContract.csproj", "{22CBCBA6-8B72-474F-95F5-D07F1A59114F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moderator", "Moderator\Moderator.csproj", "{5FD486F7-E980-4479-96B0-DCE2167A313D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moderator", "Moderator\Moderator.csproj", "{5FD486F7-E980-4479-96B0-DCE2167A313D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Participant", "Participant\Participant.csproj", "{03C7B2D5-7EFE-416A-B551-31C456C87E63}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -27,6 +29,10 @@ Global
{5FD486F7-E980-4479-96B0-DCE2167A313D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FD486F7-E980-4479-96B0-DCE2167A313D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FD486F7-E980-4479-96B0-DCE2167A313D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {03C7B2D5-7EFE-416A-B551-31C456C87E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {03C7B2D5-7EFE-416A-B551-31C456C87E63}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {03C7B2D5-7EFE-416A-B551-31C456C87E63}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {03C7B2D5-7EFE-416A-B551-31C456C87E63}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Lab1/Moderator/Moderator.cs b/Lab1/Moderator/Moderator.cs
index 179d15a..8033b3e 100644
--- a/Lab1/Moderator/Moderator.cs
+++ b/Lab1/Moderator/Moderator.cs
@@ -5,7 +5,6 @@ using SimpleRpc.Transports.Http.Client;
using SimpleRpc.Serialization.Hyperion;
using SimpleRpc.Transports;
using System.Diagnostics;
-using System.Security.Cryptography;
namespace Moderator;
@@ -28,7 +27,7 @@ internal class Moderator
///
/// Logger for this class.
///
- Logger mLog = LogManager.GetCurrentClassLogger();
+ Logger log = LogManager.GetCurrentClassLogger();
///
/// Configures logging subsystem.
@@ -53,9 +52,11 @@ internal class Moderator
var rnd = new Random();
var name = FIRSTNAMES[rnd.Next(FIRSTNAMES.Count)] + " " + LASTNAMES[rnd.Next(LASTNAMES.Count)];
- Console.Title = $"Moderator | ${name}";
- chatRoom.SetClientName(name);
+ int clientId = chatRoom.RegisterClient(name);
+ log.Info($"Registered with client id {clientId}");
+
+ Console.Title = $"Moderator | {name} | {clientId}";
while (true)
{
@@ -100,7 +101,7 @@ internal class Moderator
catch (Exception e)
{
//log whatever exception to console
- mLog.Warn(e, "Unhandled exception caught. Will restart main loop.");
+ log.Warn(e, "Unhandled exception caught. Will restart main loop.");
//prevent console spamming
Thread.Sleep(2000);
diff --git a/Lab1/Participant/Participant.cs b/Lab1/Participant/Participant.cs
new file mode 100644
index 0000000..917312a
--- /dev/null
+++ b/Lab1/Participant/Participant.cs
@@ -0,0 +1,116 @@
+using ChatRoomContract;
+using Microsoft.Extensions.DependencyInjection;
+using NLog;
+using SimpleRpc.Transports.Http.Client;
+using SimpleRpc.Serialization.Hyperion;
+using SimpleRpc.Transports;
+using System.Diagnostics;
+
+namespace Participant;
+
+internal class Participant
+{
+ private readonly List FIRSTNAMES =
+ new List {
+ "John", "Peter", "Jack", "Steve"
+ };
+
+ ///
+ /// A set of surnames to choose from.
+ ///
+ private readonly List LASTNAMES =
+ new List {
+ "Johnson", "Peterson", "Jackson", "Steveson"
+ };
+
+
+ ///
+ /// Logger for this class.
+ ///
+ Logger log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Configures logging subsystem.
+ ///
+ private void ConfigureLogging()
+ {
+ var config = new NLog.Config.LoggingConfiguration();
+
+ var console =
+ new NLog.Targets.ConsoleTarget("console")
+ {
+ Layout = @"${date:format=HH\:mm\:ss}|${level}| ${message} ${exception}"
+ };
+ config.AddTarget(console);
+ config.AddRuleForAllLevels(console);
+
+ LogManager.Configuration = config;
+ }
+
+ private void RunConnection(IChatRoomService chatRoom)
+ {
+ var rnd = new Random();
+
+ var name = FIRSTNAMES[rnd.Next(FIRSTNAMES.Count)] + " " + LASTNAMES[rnd.Next(LASTNAMES.Count)];
+
+ int clientId = chatRoom.RegisterClient(name);
+ log.Info($"Registered with client id {clientId}");
+
+ Console.Title = $"Participant | {name} | {clientId}";
+ while (true)
+ {
+
+ }
+ }
+
+ private void Run()
+ {
+ //configure logging
+ ConfigureLogging();
+
+ //initialize random number generator
+ var rnd = new Random();
+
+ while (true)
+ {
+ //connect to the server, get service client proxy
+ var sc = new ServiceCollection();
+ sc
+ .AddSimpleRpcClient(
+ "chatRoomService", //must be same as on line 86
+ new HttpClientTransportOptions
+ {
+ Url = "http://127.0.0.1:5000/simplerpc",
+ Serializer = "HyperionMessageSerializer"
+ }
+ )
+ .AddSimpleRpcHyperionSerializer();
+
+ sc.AddSimpleRpcProxy("chatRoomService"); //must be same as on line 77
+
+ var sp = sc.BuildServiceProvider();
+
+ var chatRoom = sp.GetService();
+ Debug.Assert(chatRoom != null);
+
+ try
+ {
+ RunConnection(chatRoom);
+ }
+ catch (Exception e)
+ {
+ //log whatever exception to console
+ log.Warn(e, "Unhandled exception caught. Will restart main loop.");
+
+ //prevent console spamming
+ Thread.Sleep(2000);
+ }
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ var self = new Participant();
+ self.Run();
+ }
+}
diff --git a/Lab1/Participant/Participant.csproj b/Lab1/Participant/Participant.csproj
new file mode 100644
index 0000000..ff4f6e0
--- /dev/null
+++ b/Lab1/Participant/Participant.csproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+