Советы по программированию web-сервисов: изучение шаблонов проектирования web-сервисов, часть 1

Алан-э-Дейл       01.03.2024 г.

How To Do It

Here is the code to add the Web Service to a web page:

<form
action=’tempconvert.asmx/FahrenheitToCelsius’
method=»post» target=»_blank»>
<table>
 
<tr>
   
<td>Fahrenheit to Celsius:</td>
   
<td>
    <input class=»frmInput» type=»text»
size=»30″ name=»Fahrenheit»>
    </td>
 
</tr>
 
<tr>
   
<td></td>
   
<td align=»right»>
     <input type=»submit»
value=»Submit» class=»button»>
     </td>
 
</tr>
</table>
</form>
<form
action=’tempconvert.asmx/CelsiusToFahrenheit’
method=»post» target=»_blank»>
<table>
 
<tr>
   
<td>Celsius to Fahrenheit:</td>
   
<td>
    <input class=»frmInput» type=»text»
size=»30″ name=»Celsius»>
    </td>
 
</tr>
 
<tr>
   
<td></td>
   
<td align=»right»>
    <input type=»submit»
value=»Submit» class=»button»>
    </td>
 
</tr>
</table>
</form>

Substitute the «tempconvert.asmx» with the address
of your web service like:

http://www.example.com/xml/tempconvert.asmx

❮ Previous
Next ❯

Про документацию

Если первый по важности пункт — это проектирование, второй — обязательно документация. HTTP протокол, HTTP сервисы не имеют описания, как это сделано в WEB сервисах

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

В самом начале мы «забивали» на документацию, а когда  партнеры спрашивали, каково предназначение того или иного метода, и что он в итоге принимает и возвращает — приходилось лезть в код. Теперь же мы просто говорим: посмотрите документацию, там все есть.

Документацию мы рекомендуем вести в таком виде:

  1. Адрес метода, предназначение, описание
  2. Входные и выходные параметры
  3. Описание структур данных в виде таблиц
  4. Описание обработки ошибок
  5. Примеры

Вот пример документации. Заголовок, ответ, пример, описание полей данных:

Пример создания веб сервиса в 1С

В качестве примера веб-сервиса создадим функционал, позволяющий определять длину введенной строчки. ПО отправит в роли параметра запроса – строчку, а опция, предусмотренная «1С» — возвратит количество символов. К данному механизму сможет обращаться стороннее программное обеспечение (не весь софт может работать с кириллицей, поэтому в примере наименования предметов конфигурации станем прописывать на латинице).  

Инструкция:

  • Открываем конфигуратор. Ищем ветку дерева «веб-сервисы»;
  • Называем и добавляем веб-сервис, например, «wa_LengthSring»;
  • В разделе «Операции» добавляем новую функцию, предположим, «CalcLengthSring»;
  • В свойства вносим вида обратного значения integer и int;
  • Внутри операции формируем параметр InputSring с видом значения string.

После этого прописываем в модуле веб-сервиса действие «CalcLengthSring». С этой целью переходим в свойства сформированного функционала, кликаем на лупу (расположена у строки ввода «Имени процедуры» в правой части). Программа сама сформирует функционал в модуле нашего веб-сервиса и активируем для описания работы функции «CalcLengthSring». Как действие функции указываем – определение длинны введенной строчки.

Самый простой веб-сервис успешно создан. Сейчас нужно опубликовать его в общем доступе – чтобы другие информационные системы «1С» или стороннее программное обеспечение могло использовать его функцию.   

Для публикации нового веб-сервиса и его функции у нас должен быть доступ к сайту. Прежде всего, проверяем название файла в свойствах сформированного модуля – «wa_LengthSring». Не забываем, что у него должно быть расширение «1cws».

Переходим к непосредственной публикации веб-сервиса на сервере (доступно в программах «1С» с версии 8.3):

  • Открываем форму «Публикация на веб-сервере», расположенную в разделе «Администрирование» в конфигураторе;
  • Ищем настройку веб-сервисов в открывшемся окошке.

Нам нужны следующие подразделы:

Каталог. Выбирайте путь к парке с хранящимися сведениями ВЕБ-сервиса по настройке подключения. Работаем только с латиницей.
ВЕБ-сервер. Здесь из установленных на компьютере выбираем сервер.
Имя. Указываем папку на WEB-сервере, в которой станет находиться описание нового веб-сервиса

