首页 > 编程知识 正文

使用ONVIF同步NTP时间

时间:2023-11-20 23:22:41 阅读:294043 作者:RTMR

本文将介绍如何使用ONVIF来同步NTP时间。

一、ONVIF 和 NTP

ONVIF(开放式网络视频接口)规范定义了一套电子视频设备与网络视频管理系统之间的通信接口。而NTP(网络时间协议)是一种用于同步计算机时钟的协议。

在使用ONVIF设备进行视频监控的过程中,确保设备的时间与管理系统的时间是同步的非常重要。为了实现这个目标,可以使用ONVIF提供的Web服务接口和NTP协议来同步时间。

二、使用ONVIF的GetSystemDateAndTime方法查询设备时间

首先,我们需要获取设备当前的系统时间。使用ONVIF的GetSystemDateAndTime方法可以得到设备的当前时间。

$endpoint = 'http://192.168.1.100/onvif/device_service';
$username = 'admin';
$password = '123456';
$soap = new SoapClient(null, array(
    'location' => $endpoint,
    'uri' => 'urn:dnvif-org:services',
));

$auth = array(
    'UsernameToken' => array(
        'Username' => $username,
        'Password' => $password,
        'Nonce' => uniqid(),
        'Created' => date('Y-m-dTH:i:sZ', time())
    )
);
$header = new SoapHeader('http://www.onvif.org/ver10/device/wsdl', 'Security', $auth);
$soap->__setSoapHeaders(array($header));

$params = array();
$result = $soap->__soapCall('GetSystemDateAndTime', array($params));
$dateTimeType = $result->{'SystemDateAndTime'}->{'DateTimeType'};
$date = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Date'};
$time = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Time'};

三、使用NTP同步系统时间

一旦我们已经获取了设备的当前时间,我们可以使用NTP协议来调整系统时间。以下是使用PHP进行NTP时间同步的代码。

function setSystemTime($date, $time) {
    $dateTime = "$date $time";
    $ntpServer = 'time.windows.com'; // NTP服务器地址
    $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    $data = "10" . str_repeat("", 47); // 请求NTP时间
    socket_sendto($socket, $data, strlen($data), 0, $ntpServer, 123);
    socket_recvfrom($socket, $data, 48, 0, $ntpServer, $port);
    socket_close($socket);
    $leap = (ord($data[0]) >> 6) & 3;
    $version = (ord($data[0]) >> 3) & 7;
    $mode = ord($data[0]) & 7;
    $stratum = ord($data[1]);
    $poll = ord($data[2]);
    $precision = pow(2, (ord($data[3]) - 256));
    $delay = unpack("N", substr($data, 4, 4))[1] / 1000000;
    $dispersion = unpack("N", substr($data, 8, 4))[1] / 1000000;
    $reference = unpack("N", substr($data, 12, 4))[1] - 2208988800;
    $originate = unpack("N", substr($data, 16, 4))[1] - 2208988800;
    $receive = unpack("N", substr($data, 24, 4))[1] - 2208988800;
    $transmit = unpack("N", substr($data, 32, 4))[1] - 2208988800;
    $offset = ($receive - $originate + $transmit - time()) / 2;
    return date("Y-m-d H:i:s", $transmit + $offset); // 获取同步后的系统时间
}
$systemTime = setSystemTime($date, $time); // 设置系统时间

四、完整代码示例

$endpoint = 'http://192.168.1.100/onvif/device_service';
$username = 'admin';
$password = '123456';
$soap = new SoapClient(null, array(
    'location' => $endpoint,
    'uri' => 'urn:dnvif-org:services',
));

$auth = array(
    'UsernameToken' => array(
        'Username' => $username,
        'Password' => $password,
        'Nonce' => uniqid(),
        'Created' => date('Y-m-dTH:i:sZ', time())
    )
);
$header = new SoapHeader('http://www.onvif.org/ver10/device/wsdl', 'Security', $auth);
$soap->__setSoapHeaders(array($header));

$params = array();
$result = $soap->__soapCall('GetSystemDateAndTime', array($params));
$dateTimeType = $result->{'SystemDateAndTime'}->{'DateTimeType'};
$date = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Date'};
$time = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Time'};

function setSystemTime($date, $time) {
    $dateTime = "$date $time";
    $ntpServer = 'time.windows.com'; // NTP服务器地址
    $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    $data = "10" . str_repeat("", 47); // 请求NTP时间
    socket_sendto($socket, $data, strlen($data), 0, $ntpServer, 123);
    socket_recvfrom($socket, $data, 48, 0, $ntpServer, $port);
    socket_close($socket);
    $leap = (ord($data[0]) >> 6) & 3;
    $version = (ord($data[0]) >> 3) & 7;
    $mode = ord($data[0]) & 7;
    $stratum = ord($data[1]);
    $poll = ord($data[2]);
    $precision = pow(2, (ord($data[3]) - 256));
    $delay = unpack("N", substr($data, 4, 4))[1] / 1000000;
    $dispersion = unpack("N", substr($data, 8, 4))[1] / 1000000;
    $reference = unpack("N", substr($data, 12, 4))[1] - 2208988800;
    $originate = unpack("N", substr($data, 16, 4))[1] - 2208988800;
    $receive = unpack("N", substr($data, 24, 4))[1] - 2208988800;
    $transmit = unpack("N", substr($data, 32, 4))[1] - 2208988800;
    $offset = ($receive - $originate + $transmit - time()) / 2;
    return date("Y-m-d H:i:s", $transmit + $offset); // 获取同步后的系统时间
}
$systemTime = setSystemTime($date, $time); // 设置系统时间

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。