&НаКлиенте
Перем WebSocketСоединение;
Перем ИдентификаторПодписки;
&НаКлиенте
Процедура Подключить(Команда)
ДобавитьСообщение("Попытка подключения к MOEX Algo WebSocket...");
ОбработчикиСокета = Новый ОбработчикиWebSocketКлиентСоединения;
ОбработчикиСокета.Модуль = ЭтотОбъект;
ОбработчикиСокета.ОбработчикОткрытияСоединения = "ВебСокет_ОбработчикОткрытия";
ОбработчикиСокета.ОбработчикЗакрытияСоединения = "ВебСокет_ОбработчикЗакрытия";
ОбработчикиСокета.ОбработчикПолученияСообщения = "ВебСокет_ОбработчикПолученияСообщения";
ОбработчикиСокета.ОбработчикОшибки = "ВебСокет_ОбработчикОшибки";
АдресВебСокета = "wss://iss.moex.com/infocx/v3/websocket";
Попытка
WebSocketСоединение = WebSocketКлиентСоединения.ОткрытьСоединение("MOEXAlgo", АдресВебСокета, ОбработчикиСокета);
ДобавитьСообщение("Инициировано открытие соединения");
Исключение
ДобавитьСообщение("Ошибка при открытии WebSocket: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ВебСокет_ОбработчикОткрытия(Соединение) Экспорт
ДобавитьСообщение("WebSocket соединение открыто");
Фрейм = "CONNECT" + Символы.ПС;
Фрейм = Фрейм + "domain:DEMO" + Символы.ПС;
Фрейм = Фрейм + "login:guest" + Символы.ПС;
Фрейм = Фрейм + "passcode:guest" + Символы.ПС;
Фрейм = Фрейм + Символы.ПС + Символ(0);
Соединение.ОтправитьСообщение(Фрейм);
ДобавитьСообщение("Команда CONNECT отправлена");
КонецПроцедуры
&НаКлиенте
Процедура ВебСокет_ОбработчикЗакрытия(Соединение, КодЗакрытия) Экспорт
ДобавитьСообщение("WebSocket соединение закрыто, код: " + КодЗакрытия);
КонецПроцедуры
&НаКлиенте
Процедура ВебСокет_ОбработчикОшибки(Соединение, КодОшибки, Описание) Экспорт
ДобавитьСообщение("Ошибка WebSocket: код=" + КодОшибки + ", описание=" + Описание);
КонецПроцедуры
&НаКлиенте
Процедура ВебСокет_ОбработчикПолученияСообщения(Соединение, Сообщение) Экспорт
ТекстСообщения = Сообщение;
Если ТипЗнч(Сообщение) = Тип("ДвоичныеДанные") Тогда
ТекстСообщения = ПолучитьСтрокуИзДвоичныхДанных(Сообщение, КодировкаТекста.UTF8);
КонецЕсли;
ДанныеСообщения = РазобратьSTOMPФрейм(ТекстСообщения);
Ответ = ТекстСообщения;
Если ДанныеСообщения.Команда = "CONNECTED" Тогда
ДобавитьСообщение("Успешная аутентификация!");
ИначеЕсли ДанныеСообщения.Команда = "MESSAGE" Тогда
сообщить(ТекстСообщения);
Если ЗначениеЗаполнено(ДанныеСообщения.Тело) Тогда
ОбработатьДанныеБиржи(ДанныеСообщения.Тело);
Иначе
ДобавитьСообщение("Пустое тело сообщения");
КонецЕсли;
ИначеЕсли ДанныеСообщения.Команда = "ERROR" Тогда
сообщить(ТекстСообщения);
ДобавитьСообщение("Ошибка сервера: " + ДанныеСообщения.Тело);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция РазобратьSTOMPФрейм(ФреймСтрока)
Результат = Новый Структура("Команда,Заголовки,Тело");
Строки = СтрРазделить(ФреймСтрока, Символы.ПС, Ложь);
Если Строки.Количество() > 0 Тогда
Результат.Команда = Строки[0];
КонецЕсли;
Заголовки = Новый Соответствие();
ИндексТела = 0;
Для Индекс = 1 По Строки.Количество() - 1 Цикл
ТекущаяСтрока = Строки[Индекс];
Если ПустаяСтрока(СокрЛП(ТекущаяСтрока)) Тогда
ИндексТела = Индекс + 1;
Прервать;
КонецЕсли;
Если Лев(ТекущаяСтрока, 1) = "{" Тогда
ИндексТела = Индекс;
Прервать;
КонецЕсли;
Позиция = СтрНайти(ТекущаяСтрока, ":");
Если Позиция > 0 Тогда
Ключ = СокрЛП(Лев(ТекущаяСтрока, Позиция - 1));
Значение = СокрЛП(Сред(ТекущаяСтрока, Позиция + 1));
Заголовки.Вставить(Ключ, Значение);
КонецЕсли;
КонецЦикла;
Результат.Заголовки = Заголовки;
Если ИндексТела > 0 И ИндексТела <= Строки.Количество() - 1 Тогда
ТелоJSON = "";
Для Инд = ИндексТела По Строки.Количество() - 1 Цикл
ТелоJSON = ТелоJSON + Строки[Инд];
КонецЦикла;
Результат.Тело = ТелоJSON;
КонецЕсли;
Возврат Результат;
КонецФункции
&НаКлиенте
Процедура Подписаться(Команда)
Если WebSocketСоединение = Неопределено Тогда
ДобавитьСообщение("Нет активного WebSocket соединения");
Возврат;
КонецЕсли;
ИдентификаторПодписки = Строка(Новый УникальныйИдентификатор());
Фрейм = "SUBSCRIBE" + Символы.ПС;
Фрейм = Фрейм + "id:" + ИдентификаторПодписки + Символы.ПС;
Фрейм = Фрейм + "destination:MXSE.securities" + Символы.ПС;
Фрейм = Фрейм + "selector:TICKER=""MXSE.TQBR.SBER"" and LANGUAGE=""en""" + Символы.ПС;
Фрейм = Фрейм + Символы.ПС + Символ(0);
Попытка
WebSocketСоединение.ОтправитьСообщение(Фрейм);
ДобавитьСообщение("Подписка отправлена для SBER");
Запрос = Фрейм;
Исключение
ДобавитьСообщение("Ошибка отправки SUBSCRIBE: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура Отключить(Команда)
Если WebSocketСоединение <> Неопределено Тогда
Попытка
Фрейм = "DISCONNECT" + Символы.ПС + Символы.ПС + Символ(0);
WebSocketСоединение.ОтправитьСообщение(Фрейм);
WebSocketСоединение.Закрыть();
ДобавитьСообщение("WebSocket соединение закрыто");
Исключение
ДобавитьСообщение("Ошибка при закрытии соединения: " + ОписаниеОшибки());
КонецПопытки;
WebSocketСоединение = Неопределено;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьДанныеБиржи(JSONСтрока)
Попытка
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(JSONСтрока);
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь); // Истина = читать в Соответствие
ЧтениеJSON.Закрыть();
Если Данные.Свойство("properties") Тогда
ТипОбновления = Данные.properties.type;
ДобавитьСообщение("Тип обновления: " + ТипОбновления);
КонецЕсли;
Если Данные.Свойство("data") И Данные.data.Количество() > 0 Тогда
Для Каждого ТекущаяСтрока Из Данные.data Цикл
ДобавитьСообщение("Данные: " + ТекущаяСтрока);
КонецЦикла;
КонецЕсли;
Исключение
ДобавитьСообщение("Ошибка разбора JSON: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ДобавитьСообщение(ТекстСообщения)
Сообщить(ТекстСообщения);
КонецПроцедуры