皆さん、こんにちは!今日は、私が個人利用のために開発したインターネット速度テストツールを紹介したいと思います。このツールは、ユーザーのインターネット接続速度を簡単にテストできるように設計されています。また、リンクを皆さんと共有します。以下に、コードとその動作について詳しく説明します。
[SpeedTest] (https://speedtest.tehito.com)
コードの説明
speedtest.js
// speedtest.js
var worker = new Worker('speedtest_worker.js');
worker.onmessage = function (event) {
if (event.data.type === 'result') {
// 結果の処理
console.log('ダウンロード速度: ' + event.data.downloadSpeed + ' Mbps');
console.log('アップロード速度: ' + event.data.uploadSpeed + ' Mbps');
}
};
function startSpeedtest() {
worker.postMessage('start');
}
このスクリプトは、Webワーカー(speedtest_worker.js)を作成し、速度テストの結果を処理します。startSpeedtest関数は、ワーカーにメッセージを送り、速度テストを開始します。
speedtest_worker.js
// speedtest_worker.js
self.onmessage = function (event) {
if (event.data === 'start') {
// ダウンロード速度とアップロード速度を計算するコード
var downloadSpeed = calculateDownloadSpeed();
var uploadSpeed = calculateUploadSpeed();
self.postMessage({
type: 'result',
downloadSpeed: downloadSpeed,
uploadSpeed: uploadSpeed
});
}
};
function calculateDownloadSpeed() {
// ダウンロード速度を計算するロジック
return Math.random() * 100; // プレースホルダーデータ
}
function calculateUploadSpeed() {
// アップロード速度を計算するロジック
return Math.random() * 100; // プレースホルダーデータ
}
このスクリプトは、メインスクリプトからメッセージを受け取ったときにダウンロード速度とアップロード速度を計算し、その結果をメインスクリプトに送信します。速度の計算はここではプレースホルダーデータを使用しています。
getIP.php
<?php
error_reporting(0);
define('API_KEY_FILE', 'getIP_ipInfo_apikey.php');
define('SERVER_LOCATION_CACHE_FILE', 'getIP_serverLocation.php');
require_once 'getIP_util.php';
function getLocalOrPrivateIpInfo($ip)
{
if ('::1' === $ip) {
return 'localhost IPv6 access';
}
if (stripos($ip, 'fe80:') === 0) {
return 'link-local IPv6 access';
}
if (strpos($ip, '127.') === 0) {
return 'localhost IPv4 access';
}
if (strpos($ip, '10.') === 0) {
return 'private IPv4 access';
}
if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) {
return 'private IPv4 access';
}
if (strpos($ip, '192.168.') === 0) {
return 'private IPv4 access';
}
if (strpos($ip, '169.254.') === 0) {
return 'link-local IPv4 access';
}
return null;
}
function getIpInfoTokenString()
{
if (!file_exists(API_KEY_FILE) || !is_readable(API_KEY_FILE)) {
return '';
}
require API_KEY_FILE;
if (empty($IPINFO_APIKEY)) {
return '';
}
return '?token=' . $IPINFO_APIKEY;
}
function getIspInfo($ip)
{
$json = file_get_contents('https://ipinfo.io/' . $ip . '/json' . getIpInfoTokenString());
if (!is_string($json)) {
return null;
}
$data = json_decode($json, true);
if (!is_array($data)) {
return null;
}
return $data;
}
function getIsp($rawIspInfo)
{
if (is_array($rawIspInfo)) {
if (array_key_exists('org', $rawIspInfo) && is_string($rawIspInfo['org']) && !empty($rawIspInfo['org'])) {
return preg_replace('/AS\\d+\\s/', '', $rawIspInfo['org']);
}
if (array_key_exists('asn', $rawIspInfo) && is_array($rawIspInfo['asn']) && !empty($rawIspInfo['asn']) && array_key_exists('name', $rawIspInfo['asn']) && is_string($rawIspInfo['asn']['name'])) {
return $rawIspInfo['asn']['name'];
}
}
return 'Unknown ISP';
}
function getServerLocation()
{
$serverLoc = null;
if (file_exists(SERVER_LOCATION_CACHE_FILE) && is_readable(SERVER_LOCATION_CACHE_FILE)) {
require SERVER_LOCATION_CACHE_FILE;
}
if (is_string($serverLoc) && !empty($serverLoc)) {
return $serverLoc;
}
$json = file_get_contents('https://ipinfo.io/json' . getIpInfoTokenString());
if (!is_string($json)) {
return null;
}
$details = json_decode($json, true);
if (!is_array($details) || !array_key_exists('loc', $details) || !is_string($details['loc']) || empty($details['loc'])) {
return null;
}
$serverLoc = $details['loc'];
$cacheData = "<?php\n\n\$serverLoc = '" . addslashes($serverLoc) . "';\n";
file_put_contents(SERVER_LOCATION_CACHE_FILE, $cacheData);
return $serverLoc;
}
function distance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo)
{
$rad = M_PI / 180;
$theta = $longitudeFrom - $longitudeTo;
$dist = sin($latitudeFrom * $rad) * sin($latitudeTo * $rad) + cos($latitudeFrom * $rad) * cos($latitudeTo * $rad) * cos($theta * $rad);
return acos($dist) / $rad * 60 * 1.853;
}
function getDistance($rawIspInfo)
{
if (!is_array($rawIspInfo) || !array_key_exists('loc', $rawIspInfo) || !isset($_GET['distance']) || !in_array($_GET['distance'], ['mi', 'km'], true)) {
return null;
}
$unit = $_GET['distance'];
$clientLocation = $rawIspInfo['loc'];
$serverLocation = getServerLocation();
if (!is_string($serverLocation)) {
return null;
}
return calculateDistance($clientLocation, $serverLocation, $unit);
}
function calculateDistance($clientLocation, $serverLocation, $unit)
{
list($clientLatitude, $clientLongitude) = explode(',', $clientLocation);
list($serverLatitude, $serverLongitude) = explode(',', $serverLocation);
$dist = distance($clientLatitude, $clientLongitude, $serverLatitude, $serverLongitude);
if ('mi' === $unit) {
$dist /= 1.609344;
$dist = round($dist, -1);
if ($dist < 15) {
$dist = '<15';
}
return $dist . ' mi';
}
if ('km' === $unit) {
$dist = round($dist, -1);
if ($dist < 20) {
$dist = '<20';
}
return $dist . ' km';
}
return null;
}
function sendHeaders()
{
header('Content-Type: application/json; charset=utf-8');
if (isset($_GET['cors'])) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
}
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, s-maxage=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
}
function sendResponse($ip, $ipInfo = null, $distance = null, $rawIspInfo = null)
{
$processedString = $ip;
if (is_string($ipInfo)) {
$processedString .= ' - ' . $ipInfo;
}
if (is_array($rawIspInfo) && array_key_exists('country', $rawIspInfo)) {
$processedString .= ', ' . $rawIspInfo['country'];
}
if (is_string($distance)) {
$processedString .= ' (' . $distance . ' distance to server)';
}
$response = [
'rawIp' => $ip,
'ip' => $processedString,
'isp' => getIsp($rawIspInfo),
'loc' => (is_array($rawIspInfo) && array_key_exists('loc', $rawIspInfo)) ? $rawIspInfo['loc'] : null,
'distance' => $distance,
];
echo json_encode($response);
}
sendHeaders();
$ip = getClientIp();
$ipInfo = getLocalOrPrivateIpInfo($ip);
if (is_string($ipInfo)) {
sendResponse($ip, $ipInfo);
return;
}
$rawIspInfo = getIspInfo($ip);
sendResponse($ip, $ipInfo, getDistance($rawIspInfo), $rawIspInfo);
?>
このスクリプトは、クライアントのIPアドレスを検出し、ipinfo.ioからISP情報を取得します。結果はJSON形式で返されます。
-
getLocalOrPrivateIpInfo
関数は、ローカルまたはプライベートIPアドレスに対して特別なメッセージを返します。 -
getIpInfoTokenString
関数は、APIキーが設定されている場合にトークン文字列を生成します。 -
getIspInfo関数は
、ipinfo.ioからISP情報を取得します。 -
getIsp関数は
、ISP名を解析します。 -
getServerLocation
関数は、サーバーの位置情報を取得します。 -
distance
関数は、2点間の距離を計算します。 -
getDistance
関数は、クライアントとサーバー間の距離を計算します。 -
sendHeaders
関数は、適切なヘッダーを送信します。 -
sendResponse
関数は、応答を生成し送信します。
getIP_util.php
<?php
/**
* @return string
*/
function getClientIp() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_REAL_IP'])) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$ip = preg_replace('/,.*/', '', $ip); # ホストはコンマ区切りであり、クライアントは最初に位置します
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return preg_replace('/^::ffff:/', '', $ip);
}
?>
このスクリプトは、クライアントのIPアドレスを取得する関数を提供します。
getClientIp関数は、クライアントのIPアドレスを取得します。複数のヘッダーをチェックし、最初に見つかった有効なIPアドレスを返します。
garbage.php
<?php
// 圧縮を無効にする
@ini_set('zlib.output_compression', 'Off');
@ini_set('output_buffering', 'Off');
@ini_set('output_handler', '');
/**
* @return int
*/
function getChunkCount()
{
if (
!array_key_exists('ckSize', $_GET)
|| !ctype_digit($_GET['ckSize'])
|| (int) $_GET['ckSize'] <= 0
) {
return 4;
}
if ((int) $_GET['ckSize'] > 1024) {
return 1024;
}
return (int) $_GET['ckSize'];
}
/**
* @return void
*/
function sendHeaders()
{
header('HTTP/1.1 200 OK');
if (isset($_GET['cors'])) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
}
// ファイルのダウンロードを示す
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=random.dat');
header('Content-Transfer-Encoding: binary');
// キャッシュ設定: このリクエストをキャッシュしない
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, s-maxage=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
}
// 送信するデータ量を決定
$chunks = getChunkCount();
// データを生成
if (function_exists('random_bytes')) {
$data = random_bytes(1048576);
} else {
$data = openssl_random_pseudo_bytes(1048576);
}
// 1048576バイトのチャンクを送信
sendHeaders();
for ($i = 0; $i < $chunks; $i++) {
echo $data;
flush();
}
?>
このスクリプトは、ランダムなデータを生成し、クライアントに送信します。これは主にアップロード速度のテストに使用されます。
-
getChunkCount
関数は、送信するデータチャンクの数を決定します。 -
sendHeaders
関数は、適切なHTTPヘッダーを送信します。 - データ生成と送信のためのロジックが含まれています。
まとめ
このインターネット速度テストツールは、ユーザーが簡単に接続速度をテストできるように設計されています。各コード部分の理解が深まることで、ツールを最大限に活用できるようになります。