| 
<?php
 /**
 * This file is part of the PHP Generics package.
 *
 * @package Generics
 */
 namespace Generics\Socket;
 
 /**
 * This class provides a basic client socket implementation
 *
 * @author Maik Greubel <[email protected]>
 */
 class ServerSocket extends Socket
 {
 
 /**
 * Create a new server socket
 *
 * @param Endpoint $endpoint
 *            The endpoint to use
 *
 * @throws SocketException In case of creation of socket has failed or socket options could not be set.
 */
 public function __construct(Endpoint $endpoint)
 {
 parent::__construct($endpoint);
 if (! @socket_set_option($this->handle, SOL_SOCKET, SO_REUSEADDR, 1)) {
 $code = socket_last_error($this->handle);
 throw new SocketException(socket_strerror($code), array(), $code);
 }
 }
 
 /**
 * Creates a service at the given endpoint
 *
 * @throws SocketException in case of it is not possible to serve due to binding or listening error
 */
 public function serve(ServiceCallback $callback)
 {
 $this->bind();
 
 $this->listen();
 
 $runOn = true;
 
 while ($runOn) {
 $clientHandle = @socket_accept($this->handle);
 
 if (! is_resource($clientHandle)) {
 $code = socket_last_error($this->handle);
 throw new SocketException(socket_strerror($code), array(), $code);
 }
 
 $address = null;
 $port = 0;
 if (! @socket_getpeername($clientHandle, $address, $port)) {
 $code = socket_last_error($clientHandle);
 throw new SocketException(socket_strerror($code), array(), $code);
 }
 
 $client = new ClientSocket(new Endpoint($address, $port), $clientHandle);
 
 $runOn = boolval($callback->callback($client));
 }
 }
 
 /**
 * Bind the server socket to the given endpoint
 *
 * @throws SocketException in case of binding has failed
 */
 private function bind()
 {
 if (! @socket_bind($this->handle, $this->endpoint->getAddress(), $this->endpoint->getPort())) {
 $code = socket_last_error($this->handle);
 throw new SocketException(socket_strerror($code), array(), $code);
 }
 }
 
 /**
 * Listen to the binded socket endpoint
 *
 * @throws SocketException in case of listening is not possible
 */
 private function listen()
 {
 if (! @socket_listen($this->handle, 5)) {
 $code = socket_last_error($this->handle);
 throw new SocketException(socket_strerror($code), array(), $code);
 }
 }
 }
 
 |