Skip to content

Commit d18f36a

Browse files
committed
init
0 parents  commit d18f36a

25 files changed

+6138
-0
lines changed

Workerman/Autoloader.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
/**
3+
* This file is part of workerman.
4+
*
5+
* Licensed under The MIT License
6+
* For full copyright and license information, please see the MIT-LICENSE.txt
7+
* Redistributions of files must retain the above copyright notice.
8+
*
9+
* @author walkor<walkor@workerman.net>
10+
* @copyright walkor<walkor@workerman.net>
11+
* @link http://www.workerman.net/
12+
* @license http://www.opensource.org/licenses/mit-license.php MIT License
13+
*/
14+
namespace Workerman;
15+
16+
/**
17+
* Autoload.
18+
*/
19+
class Autoloader
20+
{
21+
/**
22+
* Autoload root path.
23+
*
24+
* @var string
25+
*/
26+
protected static $_autoloadRootPath = '';
27+
28+
/**
29+
* Set autoload root path.
30+
*
31+
* @param string $root_path
32+
* @return void
33+
*/
34+
public static function setRootPath($root_path)
35+
{
36+
self::$_autoloadRootPath = $root_path;
37+
}
38+
39+
/**
40+
* Load files by namespace.
41+
*
42+
* @param string $name
43+
* @return boolean
44+
*/
45+
public static function loadByNamespace($name)
46+
{
47+
$class_path = str_replace('\\', DIRECTORY_SEPARATOR, $name);
48+
if (strpos($name, 'Workerman\\') === 0) {
49+
$class_file = __DIR__ . substr($class_path, strlen('Workerman')) . '.php';
50+
} else {
51+
if (self::$_autoloadRootPath) {
52+
$class_file = self::$_autoloadRootPath . DIRECTORY_SEPARATOR . $class_path . '.php';
53+
}
54+
if (empty($class_file) || !is_file($class_file)) {
55+
$class_file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . "$class_path.php";
56+
}
57+
}
58+
59+
if (is_file($class_file)) {
60+
require_once($class_file);
61+
if (class_exists($name, false)) {
62+
return true;
63+
}
64+
}
65+
return false;
66+
}
67+
}
68+
69+
spl_autoload_register('\Workerman\Autoloader::loadByNamespace');
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
/**
3+
* This file is part of workerman.
4+
*
5+
* Licensed under The MIT License
6+
* For full copyright and license information, please see the MIT-LICENSE.txt
7+
* Redistributions of files must retain the above copyright notice.
8+
*
9+
* @author walkor<walkor@workerman.net>
10+
* @copyright walkor<walkor@workerman.net>
11+
* @link http://www.workerman.net/
12+
* @license http://www.opensource.org/licenses/mit-license.php MIT License
13+
*/
14+
namespace Workerman\Connection;
15+
16+
use Workerman\Events\EventInterface;
17+
use Workerman\Worker;
18+
use Exception;
19+
20+
/**
21+
* AsyncTcpConnection.
22+
*/
23+
class AsyncTcpConnection extends TcpConnection
24+
{
25+
/**
26+
* Emitted when socket connection is successfully established.
27+
*
28+
* @var callback
29+
*/
30+
public $onConnect = null;
31+
32+
/**
33+
* Status.
34+
*
35+
* @var int
36+
*/
37+
protected $_status = self::STATUS_CONNECTING;
38+
39+
/**
40+
* Remote host.
41+
*
42+
* @var string
43+
*/
44+
protected $_remoteHost = '';
45+
46+
/**
47+
* Construct.
48+
*
49+
* @param string $remote_address
50+
* @throws Exception
51+
*/
52+
public function __construct($remote_address)
53+
{
54+
list($scheme, $address) = explode(':', $remote_address, 2);
55+
if ($scheme != 'tcp') {
56+
// Get application layer protocol.
57+
$scheme = ucfirst($scheme);
58+
$this->protocol = '\\Protocols\\' . $scheme;
59+
if (!class_exists($this->protocol)) {
60+
$this->protocol = '\\Workerman\\Protocols\\' . $scheme;
61+
if (!class_exists($this->protocol)) {
62+
throw new Exception("class \\Protocols\\$scheme not exist");
63+
}
64+
}
65+
}
66+
$this->_remoteAddress = substr($address, 2);
67+
$this->_remoteHost = substr($this->_remoteAddress, 0, strrpos($this->_remoteAddress, ':'));
68+
$this->id = self::$_idRecorder++;
69+
// For statistics.
70+
self::$statistics['connection_count']++;
71+
$this->maxSendBufferSize = self::$defaultMaxSendBufferSize;
72+
}
73+
74+
public function connect()
75+
{
76+
// Open socket connection asynchronously.
77+
$this->_socket = stream_socket_client("tcp://{$this->_remoteAddress}", $errno, $errstr, 0,
78+
STREAM_CLIENT_ASYNC_CONNECT);
79+
// If failed attempt to emit onError callback.
80+
if (!$this->_socket) {
81+
$this->_status = self::STATUS_CLOSED;
82+
$this->emitError(WORKERMAN_CONNECT_FAIL, $errstr);
83+
return;
84+
}
85+
// Add socket to global event loop waiting connection is successfully established or faild.
86+
Worker::$globalEvent->add($this->_socket, EventInterface::EV_WRITE, array($this, 'checkConnection'));
87+
}
88+
89+
/**
90+
* Get remote address.
91+
*
92+
* @return string
93+
*/
94+
public function getRemoteHost()
95+
{
96+
return $this->_remoteHost;
97+
}
98+
99+
/**
100+
* Try to emit onError callback.
101+
*
102+
* @param int $code
103+
* @param string $msg
104+
* @return void
105+
*/
106+
protected function emitError($code, $msg)
107+
{
108+
if ($this->onError) {
109+
try {
110+
call_user_func($this->onError, $this, $code, $msg);
111+
} catch (\Exception $e) {
112+
echo $e;
113+
exit(250);
114+
} catch (\Error $e) {
115+
echo $e;
116+
exit(250);
117+
}
118+
}
119+
}
120+
121+
/**
122+
* Check connection is successfully established or faild.
123+
*
124+
* @param resource $socket
125+
* @return void
126+
*/
127+
public function checkConnection($socket)
128+
{
129+
// Check socket state.
130+
if (stream_socket_get_name($socket, true)) {
131+
// Remove write listener.
132+
Worker::$globalEvent->del($socket, EventInterface::EV_WRITE);
133+
// Nonblocking.
134+
stream_set_blocking($socket, 0);
135+
// Try to open keepalive for tcp and disable Nagle algorithm.
136+
if (function_exists('socket_import_stream')) {
137+
$raw_socket = socket_import_stream($socket);
138+
socket_set_option($raw_socket, SOL_SOCKET, SO_KEEPALIVE, 1);
139+
socket_set_option($raw_socket, SOL_TCP, TCP_NODELAY, 1);
140+
}
141+
// Register a listener waiting read event.
142+
Worker::$globalEvent->add($socket, EventInterface::EV_READ, array($this, 'baseRead'));
143+
// There are some data waiting to send.
144+
if ($this->_sendBuffer) {
145+
Worker::$globalEvent->add($socket, EventInterface::EV_WRITE, array($this, 'baseWrite'));
146+
}
147+
$this->_status = self::STATUS_ESTABLISH;
148+
$this->_remoteAddress = stream_socket_get_name($socket, true);
149+
// Try to emit onConnect callback.
150+
if ($this->onConnect) {
151+
try {
152+
call_user_func($this->onConnect, $this);
153+
} catch (\Exception $e) {
154+
echo $e;
155+
exit(250);
156+
} catch (\Error $e) {
157+
echo $e;
158+
exit(250);
159+
}
160+
}
161+
} else {
162+
// Connection failed.
163+
$this->emitError(WORKERMAN_CONNECT_FAIL, 'connect fail');
164+
$this->destroy();
165+
$this->onConnect = null;
166+
}
167+
}
168+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* This file is part of workerman.
4+
*
5+
* Licensed under The MIT License
6+
* For full copyright and license information, please see the MIT-LICENSE.txt
7+
* Redistributions of files must retain the above copyright notice.
8+
*
9+
* @author walkor<walkor@workerman.net>
10+
* @copyright walkor<walkor@workerman.net>
11+
* @link http://www.workerman.net/
12+
* @license http://www.opensource.org/licenses/mit-license.php MIT License
13+
*/
14+
namespace Workerman\Connection;
15+
16+
/**
17+
* ConnectionInterface.
18+
*/
19+
abstract class ConnectionInterface
20+
{
21+
/**
22+
* Statistics for status command.
23+
*
24+
* @var array
25+
*/
26+
public static $statistics = array(
27+
'connection_count' => 0,
28+
'total_request' => 0,
29+
'throw_exception' => 0,
30+
'send_fail' => 0,
31+
);
32+
33+
/**
34+
* Emitted when data is received.
35+
*
36+
* @var callback
37+
*/
38+
public $onMessage = null;
39+
40+
/**
41+
* Emitted when the other end of the socket sends a FIN packet.
42+
*
43+
* @var callback
44+
*/
45+
public $onClose = null;
46+
47+
/**
48+
* Emitted when an error occurs with connection.
49+
*
50+
* @var callback
51+
*/
52+
public $onError = null;
53+
54+
/**
55+
* Sends data on the connection.
56+
*
57+
* @param string $send_buffer
58+
* @return void|boolean
59+
*/
60+
abstract public function send($send_buffer);
61+
62+
/**
63+
* Get remote IP.
64+
*
65+
* @return string
66+
*/
67+
abstract public function getRemoteIp();
68+
69+
/**
70+
* Get remote port.
71+
*
72+
* @return int
73+
*/
74+
abstract public function getRemotePort();
75+
76+
/**
77+
* Close connection.
78+
*
79+
* @param $data
80+
* @return void
81+
*/
82+
abstract public function close($data = null);
83+
}

0 commit comments

Comments
 (0)