Автоматическое отключение неактивных веб-клиентов

У вас организован доступ в базу через веб-клиент для посторонних лиц (веб-портал, веб-витрина, и т.д.), и вы испытываете проблему нехватки лицензий 1С из-за того, что пользователи оставляют открытыми вкладки с 1С, не работая в них? Есть решение!

По мотивам дискуссии на партнерском форуме https://partners.v8.1c.ru/forum/topic/1620757
Публикация сделана для тех, у кого нет доступа на партнерский форум.

Внешние пользователи, после того как поработают в 1С, любят не закрывать вкладку, а просто переключаются на другие. 

Попытка решить проблему типовыми средствами, кажущимися подходящими для данной ситуации:

1. В параметрах информационной базы установить следующие значения:
Время засыпания пассивного сеанса — 600 сек.
Время завершения спящего сеанса  — 10 сек.

2. При публикации базы на веб сервере указать параметр "Время жизни соединения в сек." — 600

Данные методы НЕ работают, по причите того что даже в пассивном режиме (неактивная вкладка браузера), в 1С выполняются множество обработчиков ожидания, в которых есть серверные вызовы (то же обновление динамического списка раз в минуту), поэтому метка неактивности клиента (используемая в механизме "Время засыпания пассивного сеанса") с каждым запросом отодвигается.

К сожалению, 1С не предоставляет штатных средств для определения времени последней активности пользователя.

 

Но есть работающий метод:

В веб-клиенте Поле HTML документа имеет доступ к родительскому окну 1С и может с ним взаимодействовать, в частности, можно установить для всего родительского окна обработчики на события активности пользователя, такие как нажатия клавиш, движения и нажатия мыши. 

На "рабочем столе" 1С должна находиться как минимум одна форма. В эту форму нужно добавить Поле HTML документа. Для него можно установить минимальный размер, а цвет фона сделать равным цвету фона формы, чтобы его не было видно. Важное уточнение: поле должно иметь свойство Видимость = Истина, иначе оно попросту не будет создано на клиенте. 

Если на вашей форме нет даже самого малого свободного места, то можно создать две страницы (видимость переключателя = Ложь). На первую страницу переносятся все элементы формы, а на вторую Поле HTML документа. Затем при открытии формы нужно программно установить активной вторую страницу, а через 0.1 сек обратно первую. Если этого не сделать, то поле HTML физически создастся только после первой активации второй страницы, то есть, никогда (учитывая что переключатель невидим).

Затем в поле HTML загружаем javascript, который и будет выполнять всю работу. Доступ к родительскому окну осуществляется посредством идентификатора top.

<HTML>
<BODY>
<SCRIPT>
// Время завершения сеанса от последней активности пользователя, в миллисекундах.
// Для 10-минутного тайм-аута следует установить 600000.
var timeoutInMiliseconds = 5000; // 5 секунд.

var onUserInactive = function() {
// При наступлении тайм-аута переходим на пустую страницу, тем самым завершая сеанс 1С.
top.location.href = 'about:blank';
}

// Первоначальный запуск обработчика ожидания.
var wait = setTimeout(onUserInactive, timeoutInMiliseconds);

var onUserActivity = function() {
// При каждой активности пользователя перезапускаем обработчик ожидания.
clearTimeout(wait);
wait = setTimeout(onUserInactive, timeoutInMiliseconds);
};

// Подключаем обработчики отслеживания активности пользователя.
top.document.onmousemove     = onUserActivity;
top.document.onmouseover     = onUserActivity;
top.document.mousedown         = onUserActivity;
top.document.mouseup         = onUserActivity;
top.document.onkeydown         = onUserActivity;
top.document.onkeyup         = onUserActivity;
top.document.focus             = onUserActivity;

// Для этих панелей подключаемся отдельно именно к этим элементам,
// так как в обработчике установленном фирмой 1С установлен запрет на event propagation,
// и top.document.onmousemove его не словит.
top.document.getElementById('navigatorPanelArea').onmousemove = onUserActivity;
top.document.getElementById('actionPanelArea').onmousemove = onUserActivity;