Обратите внимание: иногда серверы различают реестры (большие и маленькие символы).
Признаки типа «Булево». Первый признак нужен, если требуется выполнить настройку доступа к конфигурации через веб-клиент

Для публикации WEB-сервиса «1С» нам нужна вторая отметка.

Теперь нужно проконтролировать, что у нашего веб-сервиса в первом столбике есть галочка, после – кликнуть на строку «Опубликовать».

В связи с относительной новизной инструмента, в программе может возникнуть ошибка типа «Сбой при проведении файловой операции». В такой ситуации следует повторно кликнуть на кнопку «Опубликовать». Ошибка будет устранена – система выдаст информацию об опубликовании нового ВЕБ-сервиса.

Если вы хотите убедиться, что ваш веб-сервис появился на сервере, нужно, воспользовавшись любым браузером, внести в адресную строку команду вида:

<НаименованиеСервера>.ru/<НаименованиеУказанногоНаСервереКаталога>/ws/<НазваниеФайла>.1cws?wsdl

В результате адресного запроса браузер должен показать структуру XML-файла. Если вместо нее появились непонятные символы (проблемы кодировки), ошибка или пустая страница, повторно перепроверьте каждое действие. Кроме того, убедитесь в наличии доступа и правильной настройке веб-сервера.

Остались вопросы? Закажите консультацию наших специалистов!

Как выбрать программу для взыскания дебиторской задолженности
С 1 января 2021 года будут действовать новые правила заполнения путевых листов

Что нужно для работы

На стороне конфигурации

На стороне конфигурации должны быть развернуты веб-сервисы EnterpriseDataUpload и EnterpriseDataExchange соответствующих версий (в данном случае была использована версия 1.0.1.1). При открытии этих двух URL-адресов в браузере (нужно подставить правильное для вашей инсталляции «1С:Предприятия» имя веб-сервера и публикации):

должны выводиться WSDL-описания сервисов:

В примерах использовалась Visual Studio 2012. В ней было создано консольное приложение на C#, в него импортированы веб-сервисы:

  • В Solution Explorer в контекстном меню узла References выбрать команду Add Service Reference.
  • В нижнем левом углу появившегося диалога нажать кнопку Advanced.
  • В нижнем левом углу появившегося диалога нажать кнопку Add Web Reference.

Использовалась среда разработки Eclipse 4.4.2. Для генерации кода по WSDL файлов веб-сервисов применялась утилита wsdl2java из фреймворка Apache CXF 2.7.16.

How to consume a web service

Let’s add another project to our solution. You can also create a new project. I am adding to the same solution, so that it will not need me to open several instances of Visual Studio. When developing and testing a web service in Visual Studio, it’s often preferred to add both the web service and the client application to the same solution. This allows you to test and change both pieces at the same time. You can even use the integrated debugger to set breakpoints and step through the code in both the client and the server.

Right-click on solution, select Add → New project then seelct ASP.NET Empty Application then name your application, I am naming it “ServiceConsumer”.

Add a Web Form, I name it “Home.aspx”.

On the click of a button in this page, we will call our service.

For calling a Web Service you need a proxy object that will handle the complexities of sending a SOAP request and response messages.

To create this proxy class, you need a reference to the service class. Right-click on this project then select Add service reference, a window will open, type the URL of your service, click on discover, you will see all the webmethods exposed by your service listed. At the bottom of the window, there’ll be a field for Namespace. Provide a name for the namespace in which the proxy class of the referenced service will be generated, I am giving it “MyServiceReference”. Now, click on “Go”.

By adding a service reference, we created a proxy class of the referenced service to the current project (client app).

The proxy class wraps the calls to the web service’s methods. It takes care of generating the correct SOAP message format and managing the transmission of the messages over the network using HTTP and converting the results received back to the corresponding .NET data types.

Now, add mark up in Home.aspx to receive inputs. Here’s my mark up.

Home.aspx.cs

What are Web Services?

There is more than one way to answer, “What is a web service?” But, essentially, web services include any software, application, or cloud technology that provides standardized web protocols (HTTP or HTTPS) to interoperate, communicate, and exchange data messaging – usually XML (Extensible Markup Language) – throughout the internet.

