• 🔥 Бесплатный курс от Академии Кодебай: «Анализ защищенности веб-приложений»

    🛡 Научитесь находить и использовать уязвимости веб-приложений.
    🧠 Изучите SQLi, XSS, CSRF, IDOR и другие типовые атаки на практике.
    🧪 Погрузитесь в реальные лаборатории и взломайте свой первый сайт!
    🚀 Подходит новичкам — никаких сложных предварительных знаний не требуется.

    Доступ открыт прямо сейчас Записаться бесплатно

Секундомер

  • Автор темы Автор темы Serduko
  • Дата начала Дата начала
S

Serduko

Есть база для проведения тестов, срок сдачи тестов ограничен временем. Как лучше реализовать отображение времени оставшегося для сдачи теста?
 
Два варианта в голову лезут.
1. Агентом каждые 5 минут пробегаться по документам и вычислять оставшееся время
2. Агентом каждые 5 минут в notes.ini перезаписывать текущее время, получать его в столбце вьюшки @Environment("CurrentTime")

Первый, наверное лучше, особенно, если перебирать не все документы, а брать коллекцию только из тех, которые еще не просрочены. Во втором варианте, по-моему надо каждый раз перестраивать индекс вьюшки, хотя могу ошибаться.
 
Если нужно только визуальное отображение на форме то JavaScript должен прекрасно с этим справится.
 
Почитай в хелпе про NotesTimer и пример посмотри.
 
См. тему Background. Внутри агента можно брать серверное время, допустим раз в 10 секунд.
 
А каким образом брать время с сервера? На сколько точный этот NotesTime, у меня с интервалом 1 сек в течение 30 сек опоздал на 5?
 
Serduko
а потому что не надо пользоваться этим таймером для отчета времени, им надо пользоваться для инициализация скрипта который получает серверное время.
получать время можно агентом, например так @Now( flags ; serverNames )
 
А каким образом брать время с сервера?
Поиск что ли перестал работать?
Создайте документ в БД (она на сервере ж находится?) и возьмите дату создания. @Now(flags; serverNames) глючит, об этом писали здесь, ищите.

Добавлено:
На сколько точный этот NotesTime, у меня с интервалом 1 сек в течение 30 сек опоздал на 5?
Это именно "убегание" времени, а не расхождение времени между клиентом и сервером?
 
Serduko
Ещё подумал... Достаточно первый раз создать документ и взять дату и время, а затем просто прибавлять по секунде, т.к. секунда прибавляется, что на клиенте, что на сервере одинаково ;)
Время вперёд убегает потому, что при создании дока UNID генерится на определённую секунду, а если до создаётся в пределах той же секунды, то чтобы UNID для него был уникальным, он рассчитывается по следующей секунде. Об этом было подробно когда-то на форуме Интертраста.
Лучше, чтобы прибавлять >= 1 секунды, тогда время убегать не должно. Но иногда всё-таки будет, т.к. на сервере/клиентах могут работать другие агенты/люди, которые могут в то же время создавать документы.
 
Почитай в хелпе про NotesTimer и пример посмотри.
to author of post:

еще не забудь при использовании NotesTimer-а
таймер останавливается, если на документе появится диалоговое окно, допустим при открытии свойств дока.
поэтому разумнее будет

1) запомнить серверное время, когда начался тест, и скинуть его в NotesdateTime
2) потом каждый раз NotesTimer-ом получать разницу в секундах между исходным временем и текущем
3) если эти полученные секунды превышают или равны, отведенному времени, автоматом останавливаешь тест.
 
С сервера время брать не обязательно.
startTic = Getthreadinfo(6) берет "тики" с сотворения мира и они не меняются при изменении времени в операционке.

Декларируйте startTic глобально, вычисляйте его, например, в PostOpen и используйте как опорное.

И потом, лучше использовать JS:
Например на "кнопочках" - в OnLoad нажимаете программно кнопочку MyClock
window.document.forms[0].MyClock.click()
а кнопочка MyClock нажимает саму себя с интервалом в 1сек. {setInterval("window.document.forms[0].MyClock.click()",1000)}, корректирует значение startTic, выводит значение времени в какое-нибудь поле для показа и проверяет не истекло ли время (с соответствующими действиями).

Если хочется в LS, то нажимаем на кнопочку например так:
Dim ws As New NotesUIWorkspace
Call ws.URLOpen( "java script: document.forms[0].MyClock.click();" )
 
Спасибо всем, я реализовал в диалоге, примерно так (конечно код сыроват, все делалось впопыхах, но аттестация прошла успешно, теперь можно спокойно дорабатывать базу):

Код:
Sub StartExam(StartForm As NotesDocument)
Dim ws As New NotesUIWorkspace
Dim Qdoc As NotesDocument
Dim Adoc As NotesDocument
Dim NextAdoc As NotesDocument

If Len(CStr(SectionDoc.SectionTime(0))) <> 0 Then
If SectionDoc.SectionTime(0) <> 0 Then
MaxTime = SectionDoc.SectionTime(0)
startTime = Now
elapsedTime = CDat(0)
Set elapsedTimer = New NotesTimer(1, "Время сдачи раздела")
On Event Alarm From elapsedTimer Call elapsedTimerHandler
End If
End If

Set Qdoc = GetQuestionDoc(0)
If Qdoc Is Nothing Then Exit Sub
Set Adoc = GetAnswerDoc(Qdoc, "", StartForm.UserUN(0))
NextAnswer:
Adoc.OpenedInDialog	= 1
If elapsedTimer.Enabled Then Adoc.TimeLeft = GetRemainingTime
If ws.DialogBox (Adoc.Form(0), True, True, True, False, False, False, "Вопрос №" + CStr(Adoc.QuestionIndex(0)),_
Adoc, False, True) Then
...

Код:
Function GetRemainingTime As Integer
If elapsedTime = CDat(0) Then
GetRemainingTime = MaxTime
Else
GetRemainingTime = MaxTime - CInt(Format(elapsedTime - startTime,"nn"))
End If
End Function

Код:
Sub elapsedTimerHandler(Source As NotesTimer)
Dim temp As Variant
temp = Evaluate("@Now([ServerTime] : [LocalTimeOnError]; @ServerName)")
elapsedTime = temp(0)
End Sub
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab