ViennaNET: ืงื‘ื•ืฆื” ืฉืœ ืกืคืจื™ื•ืช ืขื‘ื•ืจ ื”ืงืฆื” ื”ืื—ื•ืจื™. ื—ืœืง 2

ืงื”ื™ืœืช ื”ืžืคืชื—ื™ื ืฉืœ Raiffeisenbank .NET ืžืžืฉื™ื›ื” ืœืกืงื•ืจ ื‘ืงืฆืจื” ืืช ื”ืชื•ื›ืŸ ืฉืœ ViennaNET. ืขืœ ืื™ืš ื•ืœืžื” ื”ื’ืขื ื• ืœื–ื”, ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืืช ื”ื—ืœืง ื”ืจืืฉื•ืŸ.

ื‘ืžืืžืจ ื–ื”, ื ืขื‘ื•ืจ ืขืœ ืกืคืจื™ื•ืช ืฉื˜ืจื ื ื—ืฉื‘ื• ืœืขื‘ื•ื“ื” ืขื ืขืกืงืื•ืช ืžื‘ื•ื–ืจื•ืช, ืชื•ืจื™ื ื•ืžืกื“ื™ ื ืชื•ื ื™ื, ืืฉืจ ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืžืื’ืจ GitHub ืฉืœื ื• (ืžืงื•ืจื•ืช ื ืžืฆืื™ื ื›ืืŸ), ื• ื—ื‘ื™ืœื•ืช ื ื•ื’ื˜ ื›ืืŸ.

ViennaNET: ืงื‘ื•ืฆื” ืฉืœ ืกืคืจื™ื•ืช ืขื‘ื•ืจ ื”ืงืฆื” ื”ืื—ื•ืจื™. ื—ืœืง 2

ViennaNET.Sagas

ื›ืืฉืจ ืคืจื•ื™ืงื˜ ืขื•ื‘ืจ ืœืืจื›ื™ื˜ืงื˜ื•ืจืช DDD ื•-microservice, ืื– ื›ืืฉืจ ื”ื”ื™ื’ื™ื•ืŸ ื”ืขืกืงื™ ืžื•ืคืฅ ืขืœ ืคื ื™ ืฉื™ืจื•ืชื™ื ืฉื•ื ื™ื, ืžืชืขื•ืจืจืช ื‘ืขื™ื” ื”ืงืฉื•ืจื” ืœืฆื•ืจืš ื‘ื™ื™ืฉื•ื ืžื ื’ื ื•ืŸ ืขืกืงื” ืžื‘ื•ื–ืจ, ืžื›ื™ื•ื•ืŸ ืฉืœืจื•ื‘ ืชืจื—ื™ืฉื™ื ืจื‘ื™ื ืžืฉืคื™ืขื™ื ืขืœ ืžืกืคืจ ืชื—ื•ืžื™ื ื‘ื•-ื–ืžื ื™ืช. ืืชื” ื™ื›ื•ืœ ืœื”ื›ื™ืจ ืžื ื’ื ื•ื ื™ื ื›ืืœื” ื‘ื™ืชืจ ืคื™ืจื•ื˜, ืœืžืฉืœ, ื‘ืกืคืจ "Microservices Patterns", ื›ืจื™ืก ืจื™ืฆ'ืจื“ืกื•ืŸ.

ื‘ืคืจื•ื™ืงื˜ื™ื ืฉืœื ื•, ื”ื˜ืžืขื ื• ืžื ื’ื ื•ืŸ ืคืฉื•ื˜ ืืš ืฉื™ืžื•ืฉื™: ืกืื’ื”, ืื• ื™ื•ืชืจ ื ื›ื•ืŸ ืกืื’ื” ืžื‘ื•ืกืกืช ืชื–ืžื•ืจ. ื”ืžื”ื•ืช ืฉืœื” ื”ื™ื ื›ื“ืœืงืžืŸ: ื™ืฉ ืชืจื—ื™ืฉ ืขืกืงื™ ืžืกื•ื™ื ืฉื‘ื• ื™ืฉ ืฆื•ืจืš ืœื‘ืฆืข ืคืขื•ืœื•ืช ื‘ืจืฆืฃ ื‘ืฉื™ืจื•ืชื™ื ืฉื•ื ื™ื, ื•ืื ืžืชืขื•ืจืจื•ืช ื‘ืขื™ื•ืช ื›ืœืฉื”ืŸ ื‘ื›ืœ ืฉืœื‘, ื™ืฉ ืฆื•ืจืš ืœืงืจื•ื ืœื”ืœื™ืš ื”ื—ื–ืจื” ืœืื—ื•ืจ ืขื‘ื•ืจ ื›ืœ ื”ืฉืœื‘ื™ื ื”ืงื•ื“ืžื™ื, ืฉื‘ื• ื”ื•ื ื ืžืฆื ืžืกื•ืคืง. ื›ืš, ื‘ืกื•ืฃ ื”ืกืื’ื”, ืœืœื ืงืฉืจ ืœื”ืฆืœื—ื”, ืื ื• ืžืงื‘ืœื™ื ื ืชื•ื ื™ื ืขืงื‘ื™ื™ื ื‘ื›ืœ ื”ืชื—ื•ืžื™ื.

ื”ื™ื™ืฉื•ื ืฉืœื ื• ืขื“ื™ื™ืŸ ื ืขืฉื” ื‘ืฆื•ืจืชื• ื”ื‘ืกื™ืกื™ืช ื•ืื™ื ื• ืงืฉื•ืจ ืœืฉื™ืžื•ืฉ ื‘ื›ืœ ืฉื™ื˜ื•ืช ืฉืœ ืื™ื ื˜ืจืืงืฆื™ื” ืขื ืฉื™ืจื•ืชื™ื ืื—ืจื™ื. ื–ื” ืœื ืงืฉื” ืœืฉื™ืžื•ืฉ: ืคืฉื•ื˜ ืฆื•ืจ ืฆืืฆื ืฉืœ ืžื—ืœืงืช ื”ืื‘ืกื˜ืจืงื˜ ื”ื‘ืกื™ืกื™ืช SagaBase<T>, ื›ืืฉืจ T ื”ื™ื ืžื—ืœืงืช ื”ื”ืงืฉืจ ืฉืœืš ืฉื‘ื” ืืชื” ื™ื›ื•ืœ ืœืื—ืกืŸ ืืช ื”ื ืชื•ื ื™ื ื”ืจืืฉื•ื ื™ื™ื ื”ื“ืจื•ืฉื™ื ื›ื“ื™ ืฉื”ืกืื’ื” ืชืขื‘ื•ื“, ื›ืžื• ื’ื ื›ืžื” ืชื•ืฆืื•ืช ื‘ื™ื ื™ื™ื. ืžื•ืคืข ื”ื”ืงืฉืจ ื™ื•ืขื‘ืจ ืœื›ืœ ื”ืฉืœื‘ื™ื ื‘ืžื”ืœืš ื”ื‘ื™ืฆื•ืข. Saga ืขืฆืžื• ื”ื•ื ืžื—ืœืงื” ื—ืกืจืช ืžื“ื™ื ื”, ื›ืš ืฉื ื™ืชืŸ ืœืžืงื ืืช ื”ืžื•ืคืข ื‘-DI ื›ืกื™ื ื’ืœื˜ื•ืŸ ื›ื“ื™ ืœืงื‘ืœ ืืช ื”ืชืœื•ืช ื”ื ื“ืจืฉืช.

ืžื•ื“ืขื” ืœื“ื•ื’ืžื”:

public class ExampleSaga : SagaBase<ExampleContext>
{
  public ExampleSaga()
  {
    Step("Step 1")
      .WithAction(c => ...)
      .WithCompensation(c => ...);
	
    AsyncStep("Step 2")
      .WithAction(async c => ...);
  }
}

ืฉื™ื—ื” ืœื“ื•ื’ืžื”:

var saga = new ExampleSaga();
var context = new ExampleContext();
await saga.Execute(context);

