iD学习 - 心跳
程序员文章站
2022-05-03 19:19:25
...
心跳
心跳顾名思义,就是以固定的频率向其他节点汇报当前节点状态的方式。收到心跳,一般可以认为一个节点和现在的网络拓扑是良好的。当然,心跳汇报时,一般也会携带一些附加的状态、元数据信息,以便管理。
代码说明
iD调用后台接口代码在/modules/services/osm.js里。获取后台状态方法如下:
// Fetch the status of the OSM API
// GET /api/capabilities
status: function(callback) {
var url = urlroot + '/api/capabilities';
var errback = wrapcb(this, done, _connectionID);
d3_xml(url)
.then(function(data) {
errback(null, data);
})
.catch(function(err) {
errback(err.message);
});
function done(err, xml) {
if (err) {
// the status is null if no response could be retrieved
return callback(err, null);
}
// update blacklists
var elements = xml.getElementsByTagName('blacklist');
var regexes = [];
for (var i = 0; i < elements.length; i++) {
var regex = elements[i].getAttribute('regex'); // needs unencode?
if (regex) {
regexes.push(regex);
}
}
if (regexes.length) {
_blacklists = regexes;
}
if (_rateLimitError) {
return callback(_rateLimitError, 'rateLimited');
} else {
var apiStatus = xml.getElementsByTagName('status');
var val = apiStatus[0].getAttribute('api');
return callback(undefined, val);
}
}
}
iD通过OSM的/api/capabilities接口获取服务器状态。如获取不到则显示如下:
OSM API共有4种异常状态,显示信息1如下:
"osm_api_status": {
"message": {
"error": "无法连接到 OpenStreetMap API。你的编辑在本地是安全的。请检查你的网络连接。",
"offline": "OpenStreetMap API 当前离线。你的编辑在本地是安全的。请稍后再来。",
"readonly": "OpenStreetMap API 当前为只读状态。你可以继续编辑,但需要等待一段时间才能保存。",
"rateLimit": "OpenStreetMap API 限制了匿名连接。你可以通过登录来解决此问题。"
},
"retry": "重试"
}
用于显示修改状态显示的代码在/modules/ui/status.js
import _throttle from 'lodash-es/throttle';
import { event as d3_event } from 'd3-selection';
import { t } from '../util/locale';
import { svgIcon } from '../svg/icon';
export function uiStatus(context) {
var osm = context.connection();
return function(selection) {
if (!osm) return;
function update(err, apiStatus) {
selection.html('');
if (err) {
if (apiStatus === 'connectionSwitched') {
// if the connection was just switched, we can't rely on
// the status (we're getting the status of the previous api)
return;
} else if (apiStatus === 'rateLimited') {
selection
.text(t('osm_api_status.message.rateLimit'))
.append('a')
.attr('class', 'api-status-login')
.attr('target', '_blank')
.call(svgIcon('#iD-icon-out-link', 'inline'))
.append('span')
.text(t('login'))
.on('click.login', function() {
d3_event.preventDefault();
osm.authenticate();
});
} else {
// don't allow retrying too rapidly
var throttledRetry = _throttle(function() {
// try loading the visible tiles
context.loadTiles(context.projection);
// manually reload the status too in case all visible tiles were already loaded
osm.reloadApiStatus();
}, 2000);
// eslint-disable-next-line no-warning-comments
// TODO: nice messages for different error types
selection
.text(t('osm_api_status.message.error') + ' ')
.append('a')
// let the user manually retry their connection directly
.text(t('osm_api_status.retry'))
.on('click.retry', function() {
d3_event.preventDefault();
throttledRetry();
});
}
} else if (apiStatus === 'readonly') {
selection.text(t('osm_api_status.message.readonly'));
} else if (apiStatus === 'offline') {
selection.text(t('osm_api_status.message.offline'));
}
selection.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
}
osm.on('apiStatusChange.uiStatus', update);
// reload the status periodically regardless of other factors
window.setInterval(function() {
osm.reloadApiStatus();
}, 90000);
// load the initial status in case no OSM data was loaded yet
osm.reloadApiStatus();
};
}
系统每隔90秒获取一次状态。
接口返回值
OSM API 返回值如下:
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
<api>
<version minimum="0.6" maximum="0.6"/>
<area maximum="0.25"/>
<note_area maximum="25"/>
<tracepoints per_page="5000"/>
<waynodes maximum="2000"/>
<changesets maximum_elements="10000"/>
<timeout seconds="300"/>
<status database="online" api="online" gpx="online"/>
</api>
<policy>
<imagery>
<blacklist regex=".*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*"/>
<blacklist regex="http://xdworld\.vworld\.kr:8080/.*"/>
<blacklist regex=".*\.here\.com[/:].*"/>
</imagery>
</policy>
</osm>
其中status为api状态,正常值为online,代码中获取的是apiStatus[0].getAttribute(‘api’)的值,因此判断的是status中api的值,其他属性还不清楚使用的方法。
黑名单
接口返回值中的黑名单,用于限制背景影响显示,凡是符合黑名单正则表达式的链接都不会加载。在/modules/svg/data.js和/modules/renderer/background.js里都有使用。
// test source against OSM imagery blacklists..
var osm = context.connection();
if (osm) {
var blacklists = osm.imageryBlacklists();
var fail = false;
var tested = 0;
var regex;
for (var i = 0; i < blacklists.length; i++) {
try {
regex = new RegExp(blacklists[i]);
fail = regex.test(val);
tested++;
if (fail) break;
} catch (e) {
/* noop */
}
}
// ensure at least one test was run.
if (!tested) {
regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
fail = regex.test(val);
}
}
-
iD支持多语言,字典放在/dist/locales目录下,简体中文为zh-CN.json文件。 ↩︎
上一篇: oracle中字段类型长度
下一篇: MySQL基础学习笔记02