Я успешно регистрирую SipProfile с истечением 1 часа. Я вижу сообщение REGISTER в Wireshark на компьютере SIP-сервера, повторно отправленное с авторизацией.
Brekeke немедленно отвечает с STATUS: 200 OK, возвращая 'Expires: 3600'.
Обе документы Xamarin и Android говорят мне, что lExpire
должен иметь длительность в секундах до истечения срока регистрации , поэтому он представляет интервал. Я хочу выставить полученные значения, поэтому умножьте на TimeSpan.TicksPerSecond
(чтобы преобразовать в TimeSpan), 3600 приведет к 0.01:00:00
:
void ISipRegistrationListener.OnRegistrationDone( string lclPrfUri, long lExpire )
{
long l= DateTime.Now.Ticks;
double d= (double)l / lExpire;
string s= string.Format( "RegSucced( '{0}', {1} ), {2}, {3}", lclPrfUri, lExpire,
new TimeSpan( lExpire * TimeSpan.TicksPerSecond )
.ToString( "d\\.hh\\:mm\\:ss" ), d );
..
}
Но я получаю lExpire
значения в диапазоне 1,5 триллионов (1'541'195'345'242)!
Поскольку я видел это постоянно , растущее со временем, я подумал, что это может быть связано с тиками, поэтому я выставил оба и собрал следующую статистику (H == T + 1 час - ожидаемое истечение срока):
# DT.Now.Ticks (T) lExpire (E) T/E ratio T+36000000000 (H) H/E ratio
1 636767624266839520 1541183611836 413167.918 636767660266839520 413167.941
2 636767669188704010 1541188122398 413166.738 636767705188704010 413166.761
3 636767670260843180 1541188229643 413166.710 636767706260843180 413166.733
4 636767670974718350 1541188301027 413166.691 636767706974718350 413166.715
5 636767693193745790 1541190522922 413166.110 636767729193745790 413166.133
И отношения выглядят удивительно непротиворечивыми, хотя волшебство из 413166 ускользает от меня .. И из этого lExpire
больше похоже на ссылку на момент времени, чем на интервал нет?
Но согласно документам я должен получить 3600 без каких-либо масштабных коэффициентов, верно? Что происходит ??!
ОБНОВЛЕНИЕ (2019-Jan-25)
Наконец-то подошел ближе к ответу. Копая исходные файлы Android (например, https://android.googlesource.com/platform/frameworks/base/+/431bb2269532f2514861b908d5fafda8fa64da79/voip/java/com/android/server/sip/SipService.java) я нашел следующий фрагмент:
@Override
public void onRegistrationDone(ISipSession session, int duration) {
if (DEBUG) Log.d(TAG, "onRegistrationDone(): " + session);
synchronized (SipService.this) {
if (notCurrentSession(session)) return;
mProxy.onRegistrationDone(session, duration);
if (duration > 0) {
mSession.clearReRegisterRequired();
mExpiryTime = SystemClock.elapsedRealtime() + (duration * 1000);
..
SystemClock.elapsedRealtime()
возвращает миллисекунды с момента загрузки , включая время, проведенное во сне.
Время в UNIX / Linux / Java сохраняется как количество секунд с начала эпохи (1970-01-01T00: 00: 00Z).
Страница Википедии показывает текущее время Unix как 1548450313 (2019-01-25T21: 05: 13 + 00: 00), что составляет всего 1000 раз ( с - до - мс множитель!) отличается в диапазоне от lExpire
значений, которые я наблюдаю. Формула для mExpiryTime
в последней строке как бы вселяет надежду .. "Эврика!"?
Давайте проверим, соответствуют ли они теории " # мс с эпохи ":
DateTime dtEpoch = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc );
void ISipRegistrationListener.OnRegistrationDone( string lclPrfUri, long lExpire )
{
DateTime dt = dtEpoch.AddMilliseconds( lExpire ).ToLocalTime( );
string s= string.Format( "RegSucced( '{0}', {1}, {2} )", lclPrfUri, lExpire,
dt.ToString( "yyyy-MM-dd HH:mm:ss.fff" ) );
..
}
Вчерашние скриншоты - с этим дополнением (пурпурные стрелки отмечают выставленные значения):
Как видите, разница между lExpire
, преобразованным во время, и DateTime.Now
(записанным в журнале) незначительна - в диапазоне мс!
Мне действительно нравится идея получить срок действия момент вместо продолжительность (который должен быть добавлен к undefined отправная точка). Собирался ответить на мой вопрос ..
Но все же, есть еще неразрешенные загадки :
- Почему в документации сказано, что аргумент имеет значение длительность в секундах ?
Xamarin может просто копировать документы Android, но источник неверен !
Это действительно, как хромые разработчики Android? Считай, что это должно быть риторически ((..
Кто-нибудь заботится, что запрошенный период истечения может быть превзойден [ down ] сервером PBX / SIP, и, таким образом, он должен перерегистрировать чаще ?
- Все вызовы
.onRegistrationDone(session, duration)
в исходных файлах указывают duration
, а не mExpiryTime
.
Существуют постоянные определения (EXPIRY_TIME = 3600, SHORT_EXPIRY_TIME = 10, MIN_EXPIRY_TIME = 60) и сравнения duration
с этими ..
Диапазон значений резко отличается между ними (3600 против 15 трлн).
Как / где mExpiryTime ( момент истечения ) превращает его в аргумент моего метода?
- мс с момента загрузки и с (или мс) с эпохи все еще сильно отличаются, что делает такой настройкой?
- и, наконец, спрашивая об истечении 1 часа и получив его в ответе OK от SIP-сервера, я ожидаю, что это будет отражено и здесь, поэтому
lExpire
должно составлять 1 час в будущем, а не Теперь !!
Есть идеи?