In other words, web services are XML-centered data exchange systems that use the internet for A2A (application-to-application) communication and interfacing. These processes involve programs, messages, documents, and/or objects.

A key feature of web services is that applications can be written in various languages and are still able to communicate by exchanging data with one another via a web service between clients and servers. A client summons a web service by sending a request via XML, and the service then responses with an XML response. Web services are also often associated with SOA (Service-Oriented Architecture).

To break that down, a web service comprises these essential functions:

  • Available over the internet or intranet networks
  • Standardized XML messaging system
  • Independent of a single operating system or programming language
  • Self-describing via standard XML language
  • Discoverable through a simple location method

A web service supports communication among numerous apps with HTML, XML, WSDL, SOAP, and other open standards. XML tags the data, SOAP transfers the message, and WSDL describes the service’s accessibility.

Here’s an instance of how it works: A web service sits between two sets of java, .net, or PHP apps providing a way for these applications to communicate over a network. On one side, for example, a java app interacts with the java, .net, and PHP apps on the other end by way of the web service communicating an independent language.

Web services offer different benefits across business operations. The technology helps IT pros and web architects streamline connectivity by minimizing development time. And with this simplified infrastructure, company executives begin to see higher ROI (return on investment). In a B2B operation where both parties understand how the process works, web services provide efficient technology distribution throughout an entire network.

What are the Different Types of Web Services?

There are a few central types of web services: XML-RPC, UDDI, SOAP, and REST:

XML-RPC (Remote Procedure Call) is the most basic XML protocol to exchange data between a wide variety of devices on a network. It uses HTTP to quickly and easily transfer data and communication other information from client to server.

UDDI (Universal Description, Discovery, and Integration) is an XML-based standard for detailing, publishing, and discovering web services. It’s basically an internet registry for businesses around the world. The goal is to streamline digital transactions and e-commerce among company systems.

REST, which will also be described in great detail later in the blog, provides communication and connectivity between devices and the internet for API-based tasks. Most RESTful services use HTTP as the supporting protocol.

Here are some well-known web services that use markup languages:

  • Web template
  • JSON-RPC
  • JSON-WSP
  • Web Services Description Language (WSDL)
  • Web Services Conversation Language (WSCL)
  • Web Services Flow Language (WSFL)
  • Web Services Metadata Exchange (WS-MetadataExchange)
  • XML Interface for Network Services (XINS)

Веб-сервисы (общие) [ править ]

Асинхронный JavaScript и XML

Асинхронный JavaScript и XML (AJAX) — доминирующая технология для веб-сервисов. Разработанный на основе комбинации HTTP-серверов, клиентов JavaScript и Plain Old XML (в отличие от SOAP и W3C Web Services), теперь он часто используется с JSON, а также или вместо XML.

ОТДЫХ

Передача репрезентативного состояния (REST) ​​- это архитектура для хорошо функционирующих веб-служб, которые могут функционировать в масштабе Интернета.

В документе 2004 года W3C устанавливает следующий REST в качестве ключевой отличительной черты веб-сервисов:

Веб-сервисы, использующие языки разметки

Существует ряд веб-сервисов, использующих языки разметки:

  • JSON-RPC .
  • JSON-WSP
  • Передача репрезентативного состояния (REST) ​​по сравнению с удаленным вызовом процедуры (RPC)
  • Язык разговора веб-служб (WSCL)
  • Язык описания веб-сервисов (WSDL), разработанный W3C
  • Язык потока веб-служб (WSFL), замененный BPEL
  • Веб-шаблон
  • WS-MetadataExchange
  • XML — интерфейс для сетевых служб (XINS), обеспечивает POX -стиль веб — службы формат спецификации

Веб-API править

Web API является развитие веб — сервисов , где акцент был сделан переход к более простым репрезентативной состояние передачи (REST) на основе сообщений. Restful API не требуют протоколов веб-сервисов на основе XML ( SOAP и WSDL) для поддержки своих интерфейсов.

Consuming Web Service

Before consuming a web service, we need to generate a Proxy class that wraps the call to the web services methods. It takes care of generating the correct SOAP message format and managing the transmission of the message over the wire using HTTP on port 80. When it gets the response message back, it also convert the results back to the corresponding .NET data types.

We can generate a Proxy class in .NET in either of the following two ways:

  1. Visual Studio IDE web reference feature
  2. Command line utility Wsdl.exe

