16
16
use Pusher \Pusher ;
17
17
use Ratchet \ConnectionInterface ;
18
18
use Ratchet \Http \HttpServerInterface ;
19
+ use React \Promise \PromiseInterface ;
19
20
use Symfony \Bridge \PsrHttpMessage \Factory \HttpFoundationFactory ;
20
21
use Symfony \Component \HttpKernel \Exception \HttpException ;
21
22
@@ -30,7 +31,7 @@ abstract class Controller implements HttpServerInterface
30
31
/** @var int */
31
32
protected $ contentLength ;
32
33
33
- /** @var \BeyondCode\LaravelWebSockets\WebSockets\Channels\ ChannelManager */
34
+ /** @var ChannelManager */
34
35
protected $ channelManager ;
35
36
36
37
public function __construct (ChannelManager $ channelManager )
@@ -46,7 +47,11 @@ public function onOpen(ConnectionInterface $connection, RequestInterface $reques
46
47
47
48
$ this ->requestBuffer = (string ) $ request ->getBody ();
48
49
49
- $ this ->checkContentLength ($ connection );
50
+ if (! $ this ->verifyContentLength ()) {
51
+ return ;
52
+ }
53
+
54
+ $ this ->handleRequest ($ connection );
50
55
}
51
56
52
57
protected function findContentLength (array $ headers ): int
@@ -60,31 +65,53 @@ public function onMessage(ConnectionInterface $from, $msg)
60
65
{
61
66
$ this ->requestBuffer .= $ msg ;
62
67
63
- $ this ->checkContentLength ($ from );
68
+ if (! $ this ->verifyContentLength ()) {
69
+ return ;
70
+ }
71
+
72
+ $ this ->handleRequest ($ from );
73
+ }
74
+
75
+ protected function verifyContentLength ()
76
+ {
77
+ return strlen ($ this ->requestBuffer ) === $ this ->contentLength ;
64
78
}
65
79
66
- protected function checkContentLength (ConnectionInterface $ connection )
80
+ protected function handleRequest (ConnectionInterface $ connection )
67
81
{
68
- if (strlen ($ this ->requestBuffer ) === $ this ->contentLength ) {
69
- $ serverRequest = (new ServerRequest (
70
- $ this ->request ->getMethod (),
71
- $ this ->request ->getUri (),
72
- $ this ->request ->getHeaders (),
73
- $ this ->requestBuffer ,
74
- $ this ->request ->getProtocolVersion ()
75
- ))->withQueryParams (QueryParameters::create ($ this ->request )->all ());
82
+ $ serverRequest = (new ServerRequest (
83
+ $ this ->request ->getMethod (),
84
+ $ this ->request ->getUri (),
85
+ $ this ->request ->getHeaders (),
86
+ $ this ->requestBuffer ,
87
+ $ this ->request ->getProtocolVersion ()
88
+ ))->withQueryParams (QueryParameters::create ($ this ->request )->all ());
89
+
90
+ $ laravelRequest = Request::createFromBase ((new HttpFoundationFactory )->createRequest ($ serverRequest ));
76
91
77
- $ laravelRequest = Request::createFromBase ((new HttpFoundationFactory )->createRequest ($ serverRequest ));
92
+ $ this
93
+ ->ensureValidAppId ($ laravelRequest ->appId )
94
+ ->ensureValidSignature ($ laravelRequest );
78
95
79
- $ this
80
- ->ensureValidAppId ($ laravelRequest ->appId )
81
- ->ensureValidSignature ($ laravelRequest );
96
+ // Invoke the controller action
97
+ $ response = $ this ($ laravelRequest );
82
98
83
- $ response = $ this ($ laravelRequest );
99
+ // Allow for async IO in the controller action
100
+ if ($ response instanceof PromiseInterface) {
101
+ $ response ->then (function ($ response ) use ($ connection ) {
102
+ $ this ->sendAndClose ($ connection , $ response );
103
+ });
84
104
85
- $ connection ->send (JsonResponse::create ($ response ));
86
- $ connection ->close ();
105
+ return ;
87
106
}
107
+
108
+ $ this ->sendAndClose ($ connection , $ response );
109
+ }
110
+
111
+ protected function sendAndClose (ConnectionInterface $ connection , $ response )
112
+ {
113
+ $ connection ->send (JsonResponse::create ($ response ));
114
+ $ connection ->close ();
88
115
}
89
116
90
117
public function onClose (ConnectionInterface $ connection )
@@ -122,7 +149,7 @@ protected function ensureValidSignature(Request $request)
122
149
/*
123
150
* The `auth_signature` & `body_md5` parameters are not included when calculating the `auth_signature` value.
124
151
*
125
- * The `appId`, `appKey` & `channelName` parameters are actually route paramaters and are never supplied by the client.
152
+ * The `appId`, `appKey` & `channelName` parameters are actually route parameters and are never supplied by the client.
126
153
*/
127
154
$ params = Arr::except ($ request ->query (), ['auth_signature ' , 'body_md5 ' , 'appId ' , 'appKey ' , 'channelName ' ]);
128
155
0 commit comments