Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web chat #6

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions WebChat/WebChat.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebChat", "WebChat\WebChat.csproj", "{26C3FA72-8E5F-42C8-BDB0-3BE8CF16BD14}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{26C3FA72-8E5F-42C8-BDB0-3BE8CF16BD14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26C3FA72-8E5F-42C8-BDB0-3BE8CF16BD14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26C3FA72-8E5F-42C8-BDB0-3BE8CF16BD14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26C3FA72-8E5F-42C8-BDB0-3BE8CF16BD14}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
53 changes: 53 additions & 0 deletions WebChat/WebChat/Client.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace WebChat;

using System.Net.Sockets;

/// <summary>
/// Chat client.
/// </summary>
public class Client : IDisposable
{
private readonly TcpClient _client;

private readonly NetworkStream _networkStream;

/// <summary>
/// Initializes a new instance of the <see cref="Client"/> class.
/// </summary>
public Client(string host, int port)
{
_client = new TcpClient(host, port);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так TcpClient сразу начнёт подключаться к хосту, синхронно. Правильнее было создать TcpClient конструктором без параметров, а потом, уже в RunAsync, вызвать ConnectAsync.


_networkStream = _client.GetStream();
}

/// <summary>
/// Gets a value indicating whether the client is disposed.
/// </summary>
public bool IsDisposed { get; private set; }

/// <summary>
/// Releases all resources used by the current instance of the <see cref="Client"/> class.
/// </summary>
public void Dispose()
{
if (IsDisposed)
{
return;
}

_networkStream.Dispose();
_client.Dispose();

IsDisposed = true;
}

/// <summary>
/// Runs client.
/// </summary>
public async Task RunAsync()
{
await Processing.ProcessQuery(_networkStream);
}

}
45 changes: 45 additions & 0 deletions WebChat/WebChat/Processing.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
namespace WebChat;

using System.Net.Sockets;

/// <summary>
/// Class for processing get and post queries.
/// </summary>
public static class Processing
{
/// <summary>
/// Processes get and post queries.
/// </summary>
/// <param name="stream">Working stream.</param>
public static async Task ProcessQuery(NetworkStream stream)
{
await Task.Run(async () => await Post(stream));
await Task.Run(async () => await Get(stream));
Comment on lines +16 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так мы сначала должны будем дождаться выполнения Post, а уже затем переходить к Get. Что не очень для чата. Надо было

var task1 = Post(stream);
var task2 = Get(stream);
await task1;
await task2;

Есть большая разница, когда делать await

}

private static async Task Post(NetworkStream stream)
{
while (true)
{
var writer = new StreamWriter(stream);
var message = Console.ReadLine();
await writer.WriteAsync(message);
await writer.FlushAsync();
await stream.FlushAsync();

writer = null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Бесполезно, всё равно его перетрёт тут же

}
}

private static async Task Get(NetworkStream stream)
{
while (true)
{
var reader = new StreamReader(stream);
var message = await reader.ReadLineAsync();
Console.WriteLine(message);

reader = null;
}
}
}
43 changes: 43 additions & 0 deletions WebChat/WebChat/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using WebChat;

switch (args.Length)
{
case 1:
{
await StartServer(args);
break;
}

case 2:
{
await StartClient(args);
break;
}

default:
{
throw new ArgumentException();
}
}

async Task StartClient(string[] args)
{
if (!int.TryParse(args[1], out var port))
{
throw new ArgumentException();
}

using var client = new Client(args[0], port);
await client.RunAsync();
}

async Task StartServer(string[] args)
{
if (!int.TryParse(args[0], out var port))
{
throw new ArgumentException();
}

using var server = new Server(port);
await server.RunAsync();
}
68 changes: 68 additions & 0 deletions WebChat/WebChat/Server.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
namespace WebChat;

using System.Net;
using System.Net.Sockets;

/// <summary>
/// Chat server.
/// </summary>
public class Server : IDisposable
{
private readonly TcpListener _listener;

private readonly CancellationTokenSource _cts = new ();

/// <summary>
/// Initializes a new instance of the <see cref="Server"/> class.
/// </summary>
public Server(int port)
{
_listener = new TcpListener(IPAddress.Any, port);
}

/// <summary>
/// Gets a value indicating whether the server is disposed.
/// </summary>
public bool IsDisposed { get; private set; }

private void Stop() => _cts.Cancel();

/// <summary>
/// Releases all resources used by the current instance of the <see cref="Server"/> class.
/// </summary>
public void Dispose()
{
if (IsDisposed)
{
return;
}

if (!_cts.IsCancellationRequested)
{
Stop();
}

_cts.Dispose();
IsDisposed = true;
}

/// <summary>
/// Runs server.
/// </summary>
public async Task RunAsync()
{
_listener.Start();

try
{
var token = _cts.Token;
using var socket = await _listener.AcceptSocketAsync(token);
await using var stream = new NetworkStream(socket);
await Processing.ProcessQuery(stream);
}
finally
{
_listener.Stop();
}
}
}
10 changes: 10 additions & 0 deletions WebChat/WebChat/WebChat.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>