2727namespace PhpBg \Rtsp ;
2828
2929use Evenement \EventEmitter ;
30+ use PhpBg \Rtsp \Message \MessageFactory ;
3031use PhpBg \Rtsp \Message \Request ;
3132use PhpBg \Rtsp \Message \RequestParser ;
3233use PhpBg \Rtsp \Message \Response ;
34+ use React \Promise \FulfilledPromise ;
35+ use React \Promise \PromiseInterface ;
3336use React \Socket \ConnectionInterface ;
3437use React \Socket \ServerInterface ;
3538
@@ -56,7 +59,10 @@ class Server extends EventEmitter
5659 /**
5760 * Server constructor
5861 *
59- * @param callable $callback Callback that will receive (Request, React\Socket\ConnectionInterface) and may return a Response
62+ * @param callable $callback
63+ * Callback that will receive (PhpBg\Rtsp\Message\Request, React\Socket\ConnectionInterface) and return
64+ * * a PhpBg\Rtsp\Message\Response
65+ * * a React\Promise\PromiseInterface that will resolve in a Response
6066 */
6167 public function __construct (Callable $ callback )
6268 {
@@ -120,12 +126,33 @@ protected function handleRequest(Request $request, ConnectionInterface $connecti
120126 $ this ->emit ('error ' , [$ e ]);
121127 return ;
122128 }
123- if (isset ($ response )) {
124- if ($ response instanceof Response) {
125- $ connection ->write ($ response ->toTransport ());
129+ // Convert all non-promise response to promises
130+ // There is little overhead for this, but this allows simpler code
131+ if (!isset ($ response ) || !$ response instanceof PromiseInterface) {
132+ $ response = new FulfilledPromise ($ response );
133+ }
134+
135+ $ response ->done (function ($ resolvedResponse ) use ($ connection ) {
136+ if ($ resolvedResponse instanceof Response) {
137+ $ connection ->write ($ resolvedResponse ->toTransport ());
126138 return ;
127139 }
128- $ this ->emit ('error ' , [new ServerException ("Your handler did return something, but it wasn't a Response " )]);
129- }
140+ $ message = 'The response callback is expected to resolve with an object implementing PhpBg\Rtsp\Message\Response, but resolved with "%s" instead. ' ;
141+ $ message = sprintf ($ message , is_object ($ resolvedResponse ) ? get_class ($ resolvedResponse ) : gettype ($ resolvedResponse ));
142+ $ this ->emit ('error ' , [new ServerException ($ message )]);
143+ }, function ($ error ) use ($ connection ) {
144+ $ message = 'The response callback is expected to resolve with an object implementing PhpBg\Rtsp\Message\Response, but rejected with "%s" instead. ' ;
145+ $ message = sprintf ($ message , is_object ($ error ) ? get_class ($ error ) : gettype ($ error ));
146+ $ previous = null ;
147+ if ($ error instanceof \Throwable || $ error instanceof \Exception) {
148+ $ previous = $ error ;
149+ }
150+ $ exception = new \RuntimeException ($ message , null , $ previous );
151+ $ this ->emit ('error ' , [$ exception ]);
152+
153+ $ rtspResponse = MessageFactory::response (500 , [], null , 'internal server error ' );
154+ $ connection ->write ($ rtspResponse ->toTransport ());
155+ });
130156 }
157+
131158}
0 commit comments