link to my blog post
[auerswald-callnotifier.git] / src / callnotifier / Source / Remote.php
1 <?php
2 namespace callnotifier;
3
4 class Source_Remote
5 {
6     protected $socket;
7
8     public function __construct($config, $handler)
9     {
10         $this->config  = $config;
11         $this->handler = $handler;
12     }
13
14     public function run()
15     {
16         do {
17             try {
18                 $tryAgain = false;
19                 $this->connect($this->config->host, $this->config->port);
20                 $this->init();
21                 $this->loop();
22             } catch (Exception_ConnectionReset $e) {
23                 $tryAgain = true;
24                 //connection is refused directly after a connection reset
25                 //hopefully waiting a bit will help
26                 sleep(10);
27             }
28         } while ($tryAgain);
29         $this->disconnect();
30     }
31
32     public function connect($ip, $port)
33     {
34         if ($ip == '') {
35             throw new \Exception('No remote IP or hostname given.');
36         }
37
38         $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
39         if ($socket === false) {
40             throw new \Exception(
41                 'socket_create() failed: reason: '
42                 . socket_strerror(socket_last_error())
43             );
44         }
45         //echo "Attempting to connect to '$ip' on port '$port'...";
46         $result = socket_connect($socket, $ip, $port);
47         if ($result === false) {
48             throw new \Exception(
49                 "socket_connect() failed. Reason: "
50                 . socket_strerror(socket_last_error($socket))
51             );
52         }
53
54         $this->socket = $socket;
55     }
56
57     function init()
58     {
59         $msg = "\x00\x01DecoderV=1\n";
60         socket_write($this->socket, $msg, strlen($msg));
61         $res = $this->read_response();
62         socket_write($this->socket, "\x00\x02", 2);
63     }
64
65     function loop()
66     {
67         while (true) {
68             $dbgmsg = $this->read_response();
69             //echo $dbgmsg . "\n";
70             $this->handler->handle($dbgmsg);
71         }
72     }
73
74     function read_response()
75     {
76         $res = socket_read($this->socket, 2048, PHP_NORMAL_READ);
77         if ($res === false) {
78             //handle "Connection reset by peer" that appears nightly since
79             // version 4.0N
80             throw new Exception_ConnectionReset();
81         }
82         return substr($res, 2, -1);
83     }
84
85     function disconnect()
86     {
87         socket_write($this->socket, "\x00\x03", 2);
88         socket_close($this->socket);
89     }
90
91 }
92
93 ?>