Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.

Commit

Permalink
更新
Browse files Browse the repository at this point in the history
  • Loading branch information
Yushu2606 committed Dec 1, 2023
1 parent 32c9098 commit d7fb0ff
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 318 deletions.
8 changes: 6 additions & 2 deletions Client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<PublishAot>true</PublishAot>
<RootNamespace>ChatRoom</RootNamespace>
<AssemblyName>聊天室</AssemblyName>
<ApplicationIcon>../Icon/favicon.ico</ApplicationIcon>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>

</Project>
10 changes: 9 additions & 1 deletion Client/Packet/Message.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Text.Json.Serialization;

namespace ChatRoom.Packet;

public record struct Request
Expand All @@ -11,4 +13,10 @@ public record struct Response
public DateTime DateTime { get; set; }
public string UserName { get; set; }
public string Message { get; set; }
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Request))]
[JsonSerializable(typeof(Response))]
internal partial class SourceGenerationContext : JsonSerializerContext
{
}
82 changes: 52 additions & 30 deletions Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using ChatRoom.Packet;
using ChatRoom.Utils;
using Microsoft.Extensions.Logging;
using System.CommandLine;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
Expand All @@ -13,33 +15,53 @@ internal class Client

internal static string UserName { get; set; }

private static void Main(string[] args)
private static int Main(string[] args)
{
// 进程互斥
_ = new Mutex(true, Assembly.GetExecutingAssembly().GetName().Name, out bool isNotRunning);
if (!isNotRunning && !args.Contains("--multi") && !args.Contains("-m"))
Option<bool> multiOption = new(
name: "--multi",
description: "运行重复运行实例。");
RootCommand rootCommand = new("Sample app for System.CommandLine");
rootCommand.AddOption(multiOption);
rootCommand.SetHandler((multi) =>
{
throw new EntryPointNotFoundException("你只能同时运行一个聊天室实例!");
}
// 进程互斥
_ = new Mutex(true, Assembly.GetExecutingAssembly().GetName().Name, out bool isNotRunning);
if (!isNotRunning && !multi)
{
throw new EntryPointNotFoundException("你只能同时运行一个聊天室实例!");
}
ChatMain();
}, multiOption);
return rootCommand.Invoke(args);
}

private static void ChatMain()
{
// 修复中文输入输出
Console.InputEncoding = Encoding.GetEncoding(936);
Console.OutputEncoding = Encoding.GetEncoding(936);
start:
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger("聊天室");
Console.Title = "聊天室";
TcpClient = new();
Console.Write("请输入服务器地址:");
string ip = Console.ReadLine();
try
{
TcpClient.Connect(ip, 19132);
}
catch (SocketException ex)
string ip;
while (true)
{
SimpleLogger.Error($"连接至{ip}失败:{ex.Message}");
goto start;
TcpClient = new();
Console.Write("请输入服务器地址:");
ip = Console.ReadLine();
try
{
TcpClient.Connect(ip, 19132);
}
catch (SocketException ex)
{
logger.LogError("连接至{IP}失败:{Message}", ip, ex.Message);
continue;
}
break;
}
Console.Title = $"聊天室:{ip}";
Dictionary<int, string> lastMessage = new();
Dictionary<int, string> lastMessage = [];
int lastOne = 0;
Console.Clear();
ThreadPool.QueueUserWorkItem((_) =>
Expand All @@ -54,34 +76,34 @@ private static void Main(string[] args)
{
continue;
}
stream.Read(bytes, 0, bytes.Length);
_ = stream.Read(bytes, 0, bytes.Length);
}
catch (IOException ex)
{
SimpleLogger.Error($"已断开连接:{ex.Message}");
logger.LogError("已断开连接:{Message}", ex.Message);
int count = 0;
while (!TcpClient.Connected)
{
TcpClient = new();
SimpleLogger.Info($"重连中:{++count}");
logger.LogInformation("重连中:{Count}", ++count);
try
{
TcpClient.Connect(ip, 19132);
}
catch (SocketException ex1)
{
SimpleLogger.Error($"重连至{ip}失败:{ex1.Message}");
logger.LogError("重连至{IP}失败:{Message}", ip, ex1.Message);
}
}
SimpleLogger.Info($"已重连至{ip}");
logger.LogInformation("已重连至{IP}", ip);
continue;
}
string receivedString = Encoding.UTF8.GetString(bytes).Replace("\0", string.Empty);
if (string.IsNullOrEmpty(receivedString))
{
continue;
}
Response data = JsonSerializer.Deserialize<Response>(receivedString);
Response data = JsonSerializer.Deserialize(receivedString, SourceGenerationContext.Default.Response);
if (lastMessage.TryGetValue(data.UUID, out string value) && value == data.Message)
{
continue;
Expand All @@ -100,23 +122,23 @@ private static void Main(string[] args)
lastOne = data.UUID;
}
});
SimpleLogger.Info($"已连接至{ip}");
logger.LogInformation("已连接至{IP}", ip);
while (true)
{
string line = Console.ReadLine();
if (string.IsNullOrEmpty(line) || !TcpClient.Connected)
{
continue;
}
if (line.StartsWith("/"))
if (line.StartsWith('/'))
{
try
{
Command.Process(line[1..].Split(' '), Command.Commands);
CommandHelper.Process(line[1..].Split(' '), CommandHelper.Commands);
}
catch (ArgumentException ex)
{
SimpleLogger.Error($"命令运行失败:{ex.Message}");
logger.LogError("命令运行失败:{Message}", ex.Message);
}
continue;
}
Expand All @@ -129,8 +151,8 @@ private static void Main(string[] args)
{
Message = line,
UserName = UserName
}));
}, SourceGenerationContext.Default.Request));
stream.Write(bytes, 0, bytes.Length);
}
}
}
}
18 changes: 9 additions & 9 deletions Client/Utils/Command.cs → Client/Utils/CommandHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace ChatRoom.Utils;

internal static class Command
internal static class CommandHelper
{
internal static Dictionary<string, CommandData> Commands { get; } = new()
{
Expand Down Expand Up @@ -47,30 +47,30 @@ internal static class Command
internal static void Process(IList<string> args, Dictionary<string, CommandData> commands, int deep = 1)
{
string mainCommand = args[deep - 1].ToUpper();
if (!commands.ContainsKey(mainCommand))
if (!commands.TryGetValue(mainCommand, out CommandData command))
{
throw new ArgumentException($"未知的命令:{args[deep - 1]}");
}
if (commands[mainCommand].Action is not null)
if (command.Action is not null)
{
List<string> newArgs = new(args);
if (args.Count - deep > 0)
{
newArgs.RemoveRange(0, deep);
}
commands[mainCommand].Action(newArgs);
command.Action(newArgs);
}
if (commands[mainCommand].SubCommands is not null)
if (command.SubCommands is not null)
{
if (args.Count <= deep)
{
foreach ((string command, CommandData commandData) in commands[mainCommand].SubCommands)
foreach ((string commandName, CommandData commandData) in command.SubCommands)
{
Console.WriteLine($" {command.ToLower()}\t{commandData.Description}");
Console.WriteLine($" {commandName.ToLower()}\t{commandData.Description}");
}
return;
}
Process(args, commands[mainCommand].SubCommands, deep + 1);
Process(args, command.SubCommands, deep + 1);
}
}
}
Expand All @@ -79,4 +79,4 @@ internal record struct CommandData
public string Description { get; set; }
public Action<List<string>> Action { get; set; }
public Dictionary<string, CommandData> SubCommands { get; set; }
}
}
Loading

0 comments on commit d7fb0ff

Please sign in to comment.