ื ื™ืชืŸ ืœืจืื•ืช ื“ื•ื’ืžืื•ืช ืžืœืื•ืช ืฉืœ ื™ื™ืฉื•ืžื™ื ืฉื•ื ื™ื ื›ืืŸ ื•ื‘ื”ืจื›ื‘ื” ืขื ืžื‘ื—ื ื™ื.

ViennaNET.Orm.*

ืกื˜ ืกืคืจื™ื•ืช ืœืขื‘ื•ื“ื” ืขื ืžืกื“ื™ ื ืชื•ื ื™ื ืฉื•ื ื™ื ื“ืจืš Nhibernate. ืื ื• ืžืฉืชืžืฉื™ื ื‘ื’ื™ืฉืช DB-First ื‘ืืžืฆืขื•ืช Liquibase, ื›ืš ืฉื™ืฉ ืจืง ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืœืขื‘ื•ื“ื” ืขื ื ืชื•ื ื™ื ื‘ืžืกื“ ื ืชื•ื ื™ื ืžื•ื›ืŸ.

ViennaNET.Orm.Seedwork ะธ ViennaNET.Orm โ€“ ืžื›ืœื•ืœื™ื ืขื™ืงืจื™ื™ื ื”ืžื›ื™ืœื™ื ืžืžืฉืงื™ื ื‘ืกื™ืกื™ื™ื ื•ื”ื˜ืžืขื•ืช ืฉืœื”ื, ื‘ื”ืชืืžื”. ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื”ืชื•ื›ืŸ ืฉืœื”ื ื‘ื™ืชืจ ืคื™ืจื•ื˜.

ืžืžืฉืง IEntityFactoryService ื•ื™ื™ืฉื•ืžื” EntityFactoryService ื”ื ื ืงื•ื“ืช ื”ืžื•ืฆื ื”ืขื™ืงืจื™ืช ืœืขื‘ื•ื“ื” ืขื ืžืกื“ ื”ื ืชื•ื ื™ื, ืฉื›ืŸ ื›ืืŸ ื ื•ืฆืจื™ื ื™ื—ื™ื“ืช ื”ืขื‘ื•ื“ื”, ืžืื’ืจื™ื ืœืขื‘ื•ื“ื” ืขื ื™ืฉื•ื™ื•ืช ืกืคืฆื™ืคื™ื•ืช, ื›ืžื• ื’ื ืžื‘ืฆืขื™ื ืฉืœ ืคืงื•ื“ื•ืช ื•ืฉืื™ืœืชื•ืช SQL ื™ืฉื™ืจื•ืช. ืœืคืขืžื™ื ื ื•ื— ืœื”ื’ื‘ื™ืœ ืืช ื”ื™ื›ื•ืœื•ืช ืฉืœ ืžื—ืœืงื” ืœืขื‘ื•ื“ื” ืขื ืžืกื“ ื ืชื•ื ื™ื, ืœืžืฉืœ, ืœืกืคืง ืืช ื”ื™ื›ื•ืœืช ืœืงืจื•ื ืจืง ื ืชื•ื ื™ื. ืœืžืงืจื™ื ื›ืืœื” IEntityFactoryService ื™ืฉ ืžืžืฉืง ืงื“ืžื•ืŸ IEntityRepositoryFactory, ืฉืžืฆื”ื™ืจ ืจืง ืขืœ ืฉื™ื˜ื” ืœื™ืฆื™ืจืช ืžืื’ืจื™ื.

ื›ื“ื™ ืœื’ืฉืช ื™ืฉื™ืจื•ืช ืœืžืกื“ ื”ื ืชื•ื ื™ื, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืžื ื’ื ื•ืŸ ื”ืกืคืง. ืœื›ืœ DBMS ืฉืื ื• ืžืฉืชืžืฉื™ื ื‘ืฆื•ื•ืชื™ื ืฉืœื ื• ื™ืฉ ื™ื™ืฉื•ื ืžืฉืœื•: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql.

ื‘ืžืงื‘ื™ืœ, ื ื™ืชืŸ ืœืจืฉื•ื ืžืกืคืจ ืกืคืงื™ื ื‘ืืคืœื™ืงืฆื™ื” ืื—ืช ื‘ืžืงื‘ื™ืœ, ืžื” ืฉืžืืคืฉืจ ืœืžืฉืœ ื‘ืžืกื’ืจืช ืฉื™ืจื•ืช ืื—ื“, ืœืœื ื›ืœ ืขืœื•ื™ื•ืช ืœืฉื™ื ื•ื™ ื”ืชืฉืชื™ืช, ืœื‘ืฆืข ื”ื’ื™ืจื” ืฉืœื‘ ืื—ืจ ืฉืœื‘ ืž- DBMS ืื—ื“ ืœืžืฉื ื”ื•. ื”ืžื ื’ื ื•ืŸ ืœื‘ื—ื™ืจืช ื”ื—ื™ื‘ื•ืจ ื”ื ื“ืจืฉ, ื•ืœืคื™ื›ืš, ื”ืกืคืง ืœืžื—ืœืงืช ื™ืฉื•ืช ืกืคืฆื™ืคื™ืช (ืฉืขื‘ื•ืจื” ื ื›ืชื‘ ืžื™ืคื•ื™ ืœื˜ื‘ืœืื•ืช ืžืกื“ ื ืชื•ื ื™ื) ืžื™ื•ืฉื ื‘ืืžืฆืขื•ืช ืจื™ืฉื•ื ื”ื™ืฉื•ืช ื‘ืžื—ืœืงื” BoundedContext (ืžื›ื™ืœ ืฉื™ื˜ื” ืœืจื™ืฉื•ื ื™ืฉื•ื™ื•ืช ืชื—ื•ื) ืื• ื”ื™ื•ืจืฉ ืฉืœื” ApplicationContext (ืžื›ื™ืœ ืฉื™ื˜ื•ืช ืœืจื™ืฉื•ื ื™ืฉื•ื™ื•ืช ื™ื™ืฉื•ื, ื‘ืงืฉื•ืช ื™ืฉื™ืจื•ืช ื•ืคืงื•ื“ื•ืช), ื›ืืฉืจ ืžื–ื”ื” ื”ื—ื™ื‘ื•ืจ ืžื”ืชืฆื•ืจื” ืžืชืงื‘ืœ ื›ืืจื’ื•ืžื ื˜:

"db": [
  {
    "nick": "mssql_connection",
    "dbServerType": "MSSQL",
    "ConnectionString": "...",
    "useCallContext": true
  },
  {
    "nick": "oracle_connection",
    "dbServerType": "Oracle",
    "ConnectionString": "..."
  }
],

ื“ื•ื’ืžื” ืœื”ืงืฉืจ ื™ื™ืฉื•ื:

internal sealed class DbContext : ApplicationContext
{
  public DbContext()
  {
    AddEntity<SomeEntity>("mssql_connection");
    AddEntity<MigratedSomeEntity>("oracle_connection");
    AddEntity<AnotherEntity>("oracle_connection");
  }
}

ืื ืžื–ื”ื” ื”ื—ื™ื‘ื•ืจ ืœื ืฆื•ื™ืŸ, ื™ื™ืขืฉื” ืฉื™ืžื•ืฉ ื‘ื—ื™ื‘ื•ืจ ื‘ืฉื "ื‘ืจื™ืจืช ืžื—ื“ืœ".

ืžื™ืคื•ื™ ื™ืฉื™ืจ ืฉืœ ื™ืฉื•ื™ื•ืช ืœื˜ื‘ืœืื•ืช ืžืกื“ ื ืชื•ื ื™ื ืžื™ื•ืฉื ื‘ืืžืฆืขื•ืช ื›ืœื™ื ืกื˜ื ื“ืจื˜ื™ื™ื ืฉืœ NHibernate. ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืชื™ืื•ืจ ื’ื ื“ืจืš ืงื‘ืฆื™ xml ื•ื’ื ื“ืจืš ืžื—ืœืงื•ืช. ืœื›ืชื™ื‘ื” ื ื•ื—ื” ืฉืœ ืžืื’ืจื™ ื‘ื“ืœ ื‘ื‘ื“ื™ืงื•ืช ื™ื—ื™ื“ื”, ื™ืฉ ืกืคืจื™ื” ViennaNET.TestUtils.Orm.

