1+ #!/php -q
2+ <?php
3+ /*
4+
5+ Run from command line:
6+ > php -q server.php
7+
8+ */
9+
10+ session_start ();
11+ error_reporting (E_ALL );
12+ set_time_limit (0 );
13+ ob_implicit_flush ();
14+
15+ echo "Initiating... \n" ;
16+ $ address = 'localhost ' ;
17+ $ port = 12345 ;
18+ $ maxconn = 999 ;
19+ $ uselog = true ;
20+
21+ if (($ master =socket_create (AF_INET ,SOCK_STREAM ,SOL_TCP ))<0 ){
22+ die ("socket_create() failed, reason: " .socket_strerror ($ master ));
23+ }
24+ socket_set_option ($ master ,SOL_SOCKET ,SO_REUSEADDR ,1 );
25+ if (($ ret =socket_bind ($ master ,$ address ,$ port ))<0 ){
26+ die ("socket_bind() failed, reason: " .socket_strerror ($ ret ));
27+ }
28+ if (($ ret =socket_listen ($ master ,5 ))<0 ){
29+ die ("socket_listen() failed, reason: " .socket_strerror ($ ret ));
30+ }
31+
32+ echo "Server Started : " .date ('Y-m-d H:i:s ' )."\n" ;
33+ echo "Max connections: " .$ maxconn ."\n" ;
34+ echo "Master socket : " .$ master ."\n" ;
35+ echo "Listening on : " .$ address ." port " .$ port ."\n" ;
36+
37+ $ users = array ();
38+ $ allsockets = array ($ master );
39+ $ handshake = false ;
40+
41+ while (true ){
42+ $ changed_sockets = $ allsockets ;
43+ $ num_sockets = socket_select ($ changed_sockets ,$ write =NULL ,$ except =NULL ,NULL );
44+ foreach ($ changed_sockets as $ socket ){
45+ console ();
46+ if ($ socket ==$ master ) {
47+ if (($ client =socket_accept ($ master ))<0 ) {
48+ console ("socket_accept() failed: reason: " .socket_strerror (socket_last_error ($ client )));
49+ continue ;
50+ }
51+ else {
52+ array_push ($ allsockets ,$ client );
53+ console ($ client ." CONNECTED! " );
54+ }
55+ }
56+ else {
57+ $ bytes = @socket_recv ($ socket ,$ buffer ,2048 ,0 );
58+ if ($ bytes ==0 ){ disconnected ($ socket ); }
59+ else {
60+
61+ /* TODO: store handshake per socket */
62+ if (!$ handshake ){
63+ console ("\nRequesting handshake... " );
64+ console ($ buffer );
65+ /*
66+ GET {resource} HTTP/1.1
67+ Upgrade: WebSocket
68+ Connection: Upgrade
69+ Host: {host}
70+ Origin: {origin}
71+ \r\n
72+ */
73+ list ($ resource ,$ host ,$ origin ) = getheaders ($ buffer );
74+ //$resource = "/websocket/server.php";
75+ //$host = "localhost:12345";
76+ //$origin = "http://localhost";
77+ console ("Handshaking... " );
78+ $ upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake \r\n" .
79+ "Upgrade: WebSocket \r\n" .
80+ "Connection: Upgrade \r\n" .
81+ "WebSocket-Origin: " . $ origin . "\r\n" .
82+ "WebSocket-Location: ws:// " . $ host . $ resource . "\r\n" .
83+ "\r\n" ;
84+ $ handshake = true ;
85+ socket_write ($ client ,$ upgrade .chr (0 ),strlen ($ upgrade .chr (0 )));
86+ console ($ upgrade );
87+ console ("Done handshaking... " );
88+ }
89+ else {
90+ console ("< " .$ buffer );
91+ $ action = substr ($ buffer ,1 ,$ bytes -2 ); // remove chr(0) and chr(255)
92+ switch ($ action ){
93+ case "hello " : send ($ socket ,"hello human " ); break ;
94+ case "hi " : send ($ socket ,"zup human " ); break ;
95+ case "name " : send ($ socket ,"my name is Multivac, silly I know " ); break ;
96+ case "age " : send ($ socket ,"I am older than time itself " ); break ;
97+ case "date " : send ($ socket ,"Today is " .date ("Y.m.d " )); break ;
98+ case "time " : send ($ socket ,"Server time is " .date ("H:i:s " )); break ;
99+ case "thanks " : send ($ socket ,"you're welcome " ); break ;
100+ case "bye " : send ($ socket ,"bye " ); break ;
101+ default : send ($ socket ,$ action ." not understood " ); break ;
102+ }
103+ }
104+ }
105+ }
106+ }
107+ }
108+
109+ //---------------------------------------------------------------
110+ function wrap ($ msg ){ return chr (0 ).$ msg .chr (255 ); }
111+
112+ function send ($ client ,$ msg ){
113+ console ("> " .$ msg );
114+ $ msg = wrap ($ msg );
115+ socket_write ($ client ,$ msg ,strlen ($ msg ));
116+ }
117+
118+ function disconnected ($ socket ){
119+ global $ allsockets ;
120+ $ index = array_search ($ socket , $ allsockets );
121+ if ($ index >=0 ){ unset($ allsockets [$ index ]); }
122+ socket_close ($ socket );
123+ console ($ socket ." disconnected! " );
124+ }
125+
126+ function console ($ msg ="" ){
127+ global $ uselog ;
128+ if ($ uselog ){ echo $ msg ."\n" ; }
129+ }
130+
131+ function getheaders ($ req ){
132+ $ req = substr ($ req ,4 ); /* RegEx kill babies */
133+ $ res = substr ($ req ,0 ,strpos ($ req ," HTTP " ));
134+ $ req = substr ($ req ,strpos ($ req ,"Host: " )+6 );
135+ $ host = substr ($ req ,0 ,strpos ($ req ,"\r\n" ));
136+ $ req = substr ($ req ,strpos ($ req ,"Origin: " )+8 );
137+ $ ori = substr ($ req ,0 ,strpos ($ req ,"\r\n" ));
138+ return array ($ res ,$ host ,$ ori );
139+ }
140+ ?>
0 commit comments