起動中のサーバを通知

起動中のサーバを通知

他人がサーバ起動したことを知るために、サーバの起動状況を管理するサーバとして、メタサーバを用意する。サーバ起動時にメタサーバに情報を送るかどうかは設定により変更できるとする。

サーバの起動情報は、HTTP の POST メソッドで通知するとし、その管理はメタサーバ上の PHP スクリプトで行うとする。

create_list.png

サーバ起動情報の通知と取得

従って、HTTP プロトコルで指定アドレスに POST, GET でアクセスする機能が必要となる。また、サーバ一覧情報を生成する PHP スクリプトの仕様は以下の通りとする。

上記仕様を実装したものは、こんな感じ。

<?php
/*
 オッニー、キ、ニ、、、オ。シ・ミセホエノヘ Satofumi KAMIMURA
 $Id$
*/

require_once('includes/config.php');

if (isset($_POST['port']) && isset($_POST['people'])) {
  // ・オ。シ・ミ、ォ、鬢ホ host, port トフテホ、ンツク

  $recv_ticks = time();
  $port = intval($_POST['port']);
  $people = intval($_POST['people']);
  $host = $_SERVER['REMOTE_ADDR'];
  if (!preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $host)) {
    exit;
  }

  // ・オ。シ・ミセノイテ
  $fd = fopen(DataFile, 'a');
  if ($fd && flock($fd, LOCK_EX)) {
    fwrite($fd, $recv_ticks. "\t". $people. "\t". $port. "\t". $host. "\n");
    flock($fd, LOCK_UN);
  }
  fclose($fd);
  exit;

} else {
  // オッニー、キ、ニ、、、、ネサラ、・オ。シ・ミセミホマ
  $fd = fopen(DataFile, 'r');
  if (!$fd || !flock($fd, LOCK_SH)) {
    exit;
  }
  $servers = array();
  $now_ticks = time();
  while ($info = fscanf($fd, "%d\t%d\t%d\t%s\n")) {
    list ($ticks, $people, $port, $host) = $info;
    if ($ticks + TimeoutSec > $now_ticks) {
      $servers[$port. "\t". $host] = $ticks. "\t". $people;
    }
  }
  flock($fd, LOCK_UN);
  fclose($fd);

  // ケケソキ
  $fd = fopen(DataFile, 'w');
  if (!flock($fd, LOCK_EX)) {
    exit;
  }
  if (count($servers) <= 0) {
    // ・ケ・ネ、ャカホセ遉ホス靉    echo "\n";

  } else {
    // ・ソ・、・爭「・ヲ・ネノセイチク螟ホハンツク・ケ・ネ、ンツク
    asort($servers);
    reset ($servers);
    while (list ($key, $val) = each ($servers)) {
      $people = split("\t", $val);
      $people = $people[1];
      if ($people > 0) {
        echo $people. "\t". $key. "\n";
        fwrite($fd, $val. "\t". $key. "\n");
      }
    }
  }
  flock($fd, LOCK_UN);
  fclose($fd);
}
?>


で、その実装のテストは、以下の通り。

<?php
/*
 serverList.php 、ホ・ニ・ケ・ネ
 Satofumi KAMIMURA
 $Id$
*/

define('TestHost', 'localhost');
define('TestURL', '/~satofumi/nettyping/test/serverList.php');

define('LocalHost', '127.0.0.1');
define('SomeHost', '127.0.0.1');

error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
require_once('phpunit/phpunit.php');
require_once('includes/postSendClass.php');


class ServerListTest extends TestCase {
  var $obj;
  var $url;

  // ・ウ・ケ・ネ・鬣ッ・ソ
  function ServerListTest($name) {
    $this->TestCase($name);
    $this->url = 'http://'. TestHost. TestURL;
  }

  // ・ニ・ケ・ネ、ホス魘ス
  function setUp() {}

  // ・ニ・ケ・ネ、ホスェホサ
  function tearDown() {}


