-
Notifications
You must be signed in to change notification settings - Fork 19
Поддержка протокола WebSocket на 2.0 от нативного веб сервера #112
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
base: master
Are you sure you want to change the base?
Changes from 6 commits
da635e3
81e5a96
d563107
dbf25b7
0fb083a
944998e
8f175d0
b634d82
0033997
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,6 +12,12 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Пластилин | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем ОбработчикЗапросов; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Пластилин | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем СоединенияВебСокетов; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Пластилин | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем Поделка; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем ВебСервер; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Желудь | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -46,6 +52,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура СоздатьСервер() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если ВебСервер = Неопределено Тогда | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ВебСервер = Новый ВебСервер(Настройки.Порт); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ВебСервер.ИспользоватьВебСокеты(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ВебСервер.ДобавитьОбработчикЗапросов(ЭтотОбъект, "ОбработатьЗапрос"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЕсли; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -54,6 +61,28 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Запрос = ЗапросИзКонтекста(Контекст); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если Контекст.ВебСокеты.ЭтоВебСокетЗапрос Тогда | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Сокет = Контекст.ВебСокеты.ПодключитьВебСокет(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Идентификатор = Запрос.Сессия.Идентификатор(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Топик = Запрос.Путь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| СоединениеВебСокета = Поделка.НайтиЖелудь("СоединениеВебСокета"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| СоединениеВебСокета.Сокет = Сокет; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| СоединениеВебСокета.Активно = СоединениеВебСокета.СокетАктивен(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| СоединениеВебСокета.Контекст = Контекст; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Если этот метод завершится, то соединение будет разорвано. поэтому ждем | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Пока СоединениеВебСокета.СокетАктивен() Цикл | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Приостановить(10000); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check notice on line 80 in src/Классы/НативныйВебСервер.os
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЦикла; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Возврат; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЕсли; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+64
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Критическая проблема: утечка ресурсов при обработке WebSocket Цикл ожидания с Если Контекст.ВебСокеты.ЭтоВебСокетЗапрос Тогда
Сокет = Контекст.ВебСокеты.ПодключитьВебСокет();
Идентификатор = Запрос.Сессия.Идентификатор();
Топик = Запрос.Путь;
СоединениеВебСокета = Поделка.НайтиЖелудь("СоединениеВебСокета");
СоединениеВебСокета.Сокет = Сокет;
СоединениеВебСокета.Активно = СоединениеВебСокета.СокетАктивен();
СоединениеВебСокета.Контекст = Контекст;
- СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик);
-
- // Если этот метод завершится, то соединение будет разорвано. поэтому ждем
- Пока СоединениеВебСокета.СокетАктивен() Цикл
- Приостановить(10000);
- КонецЦикла;
+ Попытка
+ СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик);
+
+ // Если этот метод завершится, то соединение будет разорвано. поэтому ждем
+ // Используем меньший интервал для более отзывчивой проверки
+ Пока СоединениеВебСокета.СокетАктивен() Цикл
+ Приостановить(100); // 100мс вместо 10000мс
+ КонецЦикла;
+ Исключение
+ // Гарантируем удаление соединения при ошибке
+ СоединенияВебСокетов.Удалить(Идентификатор, Топик);
+ ВызватьИсключение;
+ КонецПопытки;
Возврат;
КонецЕсли;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ОтветВино = ОбработчикЗапросов.СформироватьОтвет(Запрос); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ответ = ПодготовитьОтвет(ОтветВино); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,57 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем _БрокерСообщенийВебСокетов; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем _СоединенияВебСокетов; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем _Идентификатор; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем _Соединение; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем _Топик; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем _Включена; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Желудь | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Характер("Компанейский") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &ОсобоеОбращение(ОтключитьВсеНапильники = Истина) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура ПриСозданииОбъекта(&Пластилин БрокерСообщенийВебСокетов, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Пластилин СоединенияВебСокетов) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _СоединенияВебСокетов = СоединенияВебСокетов; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _БрокерСообщенийВебСокетов = БрокерСообщенийВебСокетов; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Включена = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура Подписатся(Соединение, Идентификатор, Топик) Экспорт | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Идентификатор = Идентификатор; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Соединение = Соединение; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Топик = Топик; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Включена = Истина; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ФоновыеЗадания.Выполнить(ЭтотОбъект, "ЗапуститьОбработкуСообщений"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура Отписаться() Экспорт | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Включена = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Отписка не прерывает блокирующее чтение — возможна «зависшая» фоновая задача. Если поток чтения блокируется на Примените дифф: Процедура Отписаться() Экспорт
- _Включена = Ложь;
+ _Включена = Ложь;
+ Если _Соединение <> Неопределено Тогда
+ // Закрываем сокет, чтобы прервать блокирующее чтение
+ Попытка
+ _Соединение.Закрыть();
+ Исключение
+ Сообщить("Ошибка при закрытии соединения при отписке: " + ОписаниеОшибки());
+ КонецПопытки;
+ КонецЕсли;
+ Отключить();
КонецПроцедуры📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура ЗапуститьОбработкуСообщений() Экспорт | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если НЕ _Соединение = Неопределено Тогда | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _БрокерСообщенийВебСокетов.ПриПодключении(_Топик, _Идентификатор); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ОбработкаСообщений(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Иначе | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ВызватьИсключение "Не инициализировано соединение, невозможно запустить обработку сообщений" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЕсли; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура ОбработкаСообщений() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Попытка | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Пока _Включена = Истина И _Соединение.Сокет.Состояние = СостоянияВебСокетов.Открыт() Цикл | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЦикла; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _Соединение.Активно = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Исключение | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Сообщить("Ошибка обработки сообщения " + ОписаниеОшибки()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПопытки; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Отключить(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+41
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Цикл чтения: устранить потенциальную блокировку и улучшить завершение. Добавьте выход при Примените дифф: Процедура ОбработкаСообщений()
Попытка
- Пока _Включена = Истина И _Соединение.Сокет.Состояние = СостояниеВебСокета.Открыт Цикл
- ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку();
- _БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения);
- КонецЦикла;
- _Соединение.Активно = Ложь;
+ Пока _Включена = Истина
+ И _Соединение <> Неопределено
+ И _Соединение.Сокет <> Неопределено
+ И _Соединение.Сокет.Состояние = СостояниеВебСокета.Открыт Цикл
+ ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку();
+ Если ТекстСообщения = Неопределено Тогда
+ Прервать;
+ КонецЕсли;
+ _БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения);
+ КонецЦикла;
Исключение
- Сообщить("Ошибка обработки сообщения " + ОписаниеОшибки());
+ Сообщить("Ошибка обработки сообщения (" + Строка(_Идентификатор) + ", " + Строка(_Топик) + "): " + ОписаниеОшибки());
КонецПопытки;
+ Если _Соединение <> Неопределено Тогда
+ _Соединение.Активно = Ложь;
+ Попытка
+ _Соединение.Закрыть();
+ Исключение
+ Сообщить("Ошибка при закрытии соединения: " + ОписаниеОшибки());
+ КонецПопытки;
+ КонецЕсли;
Отключить();
КонецПроцедуры📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура Отключить() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _СоединенияВебСокетов.УдалитьСоединение(_Соединение); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _БрокерСообщенийВебСокетов.ПриОтключении(_Топик, _Идентификатор); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,44 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем Сокет Экспорт; // Сокет нативного вебсервера | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем Активно Экспорт; // Состояние активности | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Перем Контекст Экспорт; // Контекст соединения | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 🧩 Analysis chainИнкапсуляция состояния вместо экспортируемых переменных. Экспорт Найдите внешние обращения к этим полям: 🏁 Script executed: #!/bin/bash
rg -nP -C2 'СоединениеВебСокета\.(Сокет|Активно|Контекст)'Length of output: 877 Инкапсуляция: сделать Сокет/Активно/Контекст приватными и предоставить API (геттеры/методы) Экспорт этих переменных даёт внешним модулям возможность напрямую менять состояние — обнаружены прямые записи/чтения:
Сделать поля приватными, добавить методы/фабрику для инициализации и управляемых обновлений (УстановитьСокет/УстановитьКонтекст/ОбновитьАктивность + геттеры) и заменить в указанных местах прямые присвоения/доступ на вызовы этих методов. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Желудь | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| &Характер("Компанейский") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура ПриСозданииОбъекта() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Активно = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура Закрыть() Экспорт | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если НЕ Сокет = Неопределено Тогда | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Сокет.Закрыть(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Активно = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЕсли; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Функция СокетАктивен() Экспорт | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если НЕ Сокет = Неопределено Тогда | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Возврат Сокет.Состояние = СостоянияВебСокетов.Открыт(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Иначе | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Возврат Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЕсли; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецФункции | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура ОтправитьСтроку(Сообщение) Экспорт | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Попытка | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Если СокетАктивен() Тогда | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Сокет.ОтправитьСтроку(Сообщение); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Иначе | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Активно = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецЕсли; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Исключение | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Сообщить("Ошибка отправки сообщения в веб сокет " + ОписаниеОшибки()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Активно = Ложь; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПопытки; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. На ошибке отправки стоит закрывать соединение. Сейчас при неактивном сокете/исключении только сбрасывается флаг, но ресурс не освобождается. Примените дифф: Процедура ОтправитьСтроку(Сообщение) Экспорт
Попытка
Если СокетАктивен() Тогда
Сокет.ОтправитьСтроку(Сообщение);
Иначе
- Активно = Ложь;
+ Закрыть();
КонецЕсли;
Исключение
Сообщить("Ошибка отправки сообщения в веб сокет " + ОписаниеОшибки());
- Активно = Ложь;
+ Закрыть();
КонецПопытки;
КонецПроцедуры📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Процедура ОтправитьДвоичныеДанные(Сообщение) Экспорт // Для обратной совместимости с брокером | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ОтправитьСтроку(Сообщение); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| КонецПроцедуры | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainОтправка двоичных данных не должна проксироваться в строковую — риск порчи данных. Нужна отдельная отправка бинарного фрейма (если поддерживается API), с понижающим переходом на текст только когда вход — строка. Примените дифф: -Процедура ОтправитьДвоичныеДанные(Сообщение) Экспорт // Для обратной совместимости с брокером
- ОтправитьСтроку(Сообщение);
-КонецПроцедуры
+Процедура ОтправитьДвоичныеДанные(Сообщение) Экспорт // Для обратной совместимости с брокером
+ Если ТипЗнч(Сообщение) = Тип("ДвоичныеДанные") Тогда
+ Попытка
+ Если СокетАктивен() Тогда
+ // Предпочтительно отправлять бинарный фрейм
+ Сокет.ОтправитьДвоичныеДанные(Сообщение);
+ Иначе
+ Закрыть();
+ КонецЕсли;
+ Исключение
+ Сообщить("Ошибка отправки двоичных данных в веб сокет " + ОписаниеОшибки());
+ Закрыть();
+ КонецПопытки;
+ Иначе
+ // Фоллбэк: текст
+ ОтправитьСтроку(Сообщение);
+ КонецЕсли;
+КонецПроцедурыПроверьте, что у нативного веб‑сокета есть метод отправки бинарных данных и как он называется: Также найдите места, где вызывается 🏁 Script executed: #!/bin/bash
rg -nP -C2 'Отправ(ить)?ДвоичныеДанные\s*\('Length of output: 3823 🌐 Web query: 💡 Result: Коротко: нет — нативный веб‑сервер 1С не предоставляет серверный API WebSocket для отправки бинарных сообщений, поэтому точного имени/сигнатуры метода нет. Основание:
Если нужно, могу:
Источники: Не проксировать двоичные данные в текст — реализовать реальную поддержку бинарных WebSocket‑фреймов или явный безопасный фоллбэк Проверено: нативный веб‑сервер 1С не предоставляет серверного API для отправки бинарных WebSocket‑фреймов, поэтому предложенный патч с вызовом Сокет.ОтправитьДвоичныеДанные некорректен. Вызовы ОтправитьДвоичныеДанные встречаются в кодовой базе и требуют корректной обработки:
Действия (выбрать и реализовать один из вариантов):
Точки изменения: прежде всего — src/Классы/СоединениеВебСокета.os; затем скорректировать брокер/обработчики и тесты в перечисленных файлах. Исправьте и повторно запросите ревью. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,29 @@ | ||||||||||||
| &Пластилин | ||||||||||||
| Перем Поделка; | ||||||||||||
|
|
||||||||||||
| Перем ИспользоватьНативныйСервер; | ||||||||||||
|
|
||||||||||||
| &Дуб | ||||||||||||
| Процедура ПриСозданииОбъекта(&Пластилин Настройки) | ||||||||||||
| ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2"; | ||||||||||||
|
Check notice on line 8 in src/Классы/ФабрикаВебСокетов.os
|
||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 🧩 Analysis chainПотенциальная проблема с определением версии платформы Использование Рекомендую использовать более точную проверку версии: - ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2";
+ СистИнфо = Новый СистемнаяИнформация();
+ МассивВерсии = СтрРазделить(СистИнфо.Версия, ".");
+ ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И
+ (МассивВерсии.Количество() > 0 И Число(МассивВерсии[0]) >= 2);Давайте проверим, как используется версия платформы в других местах кодовой базы: 🏁 Script executed: #!/bin/bash
# Поиск использования СистемнаяИнформация().Версия в кодовой базе
rg -n "СистемнаяИнформация\(\)\.Версия" --type-add 'os:*.os' --type osLength of output: 315 Исправить ненадёжную проверку версии платформы (Лев(...)= "2") Лев(Новый СистемнаяИнформация().Версия,1) = "2" ненадёжен — такая проверка встречается в двух местах; заменить на парсинг мажорной версии и числовое сравнение. Файлы: src/Классы/ФабрикаВебСокетов.os:8, src/Классы/ФабрикаВебСерверов.os:15 Рекомендуемая замена: - ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2";
+ СистИнфо = Новый СистемнаяИнформация();
+ МассивВерсии = СтрРазделить(СистИнфо.Версия, ".");
+ ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И
+ (МассивВерсии.Количество() > 0 И Число(МассивВерсии[0]) >= 2);Внести одинаковое исправление в оба файла. 📝 Committable suggestion
Suggested change
|
||||||||||||
| КонецПроцедуры | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| &Завязь(Тип = "Строка") | ||||||||||||
| &Характер("Компанейский") | ||||||||||||
| Функция ПодпискаНаВебСокет() Экспорт | ||||||||||||
| Если ИспользоватьНативныйСервер Тогда | ||||||||||||
| Возврат Поделка.НайтиЖелудь("ПодпискаНаВебСокетНативная"); | ||||||||||||
| Иначе | ||||||||||||
| Возврат Поделка.НайтиЖелудь("ПодпискаНаВебСокетПрикладная"); | ||||||||||||
| КонецЕсли; | ||||||||||||
| КонецФункции | ||||||||||||
|
|
||||||||||||
| &Завязь(Тип = "Строка") | ||||||||||||
| Функция ШифрованиеВебСокетаОбщий() Экспорт | ||||||||||||
| Если ИспользоватьНативныйСервер Тогда | ||||||||||||
| Возврат Поделка.НайтиЖелудь("ШифрованиеВебСокетаМок"); | ||||||||||||
| Иначе | ||||||||||||
| Возврат Поделка.НайтиЖелудь("ШифрованиеВебСокета"); | ||||||||||||
| КонецЕсли; | ||||||||||||
| КонецФункции | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
|
|
||
| &Желудь | ||
| Процедура ПриСозданииОбъекта() | ||
|
|
||
| КонецПроцедуры | ||
|
|
||
| Функция МагическаяСтрока() Экспорт | ||
| Возврат "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | ||
| КонецФункции | ||
|
|
||
| Функция ХешОтветаРукопожатия(КлючРукопожатия) Экспорт | ||
| Результат = СокрЛП(КлючРукопожатия) + МагическаяСтрока(); | ||
| Провайдер = Новый ХешированиеДанных(ХешФункция.SHA1); | ||
| Провайдер.Добавить(Результат); | ||
| Результат = Base64Строка(Провайдер.ХешСумма); | ||
| Возврат Результат; | ||
| КонецФункции | ||
|
|
||
| Функция ЗапаковатьСообщениеТекстовоеСообщение(Сообщение) Экспорт | ||
|
|
||
| Возврат Сообщение; | ||
|
|
||
| КонецФункции | ||
|
Comment on lines
+19
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainУпрощённая упаковка сообщений Функция Давайте проверим, как используется эта функция: 🏁 Script executed: #!/bin/bash
# Проверка использования функции упаковки сообщений
rg "ЗапаковатьСообщениеТекстовоеСообщение" --type-add 'os:*.os' --type os -A 2 -B 2Length of output: 3149 Мок должен возвращать двоичные данные, как продакшен-функция. В src/Классы/ШифрованиеВебСокетаМок.os ЗапаковатьСообщениеТекстовоеСообщение сейчас просто делает "Возврат Сообщение;", тогда как в src/Классы/ШифрованиеВебСокета.os сообщение конвертируется в двоичный формат (ПолучитьДвоичныеДанныеИзСтроки). Брокер (src/Классы/БрокерСообщенийВебСокетов.os) передаёт результат в ОтправитьДвоичныеДанные, поэтому исправить: привести мок к тому же формату (вернуть двоичные данные, напр. вызвать ПолучитьДвоичныеДанныеИзСтроки) или явно адаптировать/документировать вызовы и тесты (tests/alltest.os). 🤖 Prompt for AI Agents |
||
|
|
||
| Функция РаспаковатьСообщение(ТекстСообщения) Экспорт | ||
|
|
||
| ДанныеСообщения = Новый Структура("ТипСообщения, Сообщение", 1, ТекстСообщения); | ||
| Возврат ДанныеСообщения; | ||
|
|
||
| КонецФункции | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
|
|
||
| Функция Открыт() Экспорт | ||
|
|
||
| СостояниеСокетОткрыт = Неопределено; | ||
|
|
||
| Выполнить("СостояниеСокетОткрыт = СостояниеВебСокета.Открыт"); | ||
|
|
||
| Возврат СостояниеСокетОткрыт; | ||
|
|
||
| КонецФункции |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Отсутствует обработка ошибок при вызове обработчика
При вызове
Рефлектор.ВызватьМетодотсутствует обработка исключений, что может привести к падению всего соединения при ошибке в обработчике.Обработчик = НайтиОбработчик(Топик); СоответствиеПараметров = Новый Соответствие(); СоответствиеПараметров.Вставить("Идентификатор", Идентификатор); СоответствиеПараметров.Вставить("Топик", Топик); СоответствиеПараметров.Вставить("Сообщение", ДанныеСообщения.Сообщение); Параметры = КонструкторыПараметров.СформироватьМассивНеобходимыхПараметров(Обработчик.Действие.Параметры, СоответствиеПараметров); - Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры); + Попытка + Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры); + Исключение + // Логируем ошибку, но не разрываем соединение + // TODO: Добавить логирование + КонецПопытки;📝 Committable suggestion
🤖 Prompt for AI Agents