李勇

1.增加Server.js选点模块,Server.js本地服务器点

2.增加选点流程
此 diff 太大无法显示。
root: true
env:
es6: true
node: true
browser: true
mocha: true
ecmaFeatures:
modules: true
extends:
"airbnb"
rules:
quotes: 0
func-names: 0
comma-dangle: 0
no-new-func: 0
no-eq-null: 0
no-param-reassign: 0
... ...
.DS_Store
*.log
node_modules
src
test
examples
coverage
... ...
language: node_js
node_js:
- "iojs"
... ...
1.0.6 / 2017-2-3
==================
* update typescript config
1.0.5 / 2016-12-29
==================
* update typescript support
1.0.4 / 2016-12-23
==================
* add typescript support
1.0.3 / 2016-12-04
==================
* add examples index-ie8.html
* remove `es6-promise` dependent
1.0.2 / 2016-09-26
==================
* Use original url when Request error
1.0.1 / 2016-08-14
==================
* Format code
* Update Readme
1.0.0 / 2015-11-19
==================
* Remove Bower support
* Add jsonpCallback and jsonpCallbackFunction as options
0.9.2 / 2015-08-11
==================
* Remove global export of fetchJsonp
0.9.1 / 2015-08-11
==================
* Update removeScript fix legacy IE
... ...
# Maintaining
## Releasing a new version
This project follows [semver](http://semver.org/). So if you are making a bug
fix, only increment the patch level "1.0.x". If any new files are added, a
minor version "1.x.x" bump is in order.
### Make a release commit
To prepare the release commit:
1. Change the npm [package.json](https://github.com/camsong/fetch-jsonp/blob/master/package.json)
`version` value to match.
2. Make a single commit with the description as "Fetch JSONP 1.x.x".
3. Finally, tag the commit with `v1.x.x`.
```
$ git pull
$ vim package.json
$ git add package.json
$ git commit -m "Fetch JSONP 1.x.x"
$ git tag v1.x.x
$ git push
$ git push --tags
```
... ...
# Fetch JSONP [![Build Status](https://travis-ci.org/camsong/fetch-jsonp.svg)](https://travis-ci.org/camsong/fetch-jsonp) [![npm version](https://badge.fury.io/js/fetch-jsonp.svg)](http://badge.fury.io/js/fetch-jsonp) [![npm downloads](https://img.shields.io/npm/dm/fetch-jsonp.svg?style=flat-square)](https://www.npmjs.com/package/fetch-jsonp)
JSONP is NOT supported in standard Fetch API, https://fetch.spec.whatwg.org.
fetch-jsonp provides you same API to fetch JSONP like naive Fetch, also comes
with global `fetchJsonp` function.
If you need a `fetch` polyfill for old browsers, try [github/fetch](http://github.com/github/fetch).
## Installation
You can install with `npm`.
```
npm install fetch-jsonp
```
## Promise Polyfill for IE
IE8/9/10/11 does not support [ES6 Promise](https://tc39.github.io/ecma262/#sec-promise-constructor), run this to polyfill the global environment at the beginning of your application.
```js
require('es6-promise').polyfill();
```
## Usage
The `fetch-jsonp` function supports any HTTP method. We'll focus on GET and POST
example requests.
### Fetch JSONP in simple way
```javascript
fetchJsonp('/users.jsonp')
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
```
### Set JSONP callback name, default is 'callback'
```javascript
fetchJsonp('/users.jsonp', {
jsonpCallback: 'custom_callback'
})
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
```
### Set JSONP request timeout, default is 5000ms
```javascript
fetchJsonp('/users.jsonp', {
timeout: 3000,
jsonpCallback: 'custom_callback'
})
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
```
### Caveats
You need to call `.then(function(response) { return response.json(); })` in order
to keep consistent with Fetch API.
## Browser Support
![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)
--- | --- | --- | --- | --- |
Latest ✔ | Latest ✔ | 8+ ✔ | Latest ✔ | 6.1+ ✔ |
# License
MIT
# Acknowledgement
Thanks to [github/fetch](https://github.com/github/fetch) for bring Fetch to old browsers.
... ...
(function (global, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports', 'module'], factory);
} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
factory(exports, module);
} else {
var mod = {
exports: {}
};
factory(mod.exports, mod);
global.fetchJsonp = mod.exports;
}
})(this, function (exports, module) {
'use strict';
var defaultOptions = {
timeout: 5000,
jsonpCallback: 'callback',
jsonpCallbackFunction: null
};
function generateCallbackFunction() {
return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
}
// Known issue: Will throw 'Uncaught ReferenceError: callback_*** is not defined'
// error if request timeout
function clearFunction(functionName) {
// IE8 throws an exception when you try to delete a property on window
// http://stackoverflow.com/a/1824228/751089
try {
delete window[functionName];
} catch (e) {
window[functionName] = undefined;
}
}
function removeScript(scriptId) {
var script = document.getElementById(scriptId);
document.getElementsByTagName('head')[0].removeChild(script);
}
function fetchJsonp(_url) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
// to avoid param reassign
var url = _url;
var timeout = options.timeout || defaultOptions.timeout;
var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
var timeoutId = undefined;
return new Promise(function (resolve, reject) {
var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
var scriptId = jsonpCallback + '_' + callbackFunction;
window[callbackFunction] = function (response) {
resolve({
ok: true,
// keep consistent with fetch API
json: function json() {
return Promise.resolve(response);
}
});
if (timeoutId) clearTimeout(timeoutId);
removeScript(scriptId);
clearFunction(callbackFunction);
};
// Check if the user set their own params, and if not add a ? to start a list of params
url += url.indexOf('?') === -1 ? '?' : '&';
var jsonpScript = document.createElement('script');
jsonpScript.setAttribute('src', '' + url + jsonpCallback + '=' + callbackFunction);
jsonpScript.id = scriptId;
document.getElementsByTagName('head')[0].appendChild(jsonpScript);
timeoutId = setTimeout(function () {
reject(new Error('JSONP request to ' + _url + ' timed out'));
clearFunction(callbackFunction);
removeScript(scriptId);
}, timeout);
});
}
// export as global function
/*
let local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
local.fetchJsonp = fetchJsonp;
*/
module.exports = fetchJsonp;
});
\ No newline at end of file
... ...
declare function fetchJsonp(url: string, options?: fetchJsonp.Options): Promise<fetchJsonp.Response>;
declare namespace fetchJsonp {
interface Options {
timeout?: number;
jsonpCallback?: string;
jsonpCallbackFunction?: string;
}
interface Response {
json(): Promise<any>;
json<T>(): Promise<T>;
ok: boolean;
}
}
export = fetchJsonp;
... ...
{
"_args": [
[
"fetch-jsonp",
"D:\\work\\McuClient"
]
],
"_from": "fetch-jsonp@latest",
"_id": "fetch-jsonp@1.0.6",
"_inCache": true,
"_installable": true,
"_location": "/fetch-jsonp",
"_nodeVersion": "5.7.1",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/fetch-jsonp-1.0.6.tgz_1486087842804_0.46444737794809043"
},
"_npmUser": {
"email": "neosoyn@gmail.com",
"name": "camsong"
},
"_npmVersion": "3.6.0",
"_phantomChildren": {},
"_requested": {
"name": "fetch-jsonp",
"raw": "fetch-jsonp",
"rawSpec": "",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/fetch-jsonp/-/fetch-jsonp-1.0.6.tgz",
"_shasum": "8d2ae174ed14108292f025f43fa07d2078de6736",
"_shrinkwrap": null,
"_spec": "fetch-jsonp",
"_where": "D:\\work\\McuClient",
"author": {
"name": "Cam Song"
},
"bugs": {
"url": "https://github.com/camsong/fetch-jsonp/issues"
},
"dependencies": {},
"description": "Fetch JSONP like a boss using Fetch API",
"devDependencies": {
"babel": "^5.8.21",
"babel-core": "^5.8.21",
"babel-eslint": "^4.0.5",
"chai": "^3.2.0",
"eslint": "^1.1.0",
"eslint-config-airbnb": "^0.0.7",
"eslint-plugin-react": "^3.2.1",
"mocha": "^2.2.5"
},
"directories": {},
"dist": {
"shasum": "8d2ae174ed14108292f025f43fa07d2078de6736",
"tarball": "https://registry.npmjs.org/fetch-jsonp/-/fetch-jsonp-1.0.6.tgz"
},
"gitHead": "3b1be53776fa36a548fbf2aa16063c27ca318661",
"homepage": "https://github.com/camsong/fetch-jsonp#readme",
"keywords": [
"fetch",
"jsonp",
"github fetch",
"ajax"
],
"license": "MIT",
"main": "build/fetch-jsonp.js",
"maintainers": [
{
"email": "neosoyn@gmail.com",
"name": "camsong"
}
],
"name": "fetch-jsonp",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/camsong/fetch-jsonp.git"
},
"scripts": {
"build": "babel src/ --modules umd --out-dir build",
"clean": "rm -rf build",
"lint": "eslint src/ test/",
"test": "mocha --compilers js:babel/register --recursive --ui bdd --reporter spec"
},
"version": "1.0.6"
}
... ...
# exclude all
/*
# project structure
!/src/
!/etc/
!/doc/
!/test/
!/dist/
# project files
!.gitignore
!README.md
!package.json
!LICENSE
!webpack.config.umd.js
... ...
iphunter
to hunt a fatest http response.
# usage
iphunter(iplist,check_call_back[,timeout]);
```javascript
import iphunter from 'iphunter';
iphunter([
'192.168.99.199',
'baidu.com',
'aliyun.com',
'qq.com',
'192.168.99.100',
'127.0.0.0:8080',
'192.168.1.48:8080',
'localhost:8080'
], function (fatest_ip_response) {
if(!fatest_ip_response) return console.error('nothing!');
console.log('done -> ', fatest_ip_response);
},3000)
```
... ...
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>UMD PLAYGROUND</title></head><body><div id="stage"></div><script type="text/javascript" src="main.js"></script></body></html>
\ No newline at end of file
... ...
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.iphunter=t():e.iphunter=t()}(this,function(){return function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={exports:{},id:i,loaded:!1};return e[i].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3e3;if(!(e&&e.length&&t))throw new Error("ips and callback are required.");new o(e,t,n)}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}();t.default=i;var o=function(){function e(t,i,r){n(this,e),this.ip="",this.ipcallback=i,this.timeoutId=null,this.reqsCache=[];for(var o=0;o<t.length;o++)this.reqsCache.push(this.send(t[o],r-10));this.timeoutId=setTimeout(this.notify.bind(this),r)}return r(e,[{key:"clearAll",value:function(){this.reqsCache&&this.reqsCache.length&&this.reqsCache.forEach(function(e){e.abort()}),clearTimeout(this.timeoutId),this.ip="",this.ipcallback=null,this.timeoutId=null,this.reqsCache=[]}},{key:"clearReq",value:function(e){this.reqsCache.splice(this.reqsCache.indexOf(e),1)}},{key:"notify",value:function(){this.ipcallback(this.ip),this.clearAll()}},{key:"send",value:function(e,t){var n=this,i=new XMLHttpRequest;return i.open("HEAD","//"+e+"/?_="+Date.now()),i.timeout=t,i.onload=function(){n.ip=e,n.clearReq(i),i.onload=null,n.notify()},i.ontimeout=function(){n.clearReq(i),i.ontimeout=null},i.onerror=function(){n.clearReq(i),i.onerror=null},i.onabort=function(){n.clearReq(i),i.onabort=null},i.send(),i}}]),e}();(function(){"undefined"!=typeof __REACT_HOT_LOADER__&&(__REACT_HOT_LOADER__.register(o,"IpHunter","/Users/AlexWang/ws/iphunter/src/main.js"),__REACT_HOT_LOADER__.register(i,"check","/Users/AlexWang/ws/iphunter/src/main.js"))})()}])});
\ No newline at end of file
... ...
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>UMD PLAYGROUND</title></head><body><div id="stage"></div><script type="text/javascript" src="test.js"></script></body></html>
\ No newline at end of file
... ...
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.iphunter=t():e.iphunter=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(2)},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3e3;if(!(e&&e.length&&t))throw new Error("ips and callback are required.");new r(e,t,n)}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}();t.default=o;var r=function(){function e(t,o,i){n(this,e),this.ip="",this.ipcallback=o,this.timeoutId=null,this.reqsCache=[];for(var r=0;r<t.length;r++)this.reqsCache.push(this.send(t[r],i-10));this.timeoutId=setTimeout(this.notify.bind(this),i)}return i(e,[{key:"clearAll",value:function(){this.reqsCache&&this.reqsCache.length&&this.reqsCache.forEach(function(e){e.abort()}),clearTimeout(this.timeoutId),this.ip="",this.ipcallback=null,this.timeoutId=null,this.reqsCache=[]}},{key:"clearReq",value:function(e){this.reqsCache.splice(this.reqsCache.indexOf(e),1)}},{key:"notify",value:function(){this.ipcallback(this.ip),this.clearAll()}},{key:"send",value:function(e,t){var n=this,o=new XMLHttpRequest;return o.open("HEAD","//"+e+"/?_="+Date.now()),o.timeout=t,o.onload=function(){n.ip=e,n.clearReq(o),o.onload=null,n.notify()},o.ontimeout=function(){n.clearReq(o),o.ontimeout=null},o.onerror=function(){n.clearReq(o),o.onerror=null},o.onabort=function(){n.clearReq(o),o.onabort=null},o.send(),o}}]),e}();(function(){"undefined"!=typeof __REACT_HOT_LOADER__&&(__REACT_HOT_LOADER__.register(r,"IpHunter","/Users/AlexWang/ws/iphunter/src/main.js"),__REACT_HOT_LOADER__.register(o,"check","/Users/AlexWang/ws/iphunter/src/main.js"))})()},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}var i=n(1),r=o(i);(0,r.default)(["192.168.99.199","baidu.com","aliyun.com","qq.com","192.168.99.100","127.0.0.0:8080","192.168.1.48:8080","localhost:8080"],function(e){console.log("done -> ",e)});(function(){"undefined"==typeof __REACT_HOT_LOADER__})()}])});
\ No newline at end of file
... ...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UMD PLAYGROUND</title>
</head>
<body>
<div id="stage"></div>
</body>
</html>
... ...
{
"_args": [
[
"iphunter",
"D:\\work\\McuClient"
]
],
"_from": "iphunter@latest",
"_id": "iphunter@1.0.6",
"_inCache": true,
"_installable": true,
"_location": "/iphunter",
"_nodeVersion": "6.9.1",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/iphunter-1.0.6.tgz_1488779370023_0.8911087329033762"
},
"_npmUser": {
"email": "1669499355@qq.com",
"name": "xinwangwang"
},
"_npmVersion": "3.10.8",
"_phantomChildren": {},
"_requested": {
"name": "iphunter",
"raw": "iphunter",
"rawSpec": "",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/iphunter/-/iphunter-1.0.6.tgz",
"_shasum": "6b7559d73002bd8cc93d558a604d64518d180840",
"_shrinkwrap": null,
"_spec": "iphunter",
"_where": "D:\\work\\McuClient",
"author": {
"name": "AlexWang"
},
"dependencies": {},
"description": "to hunt a fatest http response.",
"devDependencies": {},
"directories": {
"doc": "doc",
"test": "test"
},
"dist": {
"shasum": "6b7559d73002bd8cc93d558a604d64518d180840",
"tarball": "https://registry.npmjs.org/iphunter/-/iphunter-1.0.6.tgz"
},
"gitHead": "c9958f825f514736bd0451f632c227db4bf0a7b7",
"keywords": [
"ipcheck"
],
"license": "MIT",
"main": "dist/main.js",
"maintainers": [
{
"email": "1669499355@qq.com",
"name": "xinwangwang"
}
],
"name": "iphunter",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"scripts": {
"test": "test/index.js"
},
"version": "1.0.6",
"wbp": {
"build": "dist/",
"entries": {
"main": "./src/main.js",
"test": "./test/test.js"
},
"project": "umd",
"source": "src/"
}
}
... ...
class IpHunter {
constructor(ips, callback, timeout) {
this.ip = '';
this.ipcallback = callback;
this.timeoutId = null;
this.reqsCache = [];
for (let i = 0; i < ips.length; i++) {
this.reqsCache.push(this.send(ips[i], timeout - 10));
}
this.timeoutId = setTimeout(this.notify.bind(this), timeout);
}
clearAll() {
if (this.reqsCache && this.reqsCache.length) {
this.reqsCache.forEach((req) => {
req.abort();
})
}
clearTimeout(this.timeoutId);
this.ip = '';
this.ipcallback = null;
this.timeoutId = null;
this.reqsCache = [];
}
clearReq(req) {
this.reqsCache.splice(this.reqsCache.indexOf(req), 1);
}
notify() {
this.ipcallback(this.ip);
this.clearAll();
}
send(pip, timeout) {
const req = new XMLHttpRequest();
req.open('HEAD', `//${pip}/?_=${Date.now()}`);
req.timeout = timeout;
req.onload = () => {
this.ip = pip;
this.clearReq(req);
req.onload = null;
this.notify();
}
req.ontimeout = () => {
this.clearReq(req);
req.ontimeout = null;
}
req.onerror = () => {
this.clearReq(req);
req.onerror = null;
}
req.onabort = () => {
this.clearReq(req);
req.onabort = null;
}
req.send();
return req
}
}
/**
* ips check
* @param {array} ips
* @param {number} callback
* @return {null}
*/
export default function check(ips, callback, timeout = 3000) {
if (!(ips && ips.length && callback)) throw new Error('ips and callback are required.');
new IpHunter(ips, callback, timeout);
}
... ...
import check from 'main.js';
check([
'192.168.99.199',
'baidu.com',
'aliyun.com',
'qq.com',
'192.168.99.100',
'127.0.0.0:8080',
'192.168.1.48:8080',
'localhost:8080'
], function (ip) {
console.log('done -> ', ip);
})
... ...
module.exports = function (umdConf) {
umdConf.devServer.host = '0.0.0.0';
umdConf.webpackFeatures.enableEntryHTML();
umdConf.output.publicPath = '';
if (umdConf.devMode) {
umdConf.webpackFeatures.enableEntryHot('test');
} else {
umdConf.webpackFeatures.enableUglifyJs({
comments: false
});
}
// console.log(umdConf);
};
... ...
... ... @@ -5,6 +5,7 @@ require('string.fromcodepoint');
import Emiter from './Emiter';
import Sass from 'Sass';
import ServerCheck from 'ServerCheck';
import Mcu from 'mcu';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
... ... @@ -26,6 +27,7 @@ let _sdkInfo={"version":"v.1.0.1","author":"www.3mang.com"};
//APE
let _sass;
let _serverCheck;
let _mcu ;
let _confer_ape;
let _chat_ape;
... ... @@ -34,6 +36,7 @@ let _audio_ape;
let _doc_ape;
let _whiteboard_ape;
//MCUClient 外部实例化主类
export default class MessageEntrance extends Emiter {
constructor() {
... ... @@ -53,12 +56,18 @@ export default class MessageEntrance extends Emiter {
_sass.on('*', (type, data) => this._emit(type, data));
_sass.on(_sass.SUCCESS, this._sassJoinSuccessHandler.bind(this));//通过SASS平台验证(密码和MD5)
_sass.on(_sass.CLASS_INIT_SUCCESS, this._sassInitSuccessHandler.bind(this));//获取会议初始化信息
_sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取会议的基本信息
//_sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取会议的基本信息
_sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this));//获取会议的最全信息和历史保存的数据
_sass.on(_sass.CLASS_SAVE_STATUS_INFO_SUCCESS, this._sassSaveClassStatusInfoSuccessHandler.bind(this));//保存会议状态信息
_sass.on(_sass.CLASS_SAVE_RECORD_INFO_SUCCESS, this._sassSaveClassRecordInfoSuccessHandler.bind(this));//保存会议录制信息
_sass.on(_sass.DELETE_DOCUMENT_SUCCESS, this._sassDeleteDocumentSuccess.bind(this));//sass删除文档成功
//ServerCheck ip
_serverCheck=ServerCheck;
_serverCheck.on(_serverCheck.SEVER_CHECK_BEST_IP_SUCCESS, this._serverCheckBestIpSuccessHandler.bind(this));//ip选点,获取最佳ip完成
// 底层MCU消息层
_mcu = Mcu;
_mcu.on('*', (type, data) => this._emit(type, data));
... ... @@ -295,6 +304,7 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.password = _param.password || "";
GlobalConfig.hasCamera=(typeof _param.hasCamera=="boolean")? _param.hasCamera:false;
GlobalConfig.hasMicrophone=(typeof _param.hasMicrophone=="boolean")? _param.hasMicrophone:false;
//debugger;
//开始校验
if (_sass) {
... ... @@ -355,107 +365,12 @@ export default class MessageEntrance extends Emiter {
mcu 字符串 Mcu列表
rs 字符串 Rs列表
doc 字符串 Doc列表*/
/* {
"record": "112.126.80.182:80",
"flag": "true",
"h5Module": 1,
"maxVideoChannels": 1,
"mcu": "123.56.73.119:7000;123.56.69.230:7000;112.126.80.182:7000",
"ms": "pubms.3mang.com:1935",
"doc": "101.200.150.192:80",
"rs": "pubms.3mang.com:1935",
"type": 1,
"maxAudioChannels": 1,
"h5_mcu_list": "123.56.73.119:7001;123.56.69.230:7001;112.126.80.182:7001"
}*/
/*
if (_data.h5_mcu_list) {
//MCU地址默认使用第一个
let server = _data.h5_mcu_list.split(";")[0];
GlobalConfig.MCUServerIP = server.split(":")[0];
GlobalConfig.MCUServerPort = server.split(":")[1];
}
//视频推流播流地址
if (_data.ms) {
//MS地址默认使用第一个
let server = _data.ms.split(";")[0];
GlobalConfig.MSServerIP = server.split(":")[0];
GlobalConfig.MSServerPort = server.split(":")[1];
}
//m3u8播流地址
if(_data.rs){
//RS地址默认使用第一个
let server = _data.rs.split(";")[0];
GlobalConfig.RSServerIP = server.split(":")[0];
GlobalConfig.RSServerPort = server.split(":")[1];
}
GlobalConfig.docServer = _data.doc;
GlobalConfig.h5_mcu_list = _data.h5_mcu_list;
GlobalConfig.h5Module = _data.h5Module;
GlobalConfig.mcu = _data.mcu;
GlobalConfig.ms = _data.ms;
GlobalConfig.record = _data.record;
GlobalConfig.rs = _data.rs;
GlobalConfig.maxVideoChannels = _data.maxVideoChannels;
GlobalConfig.maxAudioChannels = _data.maxAudioChannels;
*/
/*
//这个接口获取的数据在getClassParam接口的数据中都有,内容重复,这个接口废弃
//获取会议基本信息
if (_sass) {
_sass.getClassDetail();
}
*/
//获取会议最完整的数据
if (_sass) {
_sass.getClassParam();
}
}
//获取会议基本信息getClassH5
_sassGetClassDetailSuccessHandler(_data) {
loger.log('获取getClassDetail完成.');
/* {
"cycle": 0,
"repeatmonthweekweek": 0,
"status": 1,
"repeatmonthday": 0,
"repeatmode": 0,
"beginTime": "2017-02-03 09:00:00",
"frequency": 1,
"endmode": 0,
"meetingContent": "",
"endTime": "2017-03-31 11:00:00",
"repeatweek": "",
"category": "",
"finalenddate": "",
"repeatday": 0,
"meetingName": "mcu1",
"errorCode": 0,
"monthType": 0,
"repeatmonthweekday": 0,
"endcount": 1
}*/
GlobalConfig.classDetail = _data;
GlobalConfig.className = _data.meetingName || "";
GlobalConfig.classBeginTime = _data.beginTime || "";
GlobalConfig.classEndTime = _data.endTime || "";
//获取会议所有信息和以前保存的会议状态信息(最全的信息)
if (_sass) {
_sass.getClassParam();
}
}
//获取会议所有参数 api/meeting/detail.do? flash中的接口文件是 getClassParam.do
_sassGetClassParamSuccessHandler(_data) {
//console.log(GlobalConfig.classStatusInfo)
... ... @@ -467,6 +382,7 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.className = _data.meetingName || "";
GlobalConfig.classBeginTime = _data.beginTime || "";
GlobalConfig.classEndTime = _data.endTime || "";
GlobalConfig.userIp=_data.userIp||"";
GlobalConfig.maxVideoChannels = _data.maxVideoChannels;
GlobalConfig.maxAudioChannels = _data.maxAudioChannels;
... ... @@ -526,7 +442,18 @@ export default class MessageEntrance extends Emiter {
loger.log("还没有保存过会议状信息");
}
//所有Sass流程完成,开始MCU连接
//根据用户的userIp获取信息
this.getUserIpInfo();
}
//根据UserIp获取ip信息
getUserIpInfo(){
if(_serverCheck){
_serverCheck.getUserIpInfo("",GlobalConfig.userIp);
}
}
//MCU MS ip选点完成,开加入MCU
_serverCheckBestIpSuccessHandler(_data){
loger .log("_serverCheckBestIpSuccessHandler,IP选点结束");
this._joinMCU();
}
... ... @@ -569,49 +496,50 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.DOCServerIP =GlobalConfig.DOCServerIP;
initSuccessCallBackData.DOCServerPort =GlobalConfig.DOCServerPort;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.className = GlobalConfig.className;
initSuccessCallBackData.h5Module = GlobalConfig.h5Module;
initSuccessCallBackData.isHost = GlobalConfig.isHost;
initSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
initSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
initSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
initSuccessCallBackData.msType = GlobalConfig.msType;
initSuccessCallBackData.nodeId = GlobalConfig.nodeId;
initSuccessCallBackData.password = GlobalConfig.password;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.DOCServerIP =GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort =GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost;
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
initSuccessCallBackData.role = GlobalConfig.role;
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.userName = GlobalConfig.userName;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
joinClassSuccessCallBackData.country = GlobalConfig.country;//国家
joinClassSuccessCallBackData.city = GlobalConfig.city;//城市
joinClassSuccessCallBackData.province = GlobalConfig.province;//服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp;//服务商
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
initSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
loger.log('加入会议成功');
console.log(initSuccessCallBackData);
console.log(joinClassSuccessCallBackData);
//加入会议成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS,initSuccessCallBackData);
/* //返回给客户数据
if (_joinClassSuccessCallBackFun) {
_joinClassSuccessCallBackFun(initSuccessCallBackData);
}*/
this._emit(MessageTypes.CLASS_JOIN_SUCCESS,joinClassSuccessCallBackData);
}
//Sass删除文档数据
... ... @@ -746,6 +674,11 @@ export default class MessageEntrance extends Emiter {
}
_getVideoPublishPath(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_video_ape){
return _video_ape.getPublishVideoPath(_param);
}
... ... @@ -801,6 +734,10 @@ export default class MessageEntrance extends Emiter {
}
_getPublishAudioPath(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_audio_ape){
return _audio_ape.getAudioPublishPath(_param);
}
... ...
... ... @@ -272,7 +272,7 @@ GlobalConfig.hasCamera=false;//摄像头是否可用
GlobalConfig.hasMicrophone=false;//麦克风是否可用
GlobalConfig.deviceType=0; //设备类型 0:电脑 1:安卓 2:ios
GlobalConfig.userIP="";//用户当前IP
GlobalConfig.userIp="";//用户当前IP
GlobalConfig.userId=0;
GlobalConfig.userName="";
... ... @@ -326,4 +326,9 @@ GlobalConfig.musicListPrepare=[];//提提前上传的music集合
GlobalConfig.rsList=[];
GlobalConfig.country ="";//国家
GlobalConfig.city ="";//城市
GlobalConfig.province = "";//服务商
GlobalConfig.isp ="";//服务商
export default GlobalConfig;
... ...
... ... @@ -4,6 +4,9 @@ import MessageTypes from 'MessageTypes';
import GlobalConfig from 'GlobalConfig';
import MD5 from "md5";
import ApeConsts from 'apes/ApeConsts';
import iphunter from 'iphunter';
import fetchJsonp from 'fetch-jsonp';
// 日志对象
const loger = Loger.getLoger('Sass');
... ... @@ -384,23 +387,23 @@ class Sass extends Emiter {
//保存录制的信息,主要是录制文件的名称,必须和MCU录制的文件名相同
saveClassRecordContrlInfo(_param) {
loger.log('保存开始录制信息');
let key = "3mang123A";
let siteID = GlobalConfig.siteId;
let key = "3mang123A";
let siteID = GlobalConfig.siteId;
let meetingID = GlobalConfig.classId;
let userID = GlobalConfig.userId;
let userName = GlobalConfig.userName;
let userID = GlobalConfig.userId;
let userName = GlobalConfig.userName;
let meetingName = GlobalConfig.className;
let startTime =GlobalConfig.classBeginTime;
let endTime = GlobalConfig.classEndTime;
let playUrl = "";
let streamName = GlobalConfig.recordFileName;
let confRecordFileName=GlobalConfig.recordFileName;
let downloadUrl = "";
let recordStatus = GlobalConfig.classStatus;
let recordTimestamp =GlobalConfig.classTimestamp;
let startTime = GlobalConfig.classBeginTime;
let endTime = GlobalConfig.classEndTime;
let playUrl = "";
let streamName = GlobalConfig.recordFileName;
let confRecordFileName = GlobalConfig.recordFileName;
let downloadUrl = "";
let recordStatus = GlobalConfig.classStatus;
let recordTimestamp = GlobalConfig.classTimestamp;
let timestamp = new Date().getTime();;
let authId = MD5(key + siteID + meetingID + timestamp);
let timestamp = new Date().getTime();
let authId = MD5(key + siteID + meetingID + timestamp);
let url = `http://${confInfo.portal}/3m/recordingMeeting/insertRecordingMeeting.do?siteID=${siteID}&meetingID=${meetingID}&userID=${userID}&userName=${userName}&meetingName=${meetingName}&startTime=${startTime}&endTime=${endTime}&playUrl=${playUrl}&streamName=${streamName}&downloadUrl=${downloadUrl}&configFile=${confRecordFileName}&timestamp=${timestamp}&recordTimestamp=${recordTimestamp}&authId=${authId}`;
loger.log('saveClassRecordContrlInfo', url);
... ... @@ -420,7 +423,7 @@ class Sass extends Emiter {
loger.log('保存开始录制信息 完成');
this._emit(Sass.CLASS_SAVE_RECORD_INFO_SUCCESS, _param);
} else {
loger.warn('保存开始录制信息 失败.',ret);
loger.warn('保存开始录制信息 失败.', ret);
}
})
.catch(err => {
... ... @@ -428,7 +431,6 @@ class Sass extends Emiter {
});
}
}
Sass.prototype.SUCCESS = Sass.SUCCESS = 'Sass_success';
... ...
import Emiter from 'Emiter';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import GlobalConfig from 'GlobalConfig';
import MD5 from "md5";
import ApeConsts from 'apes/ApeConsts';
import iphunter from 'iphunter';
import Server from "config/Server";
import fetchJsonp from 'fetch-jsonp';
// 日志对象
const loger = Loger.getLoger('ServerCheck');
//ip选点流程的状态
let isRequestMcuCallback = false;//是否获取最佳mcu返回
let isRequestMsCallback = false;//是否获取ms最佳返回
let isTestFromSass=false;
let isTestFromServer=false;
let tempMcuIp="";
let tempMcuPort="";
let tempMsIp="";
let tempMsPort="";
class ServerCheck extends Emiter {
constructor() {
super();
}
//根据userIp获取ip相关的信息,参数是userIp
getUserIpInfo(token, userIp) {
//重置ip选点流程状态
isRequestMcuCallback = false;
isRequestMsCallback = false;
isTestFromSass=false;
isTestFromServer=false;
let userIpInfo = new Object;
userIpInfo.ret = -1;
let ip = userIp;
let md5Str = MD5("addr=" + ip + "&token=b657c3507b324353e09c1958ee956a98efceb3e3");//("addr=" + ip + "&token=b657c3507b324353e09c1958ee956a98efceb3e3"),转成MD5
let timestamp = new Date().getTime();
let location = `http://ipapi.ipip.net/find?addr=${ip}&sid=14&uid=5237&sig=${md5Str}&_=${timestamp}`;
loger.log('获取IP信息 ', userIp, location);
fetchJsonp(location, {
timeout: 3000,
}).then(function (response) {
return response.json()
}).then(function (json) {
loger.log('获取IP信息返回', json)
if (json) {
userIpInfo.ret = json.ret;
userIpInfo.country = json.data[0];//国家
userIpInfo.province = json.data[1];//省份
userIpInfo.city = json.data[2];//城市
userIpInfo.isp = json.data[4];//运营商
}
this.serverGetUserIpInfoCallback(userIpInfo);
}.bind(this)).catch(function (ex) {
loger.log('获取IP信息失败', ex.message)
this.serverGetUserIpInfoCallback(userIpInfo);
}.bind(this));
}
//获取ip信息返回
serverGetUserIpInfoCallback(userIpInfo) {
loger.log("获取IP详情,开始处理", userIpInfo);
if (userIpInfo.ret == "ok") {
GlobalConfig.country = userIpInfo.country;//国家
GlobalConfig.city = userIpInfo.city;//城市
GlobalConfig.province = userIpInfo.province;//服务商
GlobalConfig.isp = userIpInfo.isp;//服务商
loger.log("获取ip详情成功,country:" + GlobalConfig.country + ",city:" + GlobalConfig.city + ",isp:" + GlobalConfig.isp);
this._chooseBestIpFromServer();
}
else {
loger.log("获取ip详情失败");
this._chooseBestIpFromSassParam();
}
}
//从IPIP服务列表中选择最快的IP
_chooseBestIpFromServer() {
loger.log("从IPIP服务列表中选择最快的IP");
isRequestMcuCallback=false;
isRequestMsCallback=false;
isTestFromServer=true;
isTestFromSass=false;
let mcuIpGroup =this._returnServerMS();
let msIpGroup = this._returnServerMCU();
this.getBestMcuServer(mcuIpGroup);
this.getBestMsServer(msIpGroup);
}
//从Sass返回的msList mcuList中选点
_chooseBestIpFromSassParam() {
loger.log("从Sass服务列表中选择最快的IP");
isRequestMcuCallback=false;
isRequestMsCallback=false;
isTestFromServer=true;
isTestFromSass=true;
//MCU
let mcuIpGroup = [];
let speedTestPort = ':8080';//测速端口统一
for (let i = 0; i < GlobalConfig.mcuList.length; i++) {
let ipPort = GlobalConfig.mcuList[i].ip+speedTestPort;
mcuIpGroup.push(ipPort)
}
this.getBestMcuServer(mcuIpGroup);
//MS
let msIpGroup = [];
for (let i = 0; i < GlobalConfig.msList.length; i++) {
let ipPort = GlobalConfig.msList[i].ip+speedTestPort;
msIpGroup.push(ipPort)
}
this.getBestMsServer(msIpGroup);
}
//获取最快的MCU服务器地址,参数是一个ip数组
getBestMcuServer(_param) {
loger.log('getBestMcuServer ', _param);
if(_param==null||_param.length<1){
this._getBestMcuServerCallbackHandler("")
return;
}
iphunter(_param, function (fatest_ip_response) {
if (!fatest_ip_response) {
loger.warn('getBestMcuServer -> nothing!');
this._getBestMcuServerCallbackHandler("")
} else {
loger.log('getBestMcuServer done -> ', fatest_ip_response);
this._getBestMcuServerCallbackHandler(fatest_ip_response)
}
}.bind(this), 3000);
}
//获取最快的MS服务器地址,参数是一个ip数组
getBestMsServer(_param) {
loger.log('getBestMsServer ', _param);
if(_param==null||_param.length<1){
this._getBestMsServerCallbackHandler("")
return;
}
iphunter(_param, function (fatest_ip_response) {
if (!fatest_ip_response) {
loger.warn('getBestMsServer -> nothing!');
this._getBestMsServerCallbackHandler("");
} else {
loger.log('getBestMsServer done -> ', fatest_ip_response);
this._getBestMsServerCallbackHandler(fatest_ip_response);
}
}.bind(this), 3000);
}
_getBestMcuServerCallbackHandler(_data) {
loger.log("_getBestMcuServerCallbackHandler", _data);
if (isRequestMcuCallback) {
loger.log("_getBestMcuServerCallbackHandler,已经有返回");
return;
}
isRequestMcuCallback = true;
if (_data) {
let server = _data.split(":");
if (server[0]) {
tempMcuIp= server[0];
}
if (server[1]) {
tempMcuPort = server[1];
}
}
//loger.log("_getBestMcuServerCallbackHandler",tempMcuIp,tempMcuPort);
this._startConnectMcu();
}
_getBestMsServerCallbackHandler(_data) {
loger.log("_getBestMsServerCallbackHandler", _data);
if (isRequestMsCallback) {
loger.log("_getBestMsServerCallbackHandler,已经有返回");
return;
}
isRequestMsCallback = true;
if (_data) {
let server = _data.split(":");
if (server[0]) {
tempMsIp= server[0];
}
if (server[1]) {
tempMsPort= server[1];
}
}
//loger.log("_getBestMsServerCallbackHandler", tempMsIp,tempMsPort);
this._startConnectMcu();
}
//ip选点结束,开始连接MCU
_startConnectMcu() {
if (isRequestMcuCallback && isRequestMsCallback) {
if (isTestFromServer && !isTestFromSass) {
//从Server服务列表中选点结束,如果没有选到合适的,从Sass的列表中获取
if(!tempMcuIp||!tempMsIp){
this._chooseBestIpFromSassParam();
}else {
this._emit(ServerCheck.SEVER_CHECK_BEST_IP_SUCCESS);
}
} else {
//从Sass返回的服务列表中选点结束
this._emit(ServerCheck.SEVER_CHECK_BEST_IP_SUCCESS);
}
} else {
loger.warn("_startConnectMcu 正在选点", isRequestMcuCallback, isRequestMsCallback);
}
}
//检测MCU连接地址
_returnServerMCU(country, province, ctiy, isp, jsona) {
let arr=[];
return arr;
}
//检测MS连接地址
//Config.ipInfo
_returnServerMS(country, province, ctiy, isp, jsona) {
let arr = [];
/* let acquire = false;
if (isp != "") {
for (let obja in jsona.MS.isp) {
if (isp.indexOf(obja.idc) != -1) {
arr = obja.mslist;
acquire = true;
break;
}
}
}
if (country == "中国" && !acquire) {
for (let obja in jsona.MS.china) {
if (obja.province.indexOf(province) != -1 && province != "") {
arr = obja.mslist;
acquire = true;
break;
}
}
if (!acquire) {
arr = jsona.MS.china[jsona.MS.china.length - 1].mslist;
acquire = true;
}
}
if (country != "中国" && country != "") {
for (let obja:Object in jsona.MS.international) {
if (obja.country.indexOf(country) != -1) {
arr = obja.mslist;
acquire = true;
break;
}
}
if (!acquire) {
arr = jsona.MS.international[jsona.MS.international.length - 1].mslist;
acquire = true;
}
}
else if (!acquire) {
arr = jsona.MS.Default;
}
loger.info("ms匹配结束;" + arr.length);*/
return arr;
}
}
ServerCheck.prototype.SEVER_CHECK_BEST_IP_SUCCESS = ServerCheck.SEVER_CHECK_BEST_IP_SUCCESS = 'severCheck_checkBestIpSuccess_message';//获取最快的MS地址
export default new ServerCheck;
... ...
/*
* 全局数据管理
* */
import Loger from 'Loger';
import ApeConsts from "apes/ApeConsts";
let loger = Loger.getLoger('Server');
import EngineUtils from 'EngineUtils';
class Server {
constructor() {
}
static get serverList(){
return {
"共享地址": [
{
"ip": "106.3.130.98",
"name": "BGP多线3"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "221.228.109.123",
"name": "无锡"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
},
{
"ip": "liantong.ms.3mang.com",
"name": "联通专线"
},
{
"ip": "yidong.ms.3mang.com",
"name": "移动专线"
},
{
"ip": "dianxin.ms.3mang.com",
"name": "电信专线"
},
{
"ip": "103.235.232.128",
"name": "BGP多线2"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "116.213.102.217",
"name": "BGP多线1"
}
],
"局域网": [
{
"ip": "106.3.130.98",
"name": "BGP多线3"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "221.228.109.123",
"name": "无锡"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
},
{
"ip": "liantong.ms.3mang.com",
"name": "联通专线"
},
{
"ip": "yidong.ms.3mang.com",
"name": "移动专线"
},
{
"ip": "dianxin.ms.3mang.com",
"name": "电信专线"
},
{
"ip": "103.235.232.128",
"name": "BGP多线2"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "116.213.102.217",
"name": "BGP多线1"
}
],
"中国": {
"province": {
"香港": [
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "199.59.231.234",
"name": "全球通香港"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
],
"台湾": [
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.205.129",
"name": "全球通台湾"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
]
},
"isp": {
"鹏博士": [
{
"ip": "124.192.148.139",
"name": "鹏博士"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "106.3.130.98",
"name": "BGP多线3"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
],
"长城": [
{
"ip": "124.192.148.139",
"name": "鹏博士"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "106.3.130.98",
"name": "BGP多线3"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
],
"移动": [
{
"ip": "yidong.ms.3mang.com",
"name": "移动专线"
},
{
"ip": "116.213.102.217",
"name": "BGP多线1"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "103.235.232.128",
"name": "BGP多线2"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
],
"电信": [
{
"ip": "dianxin.ms.3mang.com",
"name": "电信专线"
},
{
"ip": "116.213.102.217",
"name": "BGP多线1"
},
{
"ip": "103.235.232.128",
"name": "BGP多线2"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
],
"联通": [
{
"ip": "116.213.102.217",
"name": "BGP多线1"
},
{
"ip": "103.235.232.128",
"name": "BGP多线2"
},
{
"ip": "liantong.ms.3mang.com",
"name": "联通专线"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "106.3.130.98",
"name": "BGP多线3"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
}
]
},
"default": [
{
"ip": "106.3.130.98",
"name": "BGP多线3"
},
{
"ip": "221.228.109.123",
"name": "无锡"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
},
{
"ip": "liantong.ms.3mang.com",
"name": "联通专线"
},
{
"ip": "yidong.ms.3mang.com",
"name": "移动专线"
},
{
"ip": "dianxin.ms.3mang.com",
"name": "电信专线"
},
{
"ip": "lanxms.3mang.com",
"name": "国内专线"
},
{
"ip": "123.56.75.60",
"name": "BGP多线4"
},
{
"ip": "103.235.232.128",
"name": "BGP多线2"
},
{
"ip": "116.213.102.217",
"name": "BGP多线1"
}
]
},
"美国": [
{
"ip": "38.83.109.142",
"name": "达拉斯"
},
{
"ip": "45.126.244.41",
"name": "全球通达拉斯"
},
{
"ip": "185.114.76.243",
"name": "全球通阿什本"
},
{
"ip": "159.100.196.217",
"name": "全球通迈阿密"
},
{
"ip": "185.114.77.84",
"name": "全球通圣何塞"
},
{
"ip": "159.100.195.230",
"name": "全球通洛杉矶"
},
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.192.188",
"name": "全球通芝加哥"
}
],
"加拿大": [
{
"ip": "38.83.109.142",
"name": "达拉斯"
},
{
"ip": "45.126.244.41",
"name": "全球通达拉斯"
},
{
"ip": "185.114.76.243",
"name": "全球通阿什本"
},
{
"ip": "159.100.196.217",
"name": "全球通迈阿密"
},
{
"ip": "185.114.77.84",
"name": "全球通圣何塞"
},
{
"ip": "159.100.195.230",
"name": "全球通洛杉矶"
},
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.192.188",
"name": "全球通芝加哥"
}
],
"墨西哥": [
{
"ip": "38.83.109.142",
"name": "达拉斯"
},
{
"ip": "45.126.244.41",
"name": "全球通达拉斯"
},
{
"ip": "185.114.76.243",
"name": "全球通阿什本"
},
{
"ip": "159.100.196.217",
"name": "全球通迈阿密"
},
{
"ip": "185.114.77.84",
"name": "全球通圣何塞"
},
{
"ip": "159.100.195.230",
"name": "全球通洛杉矶"
},
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.192.188",
"name": "全球通芝加哥"
}
],
"菲律宾": [
{
"ip": "223.255.248.122",
"name": "香港"
},
{
"ip": "118.193.20.130",
"name": "日本"
},
{
"ip": "118.193.24.38",
"name": "新加坡"
},
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.194.120",
"name": "全球通日本"
},
{
"ip": "185.114.78.179",
"name": "全球通新加坡"
},
{
"ip": "159.100.205.129",
"name": "全球通台湾"
},
{
"ip": "192.158.245.185",
"name": "全球通韩国"
},
{
"ip": "103.29.35.63",
"name": "全球通印度"
},
{
"ip": "199.59.231.234",
"name": "全球通香港"
}
],
"越南": [
{
"ip": "223.255.248.122",
"name": "香港"
},
{
"ip": "118.193.20.130",
"name": "日本"
},
{
"ip": "118.193.24.38",
"name": "新加坡"
},
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.194.120",
"name": "全球通日本"
},
{
"ip": "185.114.78.179",
"name": "全球通新加坡"
},
{
"ip": "159.100.205.129",
"name": "全球通台湾"
},
{
"ip": "192.158.245.185",
"name": "全球通韩国"
},
{
"ip": "103.29.35.63",
"name": "全球通印度"
},
{
"ip": "199.59.231.234",
"name": "全球通香港"
}
],
"泰国": [
{
"ip": "223.255.248.122",
"name": "香港"
},
{
"ip": "118.193.20.130",
"name": "日本"
},
{
"ip": "118.193.24.38",
"name": "新加坡"
},
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "159.100.194.120",
"name": "全球通日本"
},
{
"ip": "185.114.78.179",
"name": "全球通新加坡"
},
{
"ip": "159.100.205.129",
"name": "全球通台湾"
},
{
"ip": "192.158.245.185",
"name": "全球通韩国"
},
{
"ip": "103.29.35.63",
"name": "全球通印度"
},
{
"ip": "199.59.231.234",
"name": "全球通香港"
}
],
"default": [
{
"ip": "bjms1.3mang.com",
"name": "全球通"
},
{
"ip": "qims.3mang.com",
"name": "全球通-备"
},
{
"ip": "38.83.109.142",
"name": "达拉斯"
},
{
"ip": "118.193.20.130",
"name": "日本"
},
{
"ip": "38.123.107.18",
"name": "德国"
},
{
"ip": "223.255.248.122",
"name": "香港"
},
{
"ip": "148.153.8.22",
"port": "1935",
"name": "纽约"
},
{
"ip": "38.121.61.242",
"port": "1935",
"name": "洛杉矶"
},
{
"ip": "118.193.24.38",
"name": "新加坡"
},
{
"ip": "159.100.194.120",
"name": "全球通日本"
},
{
"ip": "159.100.192.188",
"name": "全球通芝加哥"
},
{
"ip": "45.126.244.41",
"name": "全球通达拉斯"
},
{
"ip": "45.126.246.148",
"name": "全球通德国"
},
{
"ip": "192.158.245.185",
"name": "全球通韩国"
},
{
"ip": "103.29.35.63",
"name": "全球通印度"
},
{
"ip": "202.127.74.126",
"name": "全球通新加坡"
},
{
"ip": "199.59.231.234",
"name": "全球通香港"
},
{
"ip": "159.100.205.129",
"name": "全球通台湾"
}
]
}
}
}
export default Server;
\ No newline at end of file
... ...