  // ニノ、゜スミ、キサヒカォ、ノ、ヲ、ォ、ホウホヌァ
  function testNull() {
    $lines = file($this->url);
    $this->assertEquals(1, count($lines));
    $this->assertEquals("\n", $lines[0]);
  }


  function check1stInfo() {
    // ニノ、゜スミ、キ、ニ。「・ヌ。シ・ソ、ャヘストフ、熙ォ、ホウホヌァ
    $lines = file($this->url);
    $this->assertEquals(1, count($lines));
    $this->assertEquals("1\t57577\t". LocalHost. "\n", $lines[0]);
  }


  // 」アキワ、ホ・ヌ。シ・ソ、ミマソ、ヌ、ュ、ォウホヌァ
  function test1stPost() {
    $post = new PostSend;
    $post->add('host', LocalHost);
    $post->add('port', '57577');
    $post->add('people', '1');
    $post->send(TestHost, TestURL);

    $this->check1stInfo();
  }


  // 」イキワ、ホ・ヌ。シ・ソ、ミマソ、ヌ、ュ、ォウホヌァ
  function test2ndPost() {
    $post = new PostSend;
    $post->add('host', SomeHost);
    $post->add('port', '57578');
    $post->add('people', '1');
    $post->send(TestHost, TestURL);

    // ニノ、゜スミ、キ、ニ。「・ヌ。シ・ソ、ャヘストフ、熙ォ、ホウホヌァ
    $lines = file($this->url);
    $this->assertEquals(2, count($lines));
    $this->assertEquals("1\t57578\t". SomeHost. "\n", $lines[0]);
    $this->assertEquals("1\t57577\t". LocalHost. "\n", $lines[1]);
  }


  // 0 ソヘ、スタチ、ケ、ネ。「・ヌ。シ・ソ、ャコオ、ォウホヌァ
  function testNoPeople() {
    $post = new PostSend;
    $post->add('host', SomeHost);
    $post->add('port', '57578');
    $post->add('people', '0');
    $post->send(TestHost, TestURL);

    $this->check1stInfo();
  }


  // ーヨク螟ヒ・ヌ。シ・ソ、ャコオ、ォウホヌァ
  function testTimeout() {
    sleep(1);
    $this->testNull();
  }
}
?>


<html>
<head>
<title>ServerListTest</title>
<STYLE TYPE="text/css">
<?php
include ("stylesheet.css");
?>
</STYLE>
</head>
<body>
<?php
$suite = new TestSuite('ServerListTest');
$result = new PrettyTestResult;
$suite->run($result);
$result->report();
?>

<?
/*
  ・ヌ。シ・ソ、ホ POST チョ、ヤ、ヲ、ソ、皃ホ・ッ・鬣ケ
  Satofumi KAMIMURA
  $Id$
*/


class PostSend {
  var $post_str;

  // ・ウ・ケ・ネ・鬣ッ・ソ
  function PostSend() {
    $this->post_str = '';
  }

  // POST ・ッ・ィ・ケ・ネ、ホチョ
  function send($host, $page) {
    $request =
      'POST '. $page. " HTTP/1.0\r\n".
      'Host: '. $host. "\r\n".
      "Content-Type: application/x-www-form-urlencoded\r\n".
      'Content-Length: '. strlen($this->post_str). "\r\n".
      "Accept: */*\r\n".
      "\r\n".
      $this->post_str. "\r\n".
      "\r\n";
    $fp = fsockopen($host, 80, $errno, $errstr, 10);
    if (!$fp) {
      echo 'fail: fsockopen: '. $errono. ','. $errstr;
      exit;
    }
    fputs($fp, $request);

    $response = "";
    while (!feof($fp)) {
      $response .= fgets($fp, 4096);
    }
    fclose($fp);
  }

  // POST ・ヌ。シ・ソ、ホトノイテ
  function add($key, $value) {
    if (strlen($this->post_str) > 0) {
      $this->post_str .= '&';
    }
    $this->post_str .= $key. '='. $value;
  }
}
?>

くらいかな?


Generated on Mon Apr 13 22:52:06 2009 by  doxygen 1.5.7.1