我已成功注册一个有效期为1小时的SipProfile。我在SIP服务器计算机上的Wireshark中看到REGISTER消息,已通过授权重新发送。
Brekeke立即回复状态为: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)之间!
随着时间的推移,我发现它不断地增长,我认为这可能与Ticks有关,所以我同时暴露了这两种情况并收集了以下统计信息(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的 magic 逃脱了我的注意,但比率却出乎意料地保持一致。从这一点来看,lExpire
看起来更像是对某个时间点的引用,而不是间隔,不是吗?
但是根据文档,我应该在没有任何缩放因子的情况下得到3600,对吗? 发生了什么事?!
更新(2019年1月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()
returns milliseconds since boot,包括睡眠时间。
保持UNIX / Linux / Java中的时间as number of seconds since epoch(1970-01-01T00:00:00Z)。
Wikipedia的页面显示当前Unix时间为1548450313(2019-01-25T21:05:13 + 00:00),仅是1000次( s -to- ms < / em>乘数!)的范围与我观察到的lExpire
值不同。最后一行mExpiryTime
的公式有点希望。.“ Eureka!”?
让我们检查它们是否符合“ 自时代以来的毫秒数”理论:
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
(记录在日志中)之间的差异可以忽略不计-在ms范围内!
我实际上很喜欢被赋予过期矩 而不是 duration 的想法(需要将其添加到未定义的 起点)。正要回答我的问题。
但是,仍有一些未解决的未解之谜:
.onRegistrationDone(session, duration)
的所有调用都指定duration
,而不是mExpiryTime
。
有常量定义(EXPIRY_TIME = 3600,SHORT_EXPIRY_TIME = 10,MIN_EXPIRY_TIME = 60)以及duration
与它们的比较。
两者之间的取值范围完全不同(3600与15万亿)。lExpire
应该是将来的1小时,而不是< em>现在 !有什么想法吗?