Generating the Proxy class with VS IDE

  1. Deign the default.aspx with two textboxes, three labels and a single button server control as in the following.
  2. Right-click over the client project in the Solution Explorer, and select «Add Service reference», then click on the «Advanced» button in the dialog box and finally click «Add Web Reference» as in the following.
  3. Copy the Web Service URL from the image 1.2, paste into the URL text box and hit Enter. This operation will browse your web service.
    Figure 1.5: Add Web Reference Dialog box
     
  4. The web service test page will appear in the windows with an entire methods list and the «Add Reference» button will be enabled as:
    Figure 1.6: Adding a Web Reference
     
  5. In the Web Reference name text box you can change the namespace in which the proxy class will generated.
  6. Now click over the «Add Reference» button.
  7. Now the web reference will appear in the Web References group for the project in the Solution Explorer window as in the following:
    Figure 1.7: Web Reference in Solution Explorer
     
  8. Open the Default.aspx.cs file and add a button click handler and put the following code in it:
  9. Finally run the project and enter 2 integer type values in the given text boxes and hit the button for calling the additional web service method as in the following:
    Figure 1.8: Addition Web Reference Result

Generating the Proxy class WSDL.EXE

This utility takes a WSDL file and generates a corresponding proxy class that you can use to invoke the web service. This tool does not require the web service client to use the .NET IDE.

  1. Open a command prompt from «Start» -> «All Programs» -> «Microsoft Visual Studio 10» -> «Visual Studio Tools».
  2. Then navigate to the folder that contains the WSDL file and fire this command as.
    wsdl /out:UtilityWebServiceProxy.cs http://localhost:2186/TestWS/UtilityWebService.asmx
    By default the generated class is in the C# language, but you can change it by adding the /language:vb parameter.
  3. If you browse to your project directory, notice that the «UtilityWebServiceProxy.cs» file is added there.
  4. Now copy this file to your project’s «App_Code» folder by selecting «Add Existing Item» from the Solution Explorer.
  5. And finally instantiate the web service class again.Note: if the client is already consuming the web service and you make a change later in this then you don’t need to perform the entire process again. Just go the Solution Explorer, right-click over the web reference folder and select update reference. All the new definitions are reflected automatically.

Интеграция 1С с ГИИС ДМДК

ГИИС ДМДК — единая информационная платформа для взаимодействия участников рынка драгоценных металлов и драгоценных камней. с 01.09.21 стартовал обязательный обмен данными с Федеральной пробирной палатой (ФПП) исключительно через ГИИС. А постепенно — с 01.01.2022 и с 01.03.2022 — все данные о продаже драгоценных металлов и камней должны быть интегрированы с ГИИС.
У многих пользователей возникает вопрос как автоматизировать обмен между программой 1С и ГИИС ДМДК.
В настоящей статье ВЦ Раздолье поделится своим опытом о реализации такого обмена.
Автор статьи — Мордовин Антон — архитектор систем на базе 1С Внедренческого центра «Раздолье».

Этап № 6

Теперь давайте напишем код для метода GET в этом же файле. Данный метод станет запускаться при каждом вызове сервиса из веб-браузера. Он будет применяться для получения доступных туториалов:

[WebGet(UriTemplate="/Tutorial")]

public String GetAllTutorial()
{
    int count = 1st.Count;
    String TutorialList = "";
    for (int i = ; i < count; i++)
    TutorialList = TutorialList + lsti + ",";
    return TutorialList;
}

Обратите внимание на строку [WebGet(UriTemplate=»/Tutorial»)] — она очень важна и необходима для определения, как мы будем вызывать данный метод по URL. К примеру, если наш сервис расположен по адресу http://localhost:52645/TutorialService.svc, а в его конец мы добавим «/Tutorial» и получим http://localhost:52645/TutorialService.svc/Tutorial, то будет вызван вышенаписанный код

Атрибут WebGet — это параметр, позволяющий GetAllTutorials() быть RESTful-методом, который можно вызвать GET-запросом.

Что касается самого метода GetAllTutorials(), то в нём есть код, собирающий все названия туториалов и возвращающий их в одной строке.

Свойства

Получает объект приложения для текущего HTTP-запроса.

Возвращает контейнер для компонента.

