1
+ <?php
2
+
3
+ /*!
4
+ * Open Realtime Connectivity JavaScript Library
5
+ *
6
+ * Copyright 2011, IBT, SA
7
+ *
8
+ * ORTC is part of our framework and it's powered by the world's first Real-Time Web Platform by IBT
9
+ *
10
+ * Join our movement to transform the World Wide Web into the Real-Time Web!
11
+ *
12
+ * Interested in Real-Time technology? See what we can do for your business today.
13
+ *
14
+ * Transform your old website into an exciting Real-Time experience!
15
+ *
16
+ * Improve the interaction with your visitor to a level never seen before
17
+ * and increase visitor recurrency and loyalty.
18
+ *
19
+ * Visit us at www.realtime.co and learn more.
20
+ *
21
+ * Date: Thu Dec 05 2013 v2.1.12
22
+ */
23
+
24
+ class Request {
25
+ static function execute ($ method , $ url , $ data =array (), $ referer ='' , $ timeout =30 , $ user_agent ='' ){
26
+ // Convert the data array into URL Parameters like a=b&foo=bar etc.
27
+ $ data = http_build_query ($ data );
28
+ // parse the given URL
29
+ $ url = parse_url ($ url );
30
+ // extract host and path
31
+ $ host = $ url ['host ' ];
32
+ $ path = isset ($ url ['path ' ]) ? $ url ['path ' ] : '' ;
33
+
34
+ if (trim ($ host )=="" ){
35
+ return array (
36
+ 'errcode ' => -2 ,
37
+ 'status ' => 'err ' ,
38
+ 'error ' => "Error: (parse_url) Host is empty "
39
+ );
40
+ }
41
+
42
+ if ($ url ['scheme ' ] == 'http ' ){
43
+ $ port = 80 ;
44
+ $ protocol = '' ;
45
+ }else {
46
+ $ port = 443 ;
47
+ $ protocol = 'ssl:// ' ;
48
+ }
49
+ // open a socket connection - timeout: 30 sec
50
+ $ fp = fsockopen ($ protocol .$ host , $ port , $ errno , $ errstr , $ timeout );
51
+ if ($ fp ) {
52
+ // send the request headers:
53
+ fputs ($ fp , "$ method $ path HTTP/1.1 \r\n" );
54
+ fputs ($ fp , "host: $ host \r\n" );
55
+ if ($ referer != '' ) fputs ($ fp , "Referer: $ referer \r\n" );
56
+ if ($ method == 'POST ' ){
57
+ fputs ($ fp , "Content-type: application/x-www-form-urlencoded \r\n" );
58
+ fputs ($ fp , "Content-length: " . strlen ($ data ) . "\r\n" );
59
+ }
60
+ fputs ($ fp , "Connection: close \r\n\r\n" );
61
+ fputs ($ fp , $ data );
62
+ $ result = '' ;
63
+ while (!feof ($ fp )){
64
+ // receive the results of the request
65
+ $ result .= fgets ($ fp , 128 );
66
+ }
67
+ } else {
68
+ return array (
69
+ 'errcode ' => -3 ,
70
+ 'status ' => 'err ' ,
71
+ 'error ' => "$ errstr ( $ errno) "
72
+ );
73
+ }
74
+ // close the socket connection:
75
+ fclose ($ fp );
76
+
77
+ // split the result header from the content
78
+ $ result = explode ("\r\n\r\n" , $ result , 2 );
79
+
80
+ $ header = isset ($ result [0 ]) ? $ result [0 ] : '' ;
81
+ $ content = isset ($ result [1 ]) ? $ result [1 ] : '' ;
82
+
83
+ // be carefull with HTTP1.1 (nginx)
84
+ if (preg_match ('/Transfer-Encoding: chunked/i ' , $ header )){
85
+ $ chunks = explode ("\n" , $ content );
86
+ if (count ($ chunks )>1 ){
87
+ foreach ($ chunks as $ line => $ data ){
88
+ if ($ line %2 == 0 ) unset($ chunks [$ line ]);
89
+
90
+ }
91
+ array_pop ($ chunks );
92
+ $ content = implode ("\n" , $ chunks );
93
+ } else
94
+ $ content = $ result [1 ];
95
+ }
96
+ if ( ! preg_match ('/^HTTP\/1.1 ([0-9]{3})/ ' , $ header , $ matches )){
97
+
98
+ return array (
99
+ 'errcode ' => -4 ,
100
+ 'status ' => 'err ' ,
101
+ 'error ' => 'Error: failed to localize http 1.1 in the result header ' ,
102
+ 'response ' => $ result
103
+ );
104
+ };
105
+
106
+ if ( !$ matches [1 ] || $ matches [1 ][0 ] !=='2 ' ){
107
+ return array (
108
+ 'errcode ' => -5 ,
109
+ 'status ' => 'err ' ,
110
+ 'error ' => "Error: response was not successful " ,
111
+ 'response ' => $ result
112
+ );
113
+ }
114
+
115
+ // return as structured array:
116
+ return array (
117
+ 'errcode ' => 0 ,
118
+ 'status ' => 'ok ' ,
119
+ 'header ' => $ header ,
120
+ 'content ' => $ content
121
+ );
122
+ }
123
+
124
+ }
125
+
126
+ class Realtime{
127
+ private $ ortc_data ;
128
+ private $ is_version_21 ;
129
+
130
+ function __construct ($ balancer , $ app_key , $ priv_key , $ token ){
131
+
132
+ $ arg_list = func_get_args ();
133
+ if (count ($ arg_list )<4 ) die ("ERROR: Some of constructor's parameters are missing. " );
134
+ foreach ( $ arg_list as $ idx =>$ val )
135
+ if ( trim ($ val ) == "" )
136
+ die ("ERROR: parameters ' $ idx' is not specified. " );
137
+
138
+ $ strpos_res = strpos ( $ balancer , "2.1 " );
139
+ $ this ->is_version_21 = ($ strpos_res > 0 );
140
+
141
+ $ this ->ortc_data ['balancer ' ] = $ balancer ;
142
+ $ this ->ortc_data ['app_key ' ] = $ app_key ;
143
+ $ this ->ortc_data ['priv_key ' ] = $ priv_key ;
144
+ $ this ->ortc_data ['token ' ] = $ token ;
145
+ }
146
+
147
+
148
+ private function _get_server (){
149
+ $ url = $ this ->ortc_data ['balancer ' ].'?appkey= ' .$ this ->ortc_data ['app_key ' ];
150
+ $ balancer_response = Request::execute ("GET " ,$ url );
151
+ if ($ balancer_response ['errcode ' ] != 0 ){
152
+ die ('Error getting data from balancer! ' .$ balancer_response ['error ' ].' Response: ' .print_r ($ balancer_response ['response ' ],true ));
153
+ }
154
+ // error
155
+ if (!preg_match ('/https?:\/\/[^\"]+/ ' , $ balancer_response ['content ' ], $ matches )){
156
+ return '' ;
157
+ }
158
+ if ('http://undefined:undefined ' == $ matches [0 ]) return '' ;
159
+
160
+ // success
161
+ return $ matches [0 ];
162
+ }
163
+
164
+ private function send_message_part ($ url , $ channel , $ msg , &$ response = Array () ){
165
+ $ message = array (
166
+ 'AK ' => $ this ->ortc_data ['app_key ' ],
167
+ 'PK ' => $ this ->ortc_data ['priv_key ' ],
168
+ 'AT ' => $ this ->ortc_data ['token ' ],
169
+ 'C ' => $ channel ,
170
+ 'M ' => $ msg
171
+ );
172
+
173
+ $ content = Request::execute ("POST " ,$ url . '/send/ ' , $ message );
174
+
175
+ $ response = $ content ;
176
+
177
+ return ( $ content ['errcode ' ] == 0 );
178
+ }
179
+
180
+ public function send ($ channel , $ msg , &$ response = Array () ){
181
+
182
+ $ url = $ this ->_get_server ();
183
+
184
+ if (!$ url || $ url == "" ) return false ; // no server available
185
+
186
+ $ numberOfParts = ((int )(strlen ($ msg ) / 700 )) + ((strlen ($ msg ) % 700 == 0 )? 0 : 1 );
187
+ $ guid = substr (uniqid (),5 ,8 );
188
+
189
+ if ($ numberOfParts > 1 ){
190
+ $ part = 1 ;
191
+
192
+
193
+ while ($ part <= $ numberOfParts ){
194
+
195
+ $ ret = $ this ->send_message_part ($ url , $ channel , $ guid ."_ " .$ part ."- " .$ numberOfParts ."_ " .substr ($ msg ,($ part -1 ) * 699 , 699 ), $ response ); // $response returned used for debug purposes
196
+ if (!$ ret ) return false ;
197
+
198
+ $ part = $ part + 1 ;
199
+
200
+ }
201
+
202
+ return true ;
203
+ }
204
+ else
205
+ {
206
+ $ ret = $ this ->send_message_part ($ url ,$ channel ,$ guid ."_1-1_ " .$ msg ,$ response ); // returning $response for debug purpose
207
+ return $ ret ;
208
+ }
209
+ }
210
+
211
+
212
+ public function auth ($ channels , $ private = 0 , $ expire_time = 180000 , &$ response = Array () ){
213
+
214
+ // post permissions
215
+ $ fields = array (
216
+ 'AK ' => $ this ->ortc_data ['app_key ' ],
217
+ 'PK ' => $ this ->ortc_data ['priv_key ' ],
218
+ 'AT ' => $ this ->ortc_data ['token ' ], //access token
219
+ 'PVT ' => $ private ,
220
+ 'TTL ' => $ expire_time ,
221
+ 'TP ' => count ($ channels ) // total num of channels
222
+ );
223
+
224
+ foreach ($ channels as $ channel => $ perms ){
225
+ $ fields [$ channel ] = $ perms ;
226
+ }
227
+ $ url = $ this ->_get_server ();
228
+ if (!$ url ) return false ; // no server available
229
+
230
+ $ auth_path = '/authenticate ' ;
231
+
232
+ $ content = Request::execute ('POST ' , $ url .$ auth_path , $ fields , $ referer ='' , 15 , 'ortc-php ' ); // /auth or /authenticate depends on the server version
233
+
234
+ $ response = $ content ;
235
+
236
+ return ( $ content ['errcode ' ] == 0 );
237
+ }
238
+
239
+ }
240
+ ?>
0 commit comments