// Ловим события движения мыши из вложенных фреймов (других полей html документа).
function bubbleIframeMouseMove(iframe) {
try
{
// Save any previous handler
var existingOnMouseMove = iframe.contentWindow.onmousemove;

// Attach a new listener
iframe.contentWindow.onmousemove = function(e) {
// Fire any existing listener
if (existingOnMouseMove) existingOnMouseMove(e);

// Create a new event for the this window
var evt = document.createEvent("MouseEvents");

// We'll need this to offset the mouse move appropriately
var boundingClientRect = iframe.getBoundingClientRect();

// Initialize the event, copying exiting event values
// for the most part
evt.initMouseEvent(
"mousemove",
true, // bubbles
false, // not cancelable
window,
e.detail,
e.screenX,
e.screenY,
e.clientX + boundingClientRect.left,
e.clientY + boundingClientRect.top,
e.ctrlKey,
e.altKey,
e.shiftKey,
e.metaKey,
e.button,
null // no related element
);

// Dispatch the mousemove event on the iframe element
iframe.dispatchEvent(evt);
};
}
catch(err)
{
}
}

var iframes = top.document.getElementsByTagName('iframe');
for (var i in iframes)
bubbleIframeMouseMove(iframes[i]);
</SCRIPT>
</BODY>
</HTML>

По истечении отведенного времени, сеанс веб-клиента завершится (останется пустая вкладка браузера).
Впрочем, если есть открытые формы с признаком Модифицированность = Истина (звездочка в конце заголовка формы), то сеанс не завершается автоматически, а происходит автоматическая активация вкладки 1С и отображение вопроса "Покинуть эту страницу?". Это типовое поведение, сделанное чтобы не потерять введенные данные, присутствующее и в тонком клиенте при закрытии приложения ("Данные были изменены. Сохранить изменения?").

Полная реализация метода в прикрепленной обработке.

Рекомендую ознакомиться с другой моей публикацией
Javascript и 1С. Кросс-платформенное взаимодействие //infostart.ru/public/398366/

11 Comments

  1. Leits

    я не до конца понял на какую форму нужно выводить HTML поле? там же их много(например Корзина, Рабочий стол, различные журналы заказы, РНК )

    Reply ↓
  2. VitaliyCeban

    (1) На любую, которая остается открытой на всём протяжении работы. То есть на одну из форм из «рабочей области начальной страницы».

    Reply ↓
  3. Glebis

    Статья очень нужная.

    Не понял фразу, «Затем в поле HTML загружаем javascript,». У этого элемента куча событий, но никакой загрузки в свойствах элемента нет.

    Подойдет этот способ для обычных форм?

    Reply ↓
  4. VitaliyCeban

    (3) Код из публикации помещается в макет с типом ТекстовыйДокумент.

    Затем в ПриСозданииНаСервере выполняете

    ПолеHTML = ПолучитьОбщийМакет(«МакетJavascript»).ПолучитьТекст();
    

    ПолеHTML это имя реквизита формы с типом «Строка», к которому привязано поле формы с видом «Поле HTML документа». Это вся загрузка.

    Обычные формы в веб-клиенте не доступны, соответственно, данный метод к ним неприменим. Замечу, что и при управляемых формах метод работает только в веб-клиенте, но не в тонком/толстом.

    Reply ↓
  5. Glebis

    Передо мной стоит задача: отключать сессии неактивных пользователей. Ваша статья натолкнула меня на мысль — определять период «не активности» по времени без движения мыши.

    Вопрос: можно ли добавив на обычную или управляемую форму (не веб интерфейс) рабочего стола элемент «ПолеHTMLДокумента» событием onmousemove сбрасывать таймер обработчика ожидания, который закрывает текущую сессию?

    Reply ↓
  6. VitaliyCeban

    (5) Нет, невозможно, так как в толстом/тонком клиенте omousemove будет отрабатывать движения мыши только внутри Поля HTML документа.

    Вам должно помочь http://infostart.ru/public/20593/ или http://infostart.ru/public/16441/

    Reply ↓
  7. the1

    Опять?

    Reply ↓
  8. VitaliyCeban

    (7) «Мы выживали как могли»…

    Reply ↓
  9. kungfufox

    Сделал как написали.

    Произошла ошибка:

    На этой странице произошла ошибка сценария.

    Не удалось задать свойство «onmousemove» ссылки,

    значение которой не определено или не является нулл.

    Reply ↓
  10. kungfufox

    править реестр не вариант.

    Может надо как то править js код? под старый IE

    или как решить?

    Reply ↓
  11. VitaliyCeban

    (10) Попробуйте добавить в тег head следующее:

    <met a http-equiv=»X-UA-Compatible» content=»IE=edge, 11, 9, 8″ />

    Удалите проблел между met a

    Предполагается наличие минимум Internet Explorer 8.

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *