1 Commits

Author SHA1 Message Date
Khalitova Angelina
7481362080 Пересоздала ветку от main 2023-12-18 09:52:45 +04:00
62 changed files with 569 additions and 517 deletions

View File

@@ -1,139 +0,0 @@
# Отчёт по лабораторной работе №3
## REST API, Gateway и синхронный обмен между микросервисами
Выполнила: студентка гр. ИСЭбд-41 Халитова А.М.
## Создание микросервисов
В терминале помощью команд `dotnet new web -n worker-1` и `dotnet new web -n worker-2`создано два микросервиса:
[Код программы worker-1](worker-1/Program.cs)
[Код программы worker-2](worker-2/Program.cs)
Далее были добавлены Swagger и OpenAi в проекты. Затем запустили приложения с помощью команды `dotnet run`.
Интерфейс микросервисов c CRUD-операциями - список записей, подробности конкретной записи, создание, удаление и изменение записи:
worker-1:
![](shots/shot1.PNG)
worker-2:
![](shots/shot2.PNG)
## Реализация синхронного обмена
Синхронный вызов данных с соседнего микросервиса для worker-2 при реализации получения, создания и обновления работ:
```
app.MapGet("/getJobs/{clientId}", (string clientId) =>
{
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + clientId).Result;
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
if (secondWorkerResponse == null)
return Results.NotFound(new { message = "Клиент не найден" });
List<Job> clientJobs = jobs.Where(x => x.ClientId == clientId).ToList();
return Results.Json(clientJobs);
})
.WithName("GetJobs");
app.MapGet("getJob/{id}", (string id) =>
{
Job? job = jobs.FirstOrDefault(x => x.Id == id);
if (job == null)
return Results.NotFound(new { message = "Задача не найдена" });
return Results.Json(job);
})
.WithName("GetJob");
app.MapPost("createJob", (JobViewModel jobVM) =>
{
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + jobVM.ClientId).Result;
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
if (secondWorkerResponse == null)
return Results.NotFound(new { message = "Клиент не найден" });
Job job = new Job
{
Id = Guid.NewGuid().ToString(),
DeadLine = jobVM.DeadLine,
Description = jobVM.Description,
Client = client,
ClientId = jobVM.ClientId,
Title = jobVM.Title,
};
jobs.Add(job);
return Results.Json(job);
})
.WithName("CreateJob");
app.MapPut("updateJob/{id}", (string id, JobViewModel data) =>
{
Job? job = jobs.FirstOrDefault(x => x.Id == id);
if (job == null)
return Results.NotFound(new { message = "Задача не найдена" });
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + data.ClientId).Result;
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
if (secondWorkerResponse == null)
return Results.NotFound(new { message = "Клиент не найден" });
job.Title = data.Title;
job.DeadLine = data.DeadLine;
job.ClientId = data.ClientId;
job.Client = client;
job.Description = data.Description;
return Results.Json(job);
})
.WithName("UpdateJob");
```
## Реализация gateway при помощи nginx
Файл с настройкой nginx:
```
server {
listen 8080;
listen [::]:8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /worker-1/ {
proxy_pass http://worker-1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-1;
}
location /worker-2/ {
proxy_pass http://worker-2:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-2;
}
}
```
Далее запустили команду `docker compose up --build`.
В Docker Desktop проверили, что приложение успешно запущено:
![](shots/shot3.PNG)
Страница `index.html` на шлюзе geteway-1:
![](shots/shot4.PNG)
worker-1:
![](shots/shot5.PNG)
worker-2:
![](shots/shot6.PNG)

View File

@@ -1,15 +0,0 @@
version: "3.1"
services:
worker-1:
build: ./worker-1
worker-2:
build: ./worker-2
depends_on:
- worker-1
gateway:
image: nginx:latest
ports:
- 8080:8080
volumes:
- ./static:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

View File

@@ -1,26 +0,0 @@
server {
listen 8080;
listen [::]:8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /worker-1/ {
proxy_pass http://worker-1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-1;
}
location /worker-2/ {
proxy_pass http://worker-2:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /worker-2;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Приложение для л/р 3</title>
</head>
<body>
<p>Выполнила: студентка гр.ИСЭбд-41 Халитова Ангелина</p>
<p><a href="/worker-1/">Отправить запрос к worker-1</a></p>
<p><a href="/worker-2/">Отправить запрос к worker-2</a></p>
</body>
</html>

View File

@@ -1,11 +0,0 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "worker-1.dll"]

View File

@@ -1,71 +0,0 @@
var clients = new List<Client>() {
new Client { Id = "638f2a30-ca73-4772-b827-f9e6d0e81a86", Address = "ул. Улица", Name = "Иван" },
new Client { Id = "638f2a30-ca73-4772-b827-f9e6d0e81a89", Address = "ул. Бульвар", Name = "Петр" }
};
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/getClients", () =>
{
return clients;
})
.WithName("GetClients");
app.MapGet("getClient/{id}", (string id) =>
{
Client? client = clients.FirstOrDefault(x => x.Id == id);
if (client == null)
return Results.NotFound(new { message = "Клиент не найден" });
return Results.Json(client);
})
.WithName("GetClient");
app.MapPost("createClient", (Client client) =>
{
client.Id = Guid.NewGuid().ToString();
clients.Add(client);
return client;
})
.WithName("CreateClient");
app.MapPut("updateClient/{id}", (Client data) =>
{
Client? client = clients.FirstOrDefault(x => x.Id == data.Id);
if (client == null)
return Results.NotFound(new { message = "Клиент не найден" });
client.Address = data.Address;
client.Name = data.Name;
return Results.Json(client);
})
.WithName("UpdateClient");
app.MapDelete("deleteClient/{id}", (string id) =>
{
Client? client = clients.FirstOrDefault(x => x.Id == id);
if (client == null)
return Results.NotFound(new { message = "Клиент не найден" });
clients.Remove(client);
return Results.Ok();
})
.WithName("DeleteClient");
app.Run();
public class Client
{
public string Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}

View File

@@ -1,28 +0,0 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:64210",
"sslPort": 44366
}
},
"profiles": {
"worker_1": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7139;http://localhost:5051",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>worker_1</RootNamespace>
<ItemGroup>
<PackageReference Include="openapi" Version="1.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>

View File

@@ -1,11 +0,0 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "worker-2.dll"]

View File

@@ -1,111 +0,0 @@
using Newtonsoft.Json;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
var jobs = new List<Job>();
var httpClient = new HttpClient();
app.MapGet("/getJobs/{clientId}", (string clientId) =>
{
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + clientId).Result;
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
if (secondWorkerResponse == null)
return Results.NotFound(new { message = "Клиент не найден" });
List<Job> clientJobs = jobs.Where(x => x.ClientId == clientId).ToList();
return Results.Json(clientJobs);
})
.WithName("GetJobs");
app.MapGet("getJob/{id}", (string id) =>
{
Job? job = jobs.FirstOrDefault(x => x.Id == id);
if (job == null)
return Results.NotFound(new { message = "Задача не найдена" });
return Results.Json(job);
})
.WithName("GetJob");
app.MapPost("createJob", (JobViewModel jobVM) =>
{
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + jobVM.ClientId).Result;
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
if (secondWorkerResponse == null)
return Results.NotFound(new { message = "Клиент не найден" });
Job job = new Job
{
Id = Guid.NewGuid().ToString(),
DeadLine = jobVM.DeadLine,
Description = jobVM.Description,
Client = client,
ClientId = jobVM.ClientId,
Title = jobVM.Title,
};
jobs.Add(job);
return Results.Json(job);
})
.WithName("CreateJob");
app.MapPut("updateJob/{id}", (string id, JobViewModel data) =>
{
Job? job = jobs.FirstOrDefault(x => x.Id == id);
if (job == null)
return Results.NotFound(new { message = "Задача не найдена" });
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + data.ClientId).Result;
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
if (secondWorkerResponse == null)
return Results.NotFound(new { message = "Клиент не найден" });
job.Title = data.Title;
job.DeadLine = data.DeadLine;
job.ClientId = data.ClientId;
job.Client = client;
job.Description = data.Description;
return Results.Json(job);
})
.WithName("UpdateJob");
app.MapDelete("deleteJob/{id}", (string id) =>
{
Job? job = jobs.FirstOrDefault(x => x.Id == id);
if (job == null)
return Results.NotFound(new { message = "Задача не найдена" });
jobs.Remove(job);
return Results.Ok();
})
.WithName("DeleteJob");
app.Run();
public class Client
{
public string Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
public class Job
{
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime DeadLine { get; set; }
public string ClientId { get; set; }
public Client Client { get; set; }
}
public class JobViewModel
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime DeadLine { get; set; }
public string ClientId { get; set; }
}

