onHandShake

WebSocket建立连接后进行握手。WebSocket服务器已经内置了handshake,如果用户希望自己进行握手处理,可以设置onHandShake事件回调函数。

  1. function onHandShake(swoole_http_request $request, swoole_http_response $response);
  • onHandShake事件回调是可选的
  • 设置onHandShake回调函数后不会再触发onOpen事件,需要应用代码自行处理
  • onHandShake中必须调用response->status设置状态码为101并调用end响应, 否则会握手失败.
  • 内置的握手协议为Sec-WebSocket-Version: 13,低版本浏览器需要自行实现握手

1.8.1或更高版本可以使用server->defer调用onOpen逻辑

注意: 仅仅你需要自行处理handshake的时候再设置这个回调函数,如果您不需要“自定义”握手过程,那么不要设置该回调,用swoole默认的握手即可。下面是“自定义”handshake事件回调函数中必须要具备的:

  1. $server->on('handshake', function (\swoole_http_request $request, \swoole_http_response $response) {
  2. // print_r( $request->header );
  3. // if (如果不满足我某些自定义的需求条件,那么返回end输出,返回false,握手失败) {
  4. // $response->end();
  5. // return false;
  6. // }
  7. // websocket握手连接算法验证
  8. $secWebSocketKey = $request->header['sec-websocket-key'];
  9. $patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
  10. if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
  11. $response->end();
  12. return false;
  13. }
  14. echo $request->header['sec-websocket-key'];
  15. $key = base64_encode(sha1(
  16. $request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
  17. true
  18. ));
  19. $headers = [
  20. 'Upgrade' => 'websocket',
  21. 'Connection' => 'Upgrade',
  22. 'Sec-WebSocket-Accept' => $key,
  23. 'Sec-WebSocket-Version' => '13',
  24. ];
  25. // WebSocket connection to 'ws://127.0.0.1:9502/'
  26. // failed: Error during WebSocket handshake:
  27. // Response must not include 'Sec-WebSocket-Protocol' header if not present in request: websocket
  28. if (isset($request->header['sec-websocket-protocol'])) {
  29. $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol'];
  30. }
  31. foreach ($headers as $key => $val) {
  32. $response->header($key, $val);
  33. }
  34. $response->status(101);
  35. $response->end();
  36. });