ื ื™ืชืŸ ืœืžืฆื•ื ื“ื•ื’ืžืื•ืช ืžืœืื•ืช ืœืฉื™ืžื•ืฉ ื‘-ViennaNET.Orm.* ื›ืืŸ.

ViennaNET.Messaging.*

ืกื˜ ืกืคืจื™ื•ืช ืœืขื‘ื•ื“ื” ืขื ืชื•ืจื™ื.

ืœืขื‘ื•ื“ื” ืขื ืชื•ืจื™ื, ื ื‘ื—ืจื” ืื•ืชื” ื’ื™ืฉื” ื›ืžื• ืขื DBMSs ืฉื•ื ื™ื, ื›ืœื•ืžืจ ื”ื’ื™ืฉื” ื”ืžืื•ื—ื“ืช ื”ืžืงืกื™ืžืœื™ืช ื”ืืคืฉืจื™ืช ืžื‘ื—ื™ื ืช ืขื‘ื•ื“ื” ืขื ื”ืกืคืจื™ื™ื”, ืœืœื ืงืฉืจ ืœืžื ื”ืœ ื”ืชื•ืจื™ื ื‘ื• ื ืขืฉื” ืฉื™ืžื•ืฉ. ืกึดืคึฐืจึดื™ึธื” ViennaNET.Messaging ืื—ืจืื™ ื‘ื“ื™ื•ืง ืœืื™ื—ื•ื“ ื”ื–ื”, ื• ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue ะธ ViennaNET.Messaging.KafkaQueue ืžื›ื™ืœื™ื ื™ื™ืฉื•ืžื™ ืžืชืื ืขื‘ื•ืจ IBM MQ, RabbitMQ ื•ืงืคืงื, ื‘ื”ืชืืžื”.

ื‘ืขื‘ื•ื“ื” ืขื ืชื•ืจื™ื ื™ืฉ ืฉื ื™ ืชื”ืœื™ื›ื™ื: ืงื‘ืœืช ื”ื•ื“ืขื” ื•ืฉืœื™ื—ื”.

ืฉืงื•ืœ ืœืงื‘ืœ. ื™ืฉ ื›ืืŸ 2 ืืคืฉืจื•ื™ื•ืช: ืœื”ืื–ื ื” ืจืฆื™ืคื” ื•ืงื‘ืœืช ื”ื•ื“ืขื” ื‘ื•ื“ื“ืช. ื›ื“ื™ ืœื”ืื–ื™ืŸ ื›ืœ ื”ื–ืžืŸ ืœืชื•ืจ, ืชื—ื™ืœื” ืขืœื™ืš ืœืชืืจ ืืช ืžื—ืœืงืช ื”ืžืขื‘ื“ื™ื ืฉืงื™ื‘ืœื” ื‘ื™ืจื•ืฉื” IMessageProcessor, ืฉืชื”ื™ื” ืื—ืจืื™ืช ืขืœ ืขื™ื‘ื•ื“ ื”ื”ื•ื“ืขื” ื”ื ื›ื ืกืช. ืœืื—ืจ ืžื›ืŸ, ื™ืฉ "ืœืงืฉืจ" ืื•ืชื• ืœืชื•ืจ ืกืคืฆื™ืคื™; ื–ื” ื ืขืฉื” ื‘ืืžืฆืขื•ืช ืจื™ืฉื•ื ื‘ IQueueReactorFactory ืžืฆื™ื™ืŸ ืืช ืžื–ื”ื” ื”ืชื•ืจ ืžื”ืชืฆื•ืจื”:

"messaging": {
    "ApplicationName": "MyApplication"
},
"rabbitmq": {
    "queues": [
      {
        "id": "myQueue",
        "queuename": "lalala",
        ...
      }
    ]
},

