-
Notifications
You must be signed in to change notification settings - Fork 0
/
mengo.php
executable file
·120 lines (108 loc) · 3.24 KB
/
mengo.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/local/bin/php -q
<?php
define( 'MONGODB_HOST', 'localhost' );
define( 'MONGODB_PORT', 27018 );
// listen only on hostname interface
// define( 'LISTEN_HOST', trim( shell_exec( 'hostname -i' ) ) );
// listen on every interface (some php versions perfer NULL instead of 0)
define( 'LISTEN_HOST', 0 );
define( 'LISTEN_PORT', 7734 );
error_reporting( E_ALL ^ E_NOTICE );
set_time_limit( 0 );
ob_implicit_flush();
require_once( 'System/Daemon.php' );
System_Daemon::setOptions( array(
'appName' => 'mongodaemon',
'appDir' => dirname(__FILE__),
'appDescription' => 'memcache socket server for mongodb',
'authorName' => 'mengo',
'authorEmail' => '[email protected]',
'logLocation' => '/dev/null'
));
System_Daemon::setSigHandler( SIGTERM, 'sigterm' );
function sigterm( $signal ){ if( $signal === SIGTERM ) { System_Daemon::stop(); } }
// Spawn Deamon!
System_Daemon::start();
$connected = false;
function mconnect() {
global $mongo, $connected;
if( $connected ) {
return true;
}
else {
$connected = false;
$mongo = new Mongo( MONGODB_HOST.':'.MONGODB_PORT, array( 'timeout' => 2000 ) );
if( $mongo->connect() ) {
$connected = true;
return true;
}
}
}
function msg( $socket, $buf ) {
global $mongo, $connected;
$buf = explode( ' ', $buf );
$cmd = $buf[0];
if( $cmd == 'get' ) {
$key = trim( (string)$buf[1] );
$key = trim( $key );
$chunk = explode( '|', $key );
$database = $chunk[0];
$collection = $chunk[1];
$query = json_decode( $chunk[2], true );
if( mconnect() && !empty( $database ) && !empty( $collection ) ) {
$database = $mongo->selectDB( $database );
$collection = $database->selectCollection( $collection );
$result = $collection->find( $query );
$data = array();
foreach( $result as $d ) {
if( is_array( $d ) ) {
$data[] = $d;
}
}
$data = json_encode( $data );
}
$msg = 'VALUE '.$key.' 0 '.strlen( $data )."\r\n".$data."\r\nEND\r\n";
} else {
$msg = "ERROR\r\n";
}
socket_write( $socket, $msg );
}
if( ( $master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP ) ) < 0 ) {
echo "socket_create() failed, reason: " . socket_strerror($master) . "\n";
}
socket_set_option( $master, SOL_SOCKET,SO_REUSEADDR, 1 );
if( ( $ret = socket_bind( $master, LISTEN_HOST, LISTEN_PORT ) ) < 0 ) {
echo "socket_bind() failed, reason: " . socket_strerror($ret) . "\n";
}
if( ( $ret = socket_listen( $master, 5 ) ) < 0 ) {
echo "socket_listen() failed, reason: " . socket_strerror($ret) . "\n";
}
$read_sockets = array( $master );
while( true ) {
$changed_sockets = $read_sockets;
$num_changed_sockets = socket_select( $changed_sockets, $write = NULL, $except = NULL, NULL );
foreach( $changed_sockets as $socket ) {
if( $socket == $master ) {
if( ( $client = socket_accept( $master ) ) < 0 ) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
continue;
}
else {
array_push( $read_sockets, $client );
}
}
else {
$bytes = socket_recv( $socket, $buffer, 1024, 0 );
if( $bytes == 0 ) {
$index = array_search( $socket, $read_sockets );
unset( $read_sockets[$index] );
socket_close( $socket );
}
else {
msg( $socket, $buffer );
}
}
}
}
System_Daemon::stop();
?>