swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.47k stars 3.16k forks source link

5.15版本,WebSocket 自定义握手,使用官方wiki上的例子onHandShake出现Segmentation fault #5589

Closed mdys closed 2 days ago

mdys commented 4 days ago

Please answer these questions before submitting your issue.

  1. What did you do? If possible, provide a simple script for reproducing the error. 使用WebSocket 自定义握手,无法使用onOpen 事件,看官方wiki上有使用 $server->defer 调用 onOpen 逻辑,使用后出现异常, 图片 错误如下 图片

  2. What did you expect to see?

  3. What did you see instead?

  4. What version of Swoole are you using (show your php --ri swoole)? Swoole => enabled Author => Swoole Team team@swoole.com Version => 5.1.5 Built => Nov 21 2024 19:44:14 coroutine => enabled with boost asm context epoll => enabled eventfd => enabled signalfd => enabled cpu_affinity => enabled spinlock => enabled rwlock => enabled sockets => enabled openssl => OpenSSL 1.0.2k-fips 26 Jan 2017 http2 => enabled json => enabled curl-native => enabled pcre => enabled c-ares => 1.10.0 zlib => 1.2.7 brotli => E16777225/D16777225 mutex_timedlock => enabled pthread_barrier => enabled futex => enabled mysqlnd => enabled async_redis => enabled

Directive => Local Value => Master Value swoole.enable_coroutine => On => On swoole.enable_library => On => On swoole.enable_fiber_mock => Off => Off swoole.enable_preemptive_scheduler => Off => Off swoole.display_errors => On => On swoole.use_shortname => On => On swoole.unixsock_buffer_size => 8388608 => 8388608

  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ? Linux myserver 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

PHP 8.3.8 (cli) (built: Jun 4 2024 14:53:17) (NTS gcc x86_64) Copyright (c) The PHP Group Zend Engine v4.3.8, Copyright (c) Zend Technologies with Zend OPcache v8.3.8, Copyright (c), by Zend Technologies

Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux Thread model: posix gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)

NathanFreeman commented 4 days ago

麻烦将你的代码粘贴上来,我们这边可以直接复制粘贴测试一下

NathanFreeman commented 4 days ago

swoole5开始Swoole\Server::defer已经废弃,请直接使用Swoole\Event::defer()

mdys commented 4 days ago

swoole5开始Swoole\Server::defer已经废弃,请直接使用Swoole\Event::defer()

感谢,使用Swoole\Event::defer() 不报错了,但ws-client连接后 直接就被关闭了,不知道是什么问题,感谢再给指点下。 图片 图片 图片

mdys commented 4 days ago

另外请教下,我使用nginx代理ws,可以正常接受client连接,并使用onOpen处理,但去掉nginx代理后 就收不到ws连接请求了,请教下如果我的服务端url是 ws://192.168.0.179:9501/ws ,如果不使用nginx代理的话 使用swoole如何写可以处理/ws 这个路由呢?没有找到示例,麻烦能给个提示。感谢 使用nginx代理是可以正常收到的。

location /ws { proxy_pass http://127.0.0.1:9501; proxy_read_timeout 300s; proxy_send_timeout 300s; proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }

mdys commented 4 days ago
$server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
$server->on('open', function (Swoole\WebSocket\Server $server, $request) {
  echo "server: handshake success with fd{$request->fd}\n";
});

$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
  echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
  $server->push($frame->fd, "this is server");
});

$server->on('close', function ($server, $fd) {
  echo "client {$fd} closed\n";
});

$server->on('handshake', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) {
    print_r( $request->header );
  // if (如果不满足我某些自定义的需求条件,那么返回end输出,返回false,握手失败) {
  //    $response->end();
  //     return false;
  // }  
  $headers = [
        'Upgrade' => 'websocket',
        'Connection' => 'Upgrade',  
        //'Sec-WebSocket-Version' => '13',
  ];

  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();

  global $server;
  $fd = $request->fd;
  Swoole\Event::defer(function () use ($fd, $server){
    echo "Client connected\n";
    $server->push($fd, "hello, welcome\n"); 

    echo "Client push\n";
  });

});

$server->start();
matyhtf commented 2 days ago

在 onHandshake 回调函数中判断 $request->server['request_uri'] 是否为 /ws ,不是则作为HTTP回复,是则回复 101 upgrade