(Унаследовано от MarshalByValueComponent)

Получает объект ASP.NET HttpContext для текущего запроса, где инкапсулируется весь HTTP-контекст, используемый HTTP-сервером для обработки веб-запросов.

Возвращает значение, показывающее, находится ли компонент в настоящий момент в режиме разработки.

(Унаследовано от MarshalByValueComponent)

Возвращает список обработчиков событий, которые прикреплены к этому компоненту.

(Унаследовано от MarshalByValueComponent)

Получает HttpServerUtility для текущего запроса.

Получает экземпляр HttpSessionState для текущего запроса.

Возвращает или задает сайт компонента.

(Унаследовано от MarshalByValueComponent)

Получает версию протокола SOAP, используемого для запроса SOAP к веб-службе XML.

Получает объект сервера ASP.NET . Может использоваться для проверки прав пользователя на выполнение запроса.

Генерация доменных классов на основе XML схемы

Следубщим шагом необходимо сгенерировать Java классы из XSD файла. Правильным подходом является
их автоматическое создание в процессе сборки с использованием плагина maven или gradle.

Конфигурация плагина для maven:

Сгенерированные классы будут помещены в каталог.

То же самое и с gradle:

Следующий шаг — добавление задачи , необходимой gradle для генерации Java классов:

Т.к. gradle не имеет JAXB плагина(пока), он включает в себя ant задачу, которая делает файл сборки
немного сложнее по сравнению с файлом сборки Maven.

В обоих случаях, процесс генерации объектов включен в жизненный цикл сборки, поэтому не требуются
отдельные шаги по запуску этого процесса.

Introduction

Creating your first web service is incredibly easy. In
fact, by using the wizards in Visual Studio. NET you can have your first service
up and running in minutes with no coding.

For this example I have created a service called in the /WebServices directory on my local machine. The files will be
created in the /WebServices/MyService directory.

A new namespace will be defined called , and within this namespace will be a set
of classes that define your Web Service. By default the following classes will be
created:

Global (in global.asax) Derived from HttpApplication. This file is the
ASP.NET equivalent of a standard ASP global.asa file.
WebService1 (in WebService1.cs) Derived from . This
is your WebService class that allows you to expose methods that can be
called as WebServices.

There are also a number of files created:

AssemblyInfo.cs Contains version and configuration information
for your assembly.
web.config Defines how your application will run (debug
options, the use of cookies etc).
MyService.disco Discovery information for your service.
WebService1.asmx Your WebService URL. Navigate to this file in a
browser and you will get back a user-friendly page showing the methods
available, the parameters required and the return values. Forms are even
provided allowing you to test the services through the web
page.
bin\MyService.dll The actual WebService component. This is created when you build the service.

The class for your service that is created by default is
called (in this case) , and is within the namespace. The code is
partially shown below.

C#
Copy Code

namespace MyService
{
    ...
                [WebService(Namespace="http://codeproject.com/webservices/",
	            Description="This is a demonstration WebService.")]
    public class WebService1 : System.Web.Services.WebService
    {
        public WebService1()
        {
            
            InitializeComponent();
        }

