Skip to content

Commit 8d9fd71

Browse files
Fixed memory leak when websocket hande shake failed. (#2768)
* 修复websocket握手失败不会释放WsContext中set的值而导致内存泄漏的问题 * Update Server.php * Update CHANGELOG-2.0.md Co-authored-by: 李铭昕 <715557344@qq.com>
1 parent d73d89c commit 8d9fd71

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

src/Server.php

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -165,37 +165,41 @@ public function onHandShake(SwooleRequest $request, SwooleResponse $response): v
165165

166166
$class = $psr7Response->getAttribute('class');
167167

168-
if (! empty($class)) {
169-
FdCollector::set($fd, $class);
170-
$server = $this->getServer();
171-
if ($server instanceof \Swoole\Coroutine\Http\Server) {
172-
$response->upgrade();
173-
$this->getSender()->setResponse($fd, $response);
174-
$this->deferOnOpen($request, $class, $response);
175-
176-
[, , $callbacks] = ServerManager::get($this->serverName);
177-
178-
[$onMessageCallbackClass, $onMessageCallbackMethod] = $callbacks[SwooleEvent::ON_MESSAGE];
179-
$onMessageCallbackInstance = $this->container->get($onMessageCallbackClass);
180-
181-
[$onCloseCallbackClass, $onCloseCallbackMethod] = $callbacks[SwooleEvent::ON_CLOSE];
182-
$onCloseCallbackInstance = $this->container->get($onCloseCallbackClass);
183-
184-
while (true) {
185-
$frame = $response->recv();
186-
if ($frame === false || $frame instanceof CloseFrame || $frame === '') {
187-
$onCloseCallbackInstance->{$onCloseCallbackMethod}($response, $fd, 0);
188-
break;
189-
}
190-
$onMessageCallbackInstance->{$onMessageCallbackMethod}($response, $frame);
168+
if (empty($class)) {
169+
throw new WebSocketHandeShakeException('WebSocket hande shake failed, because the class does not exists.');
170+
}
171+
172+
FdCollector::set($fd, $class);
173+
$server = $this->getServer();
174+
if ($server instanceof \Swoole\Coroutine\Http\Server) {
175+
$response->upgrade();
176+
$this->getSender()->setResponse($fd, $response);
177+
$this->deferOnOpen($request, $class, $response);
178+
179+
[, , $callbacks] = ServerManager::get($this->serverName);
180+
181+
[$onMessageCallbackClass, $onMessageCallbackMethod] = $callbacks[SwooleEvent::ON_MESSAGE];
182+
$onMessageCallbackInstance = $this->container->get($onMessageCallbackClass);
183+
184+
[$onCloseCallbackClass, $onCloseCallbackMethod] = $callbacks[SwooleEvent::ON_CLOSE];
185+
$onCloseCallbackInstance = $this->container->get($onCloseCallbackClass);
186+
187+
while (true) {
188+
$frame = $response->recv();
189+
if ($frame === false || $frame instanceof CloseFrame || $frame === '') {
190+
$onCloseCallbackInstance->{$onCloseCallbackMethod}($response, $fd, 0);
191+
break;
191192
}
192-
} else {
193-
$this->deferOnOpen($request, $class, $server);
193+
$onMessageCallbackInstance->{$onMessageCallbackMethod}($response, $frame);
194194
}
195+
} else {
196+
$this->deferOnOpen($request, $class, $server);
195197
}
196198
} catch (Throwable $throwable) {
197199
// Delegate the exception to exception handler.
198200
$psr7Response = $this->exceptionHandlerDispatcher->dispatch($throwable, $this->exceptionHandlers);
201+
FdCollector::del($request->fd);
202+
WsContext::release($request->fd);
199203
} finally {
200204
isset($fd) && $this->getSender()->setResponse($fd, null);
201205
// Send the Response to client.

0 commit comments

Comments
 (0)