ื“ื•ื’ืžื” ืœื”ืชื—ืœืช ื”ืื–ื ื”:

_queueReactorFactory.Register<MyMessageProcessor>("myQueue");
var queueReactor = queueReactorFactory.CreateQueueReactor("myQueue");
queueReactor.StartProcessing();

ืœืื—ืจ ืžื›ืŸ, ื›ืืฉืจ ื”ืฉื™ืจื•ืช ืžืชื—ื™ืœ ื•ื”ืฉื™ื˜ื” ื ืงืจืืช ืœื”ืชื—ื™ืœ ืœื”ืื–ื™ืŸ, ื›ืœ ื”ื”ื•ื“ืขื•ืช ืžื”ืชื•ืจ ืฉืฆื•ื™ืŸ ื™ืขื‘ืจื• ืœืžืขื‘ื“ ื”ืžืชืื™ื.

ืœืงื‘ืœืช ื”ื•ื“ืขื” ื‘ื•ื“ื“ืช ื‘ืžืžืฉืง ืžืคืขืœ IMessagingComponentFactory ื™ืฉ ืฉื™ื˜ื” CreateMessageReceiverืžื” ืฉื™ื™ืฆื•ืจ ื ืžืขืŸ ื”ืžืžืชื™ืŸ ืœื”ื•ื“ืขื” ืžื”ืชื•ืจ ืฉืฆื•ื™ืŸ ืœื•:

using (var receiver = _messagingComponentFactory.CreateMessageReceiver<TestMessage>("myQueue"))
{
    var message = receiver.Receive();
}

ื›ื“ื™ ืœืฉืœื•ื— ื”ื•ื“ืขื” ืืชื” ืฆืจื™ืš ืœื”ืฉืชืžืฉ ื‘ืื•ืชื• IMessagingComponentFactory ื•ืฆื•ืจ ืฉื•ืœื— ื”ื•ื“ืขื”:

using (var sender = _messagingComponentFactory.CreateMessageSender<MyMessage>("myQueue"))
{
    sender.SendMessage(new MyMessage { Value = ...});
}

ื™ืฉื ืŸ ืฉืœื•ืฉ ืืคืฉืจื•ื™ื•ืช ืžื•ื›ื ื•ืช ืœื”ืฆื’ื” ื‘ืกื™ื“ืจื” ื•ื‘ื™ื˜ื•ืœ ื‘ื”ืžืฉื›ื” ืฉืœ ื”ื•ื“ืขื”: ืจืง ื˜ืงืกื˜, XML ื•-JSON, ืืš ื‘ืžื™ื“ืช ื”ืฆื•ืจืš, ืชื•ื›ืœ ื‘ืงืœื•ืช ืœื™ืฆื•ืจ ืžื™ืžื•ืฉื™ ืžืžืฉืง ืžืฉืœืš. IMessageSerializer ะธ IMessageDeserializer.

ื ื™ืกื™ื ื• ืœืฉืžืจ ืืช ื”ื™ื›ื•ืœื•ืช ื”ื™ื™ื—ื•ื“ื™ื•ืช ืฉืœ ื›ืœ ืžื ื”ืœ ืชื•ืจ, ืœืžืฉืœ. ViennaNET.Messaging.MQSeriesQueue ืžืืคืฉืจ ืœืš ืœืฉืœื•ื— ืœื ืจืง ื˜ืงืกื˜, ืืœื ื’ื ื”ื•ื“ืขื•ืช ื‘ืชื™ื, ื• ViennaNET.Messaging.RabbitMQQueue ืชื•ืžืš ื‘ื ื™ืชื•ื‘ ื•ืชื•ืจื™ื ืชื•ืš ื›ื“ื™ ื˜ื™ืกื”. ืžืขื˜ืคืช ื”ืžืชืื ืฉืœื ื• ืขื‘ื•ืจ RabbitMQ ืžื™ื™ืฉืžืช ื’ื ืžืจืื™ืช ืขื™ืŸ ืฉืœ RPC: ืื ื• ืฉื•ืœื—ื™ื ื”ื•ื“ืขื” ื•ืžื—ื›ื™ื ืœืชื’ื•ื‘ื” ืžืชื•ืจ ื–ืžื ื™ ืžื™ื•ื—ื“, ืฉื ื•ืฆืจ ืจืง ืขื‘ื•ืจ ื”ื•ื“ืขืช ืชื’ื•ื‘ื” ืื—ืช.