        ...
        
        
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

A default method is generated and commented out. Simply
uncomment and build the project. Hey Presto, you have a walking talking
WebService. 

A WebService should be associated with a namespace. Your Wizard-generated
service will have the name space http://tempuri.org. If you compile and run the
service as-is you’ll get a long involved message indicating you should choose a
new namespace, so we add the namespace, and the WebService description as
follows:

C#
Copy Code

[WebService(Namespace="http://codeproject.com/webservices/",
            Description="This is a demonstration WebService.")]
public class WebService1 : System.Web.Services.WebService
{
    ...

To test the service you can right click on WebService1.asmx in the Solution Explorer in Visual Studio and
choose «View in Browser». The test page is shown below,

When invoked this returns the following:

Редактирование свойств Web-сервиса

На закладке Основные вводится имя, синоним и комментарий объекта.
На закладке Операции создаются подчиненные объекты Операции, которые, в свою очередь, могут иметь подчиненные объекты Параметры, необходимые для работы с объектами данного типа. Описание подчиненных объектов выполняется в палитре свойств.

Свойства «Операции»

Помимо общих свойств объектов конфигурации операция Web-сервиса содержит следующие свойства:

● Тип возвращаемого значения – тип значения, которое возвращает операция Web-сервиса. Может являться типом значения XDTO или типом объекта
XDTO.
● Возможно пустое значение – показывает, может ли возвращаемое значение принимать неопределенное значение.
● В транзакции – показывает, будет ли выполняться код модуля Web-сервиса в транзакции или нет. Если свойство установлено, то при вызове Web-сервиса автоматически будет начата транзакция, а при завершении работы Web-сервиса транзакция будет либо зафиксирована, либо произойдет откат транзакции (в зависимости от результатов выполнения). Если свойство не установлено, при начале исполнения модуля Web-сервиса
транзакция не будет начата.
● Имя метода – имя экспортируемой процедуры модуля Web-сервиса, которая будет выполнена при вызове данного свойства.
На закладке Подсистемы указывается, к каким подсистемам относятся объекты данного типа.
На закладке Прочее определяются следующие свойства:
● URI пространства имен – содержит URI пространства имен Web-сервиса. Каждый Web-сервис может быть однозначно идентифицирован по своему
имени и URI пространству имен, которому он принадлежит. Пространство имен сервиса не должна совпадать с известными пространствами имен, которые уже используются или зарезервированы другими организациями. Рекомендуется в пространство имен сервиса включать фрагмент, уникальный для организации, которая ведет разработку Web-сервиса. Например, для организации с названием Промресурс имеет смысл начинать все пространства имен с префикса, например, http://promresurs.com. Тогда URI пространства имен Web-сервиса будет иметь вид http://promresurs.com/public/services/OurService.
● Пакеты XDTO – перечень пакетов XDTO, типы которых могут использоваться в качестве типов возвращаемого значения операций и типов параметров операций Web-сервиса.
● Имя файла публикации – имя файла описания Web-сервиса, который расположен на веб-сервере.
По кнопке Модуль открывается редактор модуля Web-сервиса.

Свойства «Параметр»
Помимо общих свойств объектов конфигурации параметр операции Web-сервиса содержит следующие свойства:
● Тип значения – тип значения параметра операции Web-сервиса. Может являться типом значения XDTO или типом объекта XDTO.
● Возможно пустое значение – показывает, может ли значение параметра операции принимать неопределенное значение.
● Направление передачи – определяет направление передачи данных с помощью данного параметра. Возможные значения:
● Входной – означает, что параметр используется для передачи данных Web-сервису;
● Выходной – означает, что параметр используется для получения данных от Web-сервиса;
● Входной-Выходной – означает, что параметр может использоваться как для передачи данных, так и для их получения от Web-сервиса.

Выводы

Основным преимуществом шаблона асинхронных запросов является возможность корреляции запросов и ответов клиентом Web-сервисов и поставщиком сервиса. В представленном здесь примере был рассмотрен простой ID корреляции однократного использования и механизм обновления таймера, присущего этому отдельному примеру приложения. Для этой же цели можно использовать, к примеру, несколько комбинаций WS-* спецификаций. WS-Addressing Endpoint Reference или WS-Transaction Coordination Context также могут содержать ID корреляции и обновлять значения таймера. Использование данного шаблона индивидуально для отдельных приложений, и независимо от того, используете ли вы стандартные элементы заголовка SOAP и различные WS-* спецификации, поведение каждой реализации операции должно быть четко определено и задокументировано.

В реализуемом здесь примере для отправки запросов и получения ответов используется традиционный шаблон обмена сообщениями SOAP типа запрос-ответ. В качестве альтернативы можно использовать шаблон в стиле REST, в которой запросы отправляются сервлету методом HTTP POST, а ответы извлекаются с использованием метода HTTP GET. Каждый из этих подходов является в равной степени допустимым и обладает собственными преимуществами и недостатками. Выбор подхода осуществляется в зависимости от требования вашего приложения. Например, если операция будет требовать использования аутентификации WS-Security, то в использование модели взаимодействия в стиле REST нет смысла.

В заключении, можно легко представить расширение области применения данного примера для выполнения запрашивающими сторонами детальных запросов статуса в длительных операциях или даже для отмены уже выполняемых операций. Иллюстрация таких возможностей не является задачей данной статьи, вам предлагается исследовать их самостоятельно.

Гость форума
От: admin

Эта тема закрыта для публикации ответов.