View File

@@ -1,28 +0,0 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:21583",
"sslPort": 44340
}
},
"profiles": {
"worker_2": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7037;http://localhost:5066",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>worker_2</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="newtonsoft.json" Version="13.0.3" />
<PackageReference Include="openapi" Version="1.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>

View File

@@ -1,3 +1,5 @@
var/result/
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
## ##

View File

@@ -0,0 +1,162 @@
# Отчёт по лабораторной работе №4
## Работа с брокером сообщений
Выполнила: студентка гр. ИСЭбд-41 Халитова А.М.
## Установка брокера сообщений RabbitMQ
Была выполнена установка RabbitMQ и Erlang:
![](shots/shot1.PNG)
![](shots/shot2.PNG)
И выполнен вход на http://localhost:15672/ в качестве гостя:
![](shots/shot3.PNG)
## Прохождение tutorial
tutorial1:
![](shots/shot4.PNG)
![](shots/shot5.PNG)
![](shots/shot6.PNG)
tutorial2:
![](shots/shot7.PNG)
![](shots/shot8.PNG)
![](shots/shot9.PNG)
![](shots/shot10.PNG)
tutorial3:
![](shots/shot11.PNG)
![](shots/shot12.PNG)
![](shots/shot13.PNG)
## Разработка демонстрационных приложений
Предметная область - заказ работ на исполнение. Производитель - заказчик работ. Потребитель 1 - исполнитель принимает заказ и выполняет работу. Потребитель 2 - исполнитель откладывает выполнение задачи.
1. Publisher:
```
using System.Text;
using RabbitMQ.Client;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "job", type: ExchangeType.Fanout);
Random rand = new Random();
foreach (var item in Enumerable.Range(0, 1000))
{
var message = rand.Next().ToString();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "job",
routingKey: string.Empty,
basicProperties: null,
body: body);
Console.WriteLine($" [x] Поступила работа {message}");
await Task.Delay(500);
}
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
static string GetMessage(string[] args)
{
return ((args.Length > 0) ? string.Join(" ", args) : "info: Принято!");
}
```
2. Consumer 1:
```
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "accepted");
channel.QueueBind(queue: "accepted",
exchange: "job",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
string outputText = $"Работа принята к исполнению {message}";
Console.WriteLine($" [x] Done. {outputText}");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: "accepted",
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
```
3. Consumer 3:
```
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
Random rand = new Random();
string queueName = $"denied{rand.Next()}";
channel.QueueDeclare(queue: queueName);
channel.QueueBind(queue: queueName,
exchange: "job",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
int waitTime = rand.Next(20, 90);
Thread.Sleep(waitTime * 100);
string outputText = $"Работа отложена {message} на {waitTime} минут";
Console.WriteLine($" [x] Done. {outputText}");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: queueName,
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
```
## Результаты выполнения работ
Запуск каждой программы по одному экземпляру:
![](shots/shot14.PNG)
![](shots/shot15.PNG)
![](shots/shot16.PNG)
Результаты обработки:
![](shots/shot17.PNG)
![](shots/shot18.PNG)
Потребителю один соответствует очередь accepted, а потребителю два - очередь denied. Как видно, первый потребитель работает без задержки, а очередь второго потребителя переполенена. Из этого следует, что скорость первого в разы выше, и он потребляет намного меньше памяти за счет постоянно пустой очереди.
Запуск двух экземпляров потребителя два и по одному экземпляру потребителя один и заказчика:
![](shots/shot19.PNG)
![](shots/shot20.PNG)
Ситуация в очередью потребителя один не изменилась, а экземпляры потребителя два теперь затрачивают в 2 раза больше времени и памяти, их очереди так же переполнены, как и в ситуации выше.

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ" Version="3.6.2" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,31 @@
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "accepted");
channel.QueueBind(queue: "accepted",
exchange: "job",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
string outputText = $"Работа принята к исполнению {message}";
Console.WriteLine($" [x] Done. {outputText}");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: "accepted",
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ" Version="3.6.2" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,37 @@
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
Random rand = new Random();
string queueName = $"denied{rand.Next()}";
channel.QueueDeclare(queue: queueName);
channel.QueueBind(queue: queueName,
exchange: "job",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
int waitTime = rand.Next(20, 90);
Thread.Sleep(waitTime * 100);
string outputText = $"Работа отложена {message} на {waitTime} минут";
Console.WriteLine($" [x] Done. {outputText}");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: queueName,
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

View File

@@ -0,0 +1,30 @@
using System.Text;
using RabbitMQ.Client;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "job", type: ExchangeType.Fanout);
Random rand = new Random();
foreach (var item in Enumerable.Range(0, 1000))
{
var message = rand.Next().ToString();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "job",
routingKey: string.Empty,
basicProperties: null,
body: body);
Console.WriteLine($" [x] Поступила работа {message}");
await Task.Delay(500);
}
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
static string GetMessage(string[] args)
{
return ((args.Length > 0) ? string.Join(" ", args) : "info: Принято!");
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ" Version="3.6.2" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,29 @@
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($" [x] Received {message}");
};
channel.BasicConsume(queue: "hello",
autoAck: true,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using System.Text;
using RabbitMQ.Client;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
const string message = "Hello World! This is the first tutorial!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: string.Empty,
routingKey: "hello",
basicProperties: null,
body: body);
Console.WriteLine($" [x] Sent {message}");
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,32 @@
using System.Text;
using RabbitMQ.Client;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "task_queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
var message = GetMessage(args);
var body = Encoding.UTF8.GetBytes(message);
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
channel.BasicPublish(exchange: string.Empty,
routingKey: "task_queue",
basicProperties: properties,
body: body);
Console.WriteLine($" [x] Sent {message}");
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
static string GetMessage(string[] args)
{
return ((args.Length > 0) ? string.Join(" ", args) : "Это туториал номер два");
}

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,38 @@
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "task_queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($" [x] Received {message}");
int dots = message.Split('.').Length - 1;
Thread.Sleep(dots * 1000);
Console.WriteLine(" [x] Done");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: "task_queue",
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using System.Text;
using RabbitMQ.Client;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
var message = GetMessage(args);
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "logs",
routingKey: string.Empty,
basicProperties: null,
body: body);
Console.WriteLine($" [x] Sent {message}");
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
static string GetMessage(string[] args)
{
return ((args.Length > 0) ? string.Join(" ", args) : "info: Это третий туториал");
}

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.4.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,31 @@
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
// declare a server-named queue
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
exchange: "logs",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for logs.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($" [x] {message}");
};
channel.BasicConsume(queue: queueName,
autoAck: true,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="6.4.0" />
</ItemGroup>
</Project>