ื›ืืŸ ื“ื•ื’ืžื” ืœืฉื™ืžื•ืฉ ื‘ืชื•ืจื™ื ืขื ื ื™ื•ืื ืกื™ื ื‘ืกื™ืกื™ื™ื ืฉืœ ื—ื™ื‘ื•ืจ.

ViennaNET.CallContext

ืื ื• ืžืฉืชืžืฉื™ื ื‘ืชื•ืจื™ื ืœื ืจืง ืœืื™ื ื˜ื’ืจืฆื™ื” ื‘ื™ืŸ ืžืขืจื›ื•ืช ืฉื•ื ื•ืช, ืืœื ื’ื ืœืชืงืฉื•ืจืช ื‘ื™ืŸ ืžื™ืงืจื•-ืฉื™ืจื•ืชื™ื ืฉืœ ืื•ืชื” ืืคืœื™ืงืฆื™ื”, ืœืžืฉืœ, ื‘ืชื•ืš ืกืื’ื”. ื–ื” ื”ื•ื‘ื™ืœ ืœืฆื•ืจืš ืœื”ืขื‘ื™ืจ ื™ื—ื“ ืขื ื”ื”ื•ื“ืขื” ื ืชื•ื ื™ื ื ืœื•ื•ื™ื ื›ื’ื•ืŸ ื”ืชื—ื‘ืจื•ืช ืžืฉืชืžืฉ, ืžื–ื”ื” ื‘ืงืฉื” ืœืจื™ืฉื•ื ืžืงืฆื” ืœืงืฆื”, ื›ืชื•ื‘ืช IP ืžืงื•ืจ ื•ื ืชื•ื ื™ ื”ืจืฉืื”. ื›ื“ื™ ืœื™ื™ืฉื ืืช ื”ืขื‘ืจืช ื”ื ืชื•ื ื™ื ื”ืœืœื•, ืคื™ืชื—ื ื• ืกืคืจื™ื” ViennaNET.CallContext, ื”ืžืืคืฉืจ ืœืื—ืกืŸ ื ืชื•ื ื™ื ืžื‘ืงืฉื” ืฉื ื›ื ืกืช ืœืฉื™ืจื•ืช. ื‘ืžืงืจื” ื–ื”, ืื™ืŸ ื—ืฉื™ื‘ื•ืช ืœืื•ืคืŸ ืฉื‘ื• ื‘ื•ืฆืขื” ื”ื‘ืงืฉื”, ื“ืจืš ืชื•ืจ ืื• ื‘ืืžืฆืขื•ืช Http. ืœืื—ืจ ืžื›ืŸ, ืœืคื ื™ ืฉืœื™ื—ืช ื”ื‘ืงืฉื” ืื• ื”ื”ื•ื“ืขื” ื”ื™ื•ืฆืืช, ื”ื ืชื•ื ื™ื ื ืœืงื—ื™ื ืžื”ื”ืงืฉืจ ื•ืžืžื•ืงืžื™ื ื‘ื›ื•ืชืจื•ืช. ื›ืš, ื”ืฉื™ืจื•ืช ื”ื‘ื ืžืงื‘ืœ ืืช ื ืชื•ื ื™ ื”ืขื–ืจ ื•ืžื ื”ืœ ืื•ืชื ื‘ืื•ืชื• ืื•ืคืŸ.

ืชื•ื“ื” ืขืœ ืชืฉื•ืžืช ื”ืœื‘ ืฉืœืš, ืื ื• ืžืฆืคื™ื ืœื”ืขืจื•ืชื™ืš ื•ืœื‘ืงืฉื•ืช ืฉืœืš!

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”