@@ -49,7 +49,12 @@ final class Connection
4949 private $ lastWrite = 0 ;
5050
5151 /**
52- * @var string|null
52+ * @var int
53+ */
54+ private $ lastRead = 0 ;
55+
56+ /**
57+ * @var string
5358 */
5459 private $ heartbeatWatcherId ;
5560
@@ -126,6 +131,7 @@ function () use ($timeout, $maxAttempts, $noDelay) {
126131 }
127132
128133 $ this ->socket = yield connect ($ this ->uri , $ context );
134+ $ this ->lastRead = Loop::now ();
129135
130136 asyncCall (
131137 function () {
@@ -138,6 +144,7 @@ function () {
138144
139145 while ($ frame = $ this ->parser ->parse ()) {
140146 $ class = \get_class ($ frame );
147+ $ this ->lastRead = Loop::now ();
141148
142149 /**
143150 * @psalm-var callable(AbstractFrame):Promise<bool> $callback
@@ -157,18 +164,14 @@ function () {
157164 );
158165 }
159166
160- public function heartbeat (int $ interval ): void
167+ public function heartbeat (int $ interval, ? callable $ connectionLost = null ): void
161168 {
162169 $ this ->heartbeatWatcherId = Loop::repeat (
163170 $ interval ,
164- function (string $ watcherId ) use ($ interval ) {
165- if ($ this ->socket === null ) {
166- Loop::cancel ($ watcherId );
167-
168- return ;
169- }
171+ function ($ watcherId ) use ($ interval , $ connectionLost ){
172+ $ currentTime = Loop::now ();
170173
171- $ currentTime = Loop:: now ();
174+ if ( null !== $ this -> socket ) {
172175 $ lastWrite = $ this ->lastWrite ?: $ currentTime ;
173176
174177 $ nextHeartbeat = $ lastWrite + $ interval ;
@@ -182,9 +185,18 @@ function (string $watcherId) use ($interval) {
182185 );
183186 }
184187
185- unset($ currentTime , $ lastWrite , $ nextHeartbeat );
188+ unset($ lastWrite , $ nextHeartbeat );
186189 }
187- );
190+
191+ if (null !== $ connectionLost && 0 !== $ this ->lastRead ) {
192+ if ($ currentTime > ($ this ->lastRead + $ interval + 1000 )) {
193+ $ connectionLost ();
194+ Loop::cancel ($ watcherId );
195+ }
196+ }
197+
198+ unset($ currentTime );
199+ });
188200 }
189201
190202 public function close (): void
0 commit comments