onHandShake 事件回调是可选的,需要自行处理 handshake 的时候,再设置这个回调函数。如果您不需要 “自定义” 握手过程,那么不要设置该回调,用 Swoole 默认的握手即可。
· 设置 onHandShake 回调函数后不会再触发 onOpen 事件,需要应用代码自行处理
· onHandShake 中必须调用 response->status() 设置状态码为 101 并调用 response->end() 响应,否则会握手失败.
· 内置的握手协议为 Sec-WebSocket-Version: 13,低版本浏览器需要自行实现握手
· 可以使用 server->defer 调用 onOpen 逻辑
$server->on('handshake', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
// print_r( $request->header );
// if (如果不满足我某些自定义的需求条件,那么返回end输出,返回false,握手失败) {
// $response->end();
// return false;
// }
// websocket握手连接算法验证
$secWebSocketKey = $request->header['sec-websocket-key'];
$patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
$response->end();
return false;
}
echo $request->header['sec-websocket-key'];
$key = base64_encode(
sha1(
$request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
true
)
);
$headers = [
'Upgrade' => 'websocket',
'Connection' => 'Upgrade',
'Sec-WebSocket-Accept' => $key,
'Sec-WebSocket-Version' => '13',
];
// WebSocket connection to 'ws://127.0.0.1:9502/'
// failed: Error during WebSocket handshake:
// Response must not include 'Sec-WebSocket-Protocol' header if not present in request: websocket
if (isset($request->header['sec-websocket-protocol'])) {
$headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol'];
}
foreach ($headers as $key => $val) {
$response->header($key, $val);
}
$response->status(101);
$response->end();
});