GithubHelp home page GithubHelp logo

think-swoole's Issues

多个开发想法

我想征求下意见

队列

目前有thinkphp-queue,而且非常好用。

不过swoole实现的队列和TP-queue有一些区别。

1.可以共享task worker来运行,对于一些需要后台执行的任务,如果任务不重,但是数量较多,共享worker可以降低资源的消耗,同时提高资源的利用率

2.可以使用swoole提供的协程,协程更简单。

3.启动多个队列更简单,统一管理

RPC

其实大家更习惯传统的运行方式,swoole workerman的方式需要花费额外的时间去了解多进程,常驻内存等一些知识。个人觉得,大多数业务仍然采用传统方式,当存在耗时业务时,通过一种简单的方式投递到think-swoole的后台运行当中

method not exists:think\Request->withInput

[think\exception\ErrorException] Uncaught think\Exception: method not exists:think\Request->withInput in /home/vagrant/code/knowledge/thinkphp/library/ think/Request.php:335 Stack trace: #0 /home/vagrant/code/knowledge/vendor/topthink/think-swoole/src/Application.php(53): think\Request->__call('withInput ', Array) #1 /home/vagrant/code/knowledge/vendor/topthink/think-swoole/src/Swoole.php(131): think\swoole\Application->swoole(Obj ect(Swoole\Http\Request), Object(Swoole\Http\Response)) #2 {main} thrown

think内核swoole分模块配置有BUG

TP版本:5.1.x-dev版本
TP-Swoole:2.0.x-dev版本

配置BUG问题如下:
有两个模块
默认module为:index
API的module为:api

问题经过还原如下
在API中建立config/app.php配置文件
目录如下/application/api/config/app.php

当我们启动swoole的时候,在onWorkerStart里会初始化读取一次配置,如下;
7
然后去init()去读取配置
1
$dir = $this->configPath . $module;
在workerstart的时候已经加载到内存中没有问题。

问题出现:

但是当我们在api模块下,建立一个config/app.php
配置如下:
return [ // 默认输出类型 'default_return_type' => 'json', ];
访问api/index/index的时候,api模块下的配置会被重载到内存中。
此时api模块下输出的为json格式

但是我们此时切换回index/index/index的时候,当我们访问 index/index/index的时候
而此时 $dir会找不到。所以默认采用内存中上次出现的配置
此时index/index/index 本来应该采用默认配置输出html格式的。却输出了json格式。

解决方式:
在index模块下也建立一个配置,默认输出改为html

希望能更新一下 README 中的错误

README 中有错误,例如:
$swoole=Container::get('swoole');//获取swoole实例
会报错。
use think\swoole\template\Task; 文件不存在。
use think\swoole\facade\Task; 文件不存在。
等等。

协程中数据库问题

协程模式下,同一个worker下全局变量共享,那么数据库连接也应该是共享的,\think\Db::$connection,但是有多个协程在执行,多个协程在复用这个连接,在实际的业务逻辑中又用到了事务,不会存在冲突吗?

比如这种情况:协程A 开启事务 这个事务比较耗时 这是会执行协程B,协程B进行了一个插入操作,返回协程A ,这时候协程A事务回滚,这样协程B的插入操作就失效了。(协程A B 执行不同的请求)
或者类似于这样的其他冲突情况。

验证码无法显示

Http\Response->end(string $html); 只支持HTML的输出,验证码输出是图片格式,所以要使用Http\Response->write(string $data);

swoole 和swoole:server 有什么区别?

我看源码,如果是swoole 启动就会使用自定义的think\swoole\Application;
此时可以启用Websocket服务也可以启用Http服务. 但是如果是swoole:server启动就不使用think\swoole\Application;
问题
1: 请问这两种启动方式的区别是什么?
2: 为什么swoole:server方式启动 不使用think\swoole\Application,而swoole却使用了;
3. 当使用swoole 方式启动Websocket服务时,返回消息是$resp->send(),Websocket 发送消息不应该是 $server->push($frame->fd,$resp->getData())吗?

installation of think-swoole error

php version: 7.0.13
swoole version: 1.10.5
installation tips:

Fatal error: Uncaught TypeError: Return value of Endroid\Installer\Installer::activate() must be an instance of Endroid\Installer\void, none returned in /mnt/hgfs/www/saletool/vendor/endroid/installer/src/Installer.php:36
Stack trace:
#0 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(232): Endroid\Installer\Installer->activate(Object(Composer\Composer), Object(Composer\IO\ConsoleIO))
#1 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(205): Composer\Plugin\PluginManager->addPlugin(Object(Endroid\Installer\Installer))
#2 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(257): Composer\Plugin\PluginManager->registerPackage(Object(Composer\Package\CompletePackage))
#3 phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(76): Composer\Plugin\PluginManager->loadRepository(Object(Composer\Repository\InstalledFilesystemRepository))
#4 phar:///usr/local/bin/composer/src/Composer/Factory.php(377): Composer\Plugin\PluginManager->loadInstalledPlugins()
#5 p in /mnt/hgfs/www/saletool/vendor/endroid/installer/src/Installer.php on line 36

swoole request isAjax判断有问题

/**
     * 当前是否Ajax请求
     * @access public
     * @param  bool $ajax  true 获取原始ajax请求
     * @return bool
     */
    public function isAjax($ajax = false)
    {
//  这里的HTTP_X_REQUESTED_WITH不存在!
        $value  = $this->server('HTTP_X_REQUESTED_WITH');
        $result = 'xmlhttprequest' == strtolower($value) ? true : false;

        if (true === $ajax) {
            return $result;
        }

        $result           = $this->param($this->config['var_ajax']) ? true : $result;
        $this->mergeParam = false;
        return $result;
    }

Undefined property: swoole_http_request::$cookie

Thinkphp: 5.1.32
PHP: 7.2.10-0ubuntu0.18.04.1
Swoole: swoole-1.9.6
Thinkphp-swoole: installed with composer

Errors when run with "php think swoole":
Uncaught think\exception\ErrorException: Undefined property: swoole_http_request::$cookie
Uncaught think\exception\ErrorException: Undefined property: swoole_http_request::$get
Uncaught think\exception\ErrorException: Undefined property: swoole_http_request::$post
Uncaught think\exception\ErrorException: Undefined property: swoole_http_request::$files

Valid code(thinphp-swoole/src/Application.php):
48 $_COOKIE = isset($request->cookie) ? $request->cookie: [];
49 $_GET = isset($request->get) ? $requeset->get: [];
50 $_POST = isset($request->post) ? $requeset->post: [];
51 $_FILES = isset($request->files) ? $requeset->files: [];
52 $header = $request->header ?: [];
53 $server = $request->server ?: [];

通过docker 部署出现问题

镜像地址: dragonlhp/nginx-php-fpm-swoole:latest
启动命令:
/usr/bin/php /var/www/html/think swoole
报错:
swoole http server process is already running.

自定义服务类出现错误:Swoole\Server::on(): unknown event types[Message]

4, 'daemonize' => false, 'task_worker_num' => 4 //'backlog' => 128 ]; public function onMessage($server, $frame) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n"; $server->push($frame->fd, "this is server"); } // 设置了onRequest回调,websocket服务器也可以同时作为http服务器 public function onRequest($request, $response) { $response->end("

Hello Swoole. #this is socket server" . "

"); } public function onTask($server, $task_id, $worker_id, $data) { echo 'task start success,taskID is '.$task_id.PHP_EOL; sleep(10); return ['code'=>0, 'message'=>'OK'];// 返回到 onFinish 中 } public function onFinish($server, $task_id, $data) { echo 'taskId is '.$task_id . PHP_EOL; echo 'task coming data is '. json_encode($data); echo 'task finished....'.PHP_EOL; } public function onClose($server, $fd) { echo "client {$fd} closed\n"; } } 所有回调事件都 在自定义服务里面洗的话,就报这个错误,,unknown event types[XXXX]

runtime/swoole.log不断频繁写入swoole的TRACE数据

启动后runtime目录下的swoole.log不断追加swoole携程的TRACE信息,日志文件很快被写得很大,请问这样频繁的创建关闭是正常的么?怎么关闭这个日志

`
[2018-12-13 14:39:24 *23190.0] TRACE ~Context(:38): free stack: ptr=0x7f4b413b2010
[2018-12-13 14:39:24 *23190.0] TRACE Context(:16): alloc stack: size=2097152, ptr=0x7f4b413b2010.
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_func(:245): Create coro id: 439132, coro total count: 1, heap size: 3122608
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_close(:385): coro_close coro id 439132
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_close(:420): close coro and 0 remained. usage size: 2860464. malloc size: 4194304
[2018-12-13 14:39:24 *23190.0] TRACE ~Context(:38): free stack: ptr=0x7f4b413b2010
[2018-12-13 14:39:24 *23190.0] TRACE Context(:16): alloc stack: size=2097152, ptr=0x7f4b413b2010.
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_func(:245): Create coro id: 439133, coro total count: 1, heap size: 3122608
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_close(:385): coro_close coro id 439133
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_close(:420): close coro and 0 remained. usage size: 2860464. malloc size: 4194304
[2018-12-13 14:39:24 *23190.0] TRACE ~Context(:38): free stack: ptr=0x7f4b413b2010
[2018-12-13 14:39:24 *23190.0] TRACE Context(:16): alloc stack: size=2097152, ptr=0x7f4b413b2010.
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_func(:245): Create coro id: 439134, coro total count: 1, heap size: 3122608
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_close(:385): coro_close coro id 439134
[2018-12-13 14:39:24 *23190.0] TRACE sw_coro_close(:420): close coro and 0 remained. usage size: 2860464. malloc size: 4194304

`

think-swoole重启是否应该适当延时?

现在的代码没有增加延时,重启有很大几率出现端口绑定冲突问题,错误代码如下:
`[root@NAS sms]# php think swoole:server restart
Stopping swoole server...

success
Starting swoole server...
[2018-11-10 12:59:15 @28949.0] WARNING swSocket_bind (ERROR 502): bind(127.0.0.1:65535) failed. Error: Address already in use [98]

[Swoole\Exception]
failed to listen server port[127.0.0.1:65535]. Error: Address already in use[98].

当对重启指令部分适当增加点延时后,重启不会提示端口绑定失败。/**
* 重启server
* @access protected
* @return void
*/
protected function restart()
{
$pid = $this->getMasterPid();

    if ($this->isRunning($pid)) {
        $this->stop();
    }
    sleep(1);
    $this->start();
}`

执行结果如下:
`[root@NAS sms]# php think swoole:server restart
Stopping swoole server...

success
Starting swoole server...
[root@NAS sms]#`

请问队列怎么用?

用think-queue跑起来了,不过好像是单进程的。看了这个扩展可以多进程去跑,可是不知道怎么用

关于swoole 下静态变量的分析

静态变量在传统php开发中很好用,但是在swoole等常驻内存模式下很容易造成bug
下面是一些thinkphp中比较重要的静态变量,大部分都有可能在swoole模式下造成bug

\think\Model::$initialized;
//原本作用:确保一个模型类中的init方法在一次请求中只被执行一次
//常驻内存下:一个模型只在第一次请求时执行该方法,后续请求不再执行,极有可能会造成bug
\think\Model::$readMaster;
//原本作用:设置某一个或者全部模型是否从主库读取数据
//常驻内存下:如果在一个请求执行了Model::readMaster()方法,\think\Model::$readMaster不会释放,将会影响到其他请求
think\model\concern\ModelEvent::$event;
//原本作用:给模型设置的事件回调
//常驻内存下:随着运行时间不断增加将不断增加运行内存,一次请求增加的事件将影响到另外一次请求
think\model\concern\ModelEvent::$observe;
//没有影响
think\db\Query::$readMaster;
//原本作用:设置某一个或者全部模型是否从主库读取数据
//常驻内存下:如果在一个请求执行了Query::readMaster()方法,Query::$readMaster不会释放,将会影响到其他请求
think\db\Query::$event;
//常驻内存下:一次请求增加的事件将影响到另外一次请求
think\db\Query::$extend;
//扩展查询方法
//几乎没有影响
think\Request::$ip;
//协程下会用bug 常驻内存非协程下没有影响
think\Template::$_varFunctionList;
//常驻内存模式下增加的变量无法释放,造成内存不断增加,模板变量冲突 可能造成bug
think\cache\Driver::$serialize;
//常住内存模式下 一次请求调用registerSerialize()方法后,会对下一次请求有影响
think\Validate::$typeMsg;
//应该基本没有啥影响
think\db\Connection::$instance;
//建立的连接管理实例
//协程模式,高并发下可能会导致数据库操作bug
think\db\Connection::$event;
//连接事件
//随着运行时间不断增加将不断增加运行内存,事件重复执行,一次请求增加的事件将影响到另外一次请求
think\db\Connection::$info;
//数据表信息
//应该没事影响
think\Db::$executeTimes;
//常驻内存下实际是全局执行时间
think\Db::$queryTimes;
//常驻内存下实际是全局执行次数
think\Db::$connection;
//协程模式,高并发下可能会导致数据库操作bug

既然think-swoole出现在官方文档中了,建议最好对这些整理下,做下说明以免使用者在不注意的情况下造成bug。
下个框架版本能对这些改进,即使在swoole下也能完美运行就完美了

在swoole中中间件失效的BUG

swoole版本:4.2.1
失效原因:
第一次访问URL到对应控制器时候,会调用中间件,第二次就不会调用了。

失效过程,还原过如下

在thinkphp5中,要对某个类用中间件拦截
需要继承Controller;

2

中间件,官方在Controller控制器的处理如下:
1

问题原因:

swoole的onRequest里第一次访问url的时候,会去执行一次构造方法,再次访问的时候,就不会去执行构造方法。
因此中间件只会被执行一次,再次访问URL时候构造函数里的操作并不会被执行。

swoole 服务器无法启动

框架核心更新到 5.1.24 , swoole 更新到 2.0.x-dev b618376

php think swoole 启动提示

[think\exception\ThrowableError]
Fatal error: Call to a member function getName() on string

php think swoole:server 没有问题

在代码中无法进行302跳转,

PHP Fatal error: Uncaught think\exception\ErrorException: Swoole\Http\Response::write(): data to send is empty.
设置location 会报这个错误

Task执行异常

在v2.0.13版本里,在已运行服务的情况下,使用Task跟直接调用容器里的swoole的时候,均发现

  [think\exception\ErrorException]
  Uncaught think\exception\ClassNotFoundException: class not exists: swoole in /home/liang/tp5/thinkphp/library/think/Cont
  ainer.php:442
  Stack trace:
  #0 /home/liang/tp5/thinkphp/library/think/Container.php(284): think\Container->invokeClass('swoole', Array)
  #1 /home/liang/tp5/thinkphp/library/think/Container.php(132): think\Container->make('swoole', Array, false)
  #2 /home/liang/tp5/vendor/topthink/think-swoole/src/Task.php(33): think\Container::get('swoole')
  #3 [internal function]: think\swoole\Task->async(Object(think\swoole\SuperClosure))
  #4 /home/liang/tp5/thinkphp/library/think/Facade.php(123): call_user_func_array(Array, Array)
  #5 /home/liang/tp5/application/server/controller/Socketserver.php(47): think\Facade::__callStatic('async', Array)
  #6 [internal function]: app\server\controller\SocketServer->task(Object(stdClass))
  #7 /home/liang/tp5/application/server/controller/Socketserver.php(27): call_user_func(Array, Object(stdClass))
  #8 {main}
    thrown

事例

Task::async(function($serv, $task_id, $data){
            $i = 0;
            while ($i < 10) {
                $i++;
                echo $i;
                sleep(1);
            }
        });

Session.php中由于会莫名遇到Cookie类已被使用

use think\facade\Cookie;

里边的方法在调用的Cookie的时候提示 已被占用。 具体产生原因比较模糊,有时候重新 php think swoole的时候就产生了这个问题。 改了别名后可正常使用了
use think\facade\Cookie as ThinkCookie; 然后替换掉Cookie类

Time定时器存在bug

官方文档里要继承自 think\swoole\template\timer,里面有一个
abstract protected function run();

是一个受保护的方法
但是在timer里面投递的系统定时器的时候,需要一个公开的,因此会报错

session组件有BUG

BUG过程还原如下

例如:
我们使用index/user/login 进行用户登录,登录后将用户一些信息存储到session中。此时我们会调用 Session::set() 进行用户的session设置。可以成功。

但是我们打开浏览器,清除cookie如下
1

用户会退出登录,没有错。
但是我们再次去登录用户的时候,用户会登录不上,captcha验证码验证组件也会时效。原因在于,当我们用set去设置的时候,会判断是否有session_id存在,如下:
2

其中getId 如下:
/** * 获取session_id * @access public * @return string */ public function getId() { return ThinkCookie::get($this->sessionName) ?: ''; }
会去获取sessionId开头的 cookie,而此时的cookie已经被我们清空了。根本获取不到了id了

由于成员变量,在swoole里已初始化就加载内存中顶了

所以下面的这一段是不会再去执行了
`
empty($this->init) && $this->boot();

boot里面的
if (false === $this->init) {
$this->start();
}
还有这个
if ($sessionId) {
$this->setSession($sessionId, $name, $value);
}
`
session设置就没有作用了

启动swoole服务器发生内存泄漏

直接命令行php think swoole,内存直接爆了,虽然程序还能勉强运行。

swoole4.2.13,thinkphp5.1.23,think-swoole扩展是直接composer安装的。

app_host 设置不生效

swoole 模式下 nginx 做转发 app_host 设置不生效
image
源码Application.php里的这块是不是应该改为获取配置里的值呢

2.0.4 启动异常

执行环境

cygwin64

代码

<?php
namespace app\index\controller;

use think\swoole\Server;

class Swoole extends Server
{
	protected $host = '127.0.0.1';
	protected $port = 9502;
	protected $option = [ 
		'worker_num'	=> 4,
		'daemonize'	=> true,
		'backlog'	=> 128
	];

	public function onReceive($server, $fd, $from_id, $data)
	{
		$server->send($fd, 'Swoole: '.$data);
	}
}

执行

php index.php index/swoole/start

报错

PHP Fatal error:  Swoole\Http\Server::start(): require onRequest callback in /home/tp5/vendor/topthink/think-swoole/src/Server.php on line 112



  [think\exception\ErrorException]
  Swoole\Http\Server::start(): require onRequest callback



composer 未加载

使用swoole后,composer相关包为加载,vendor应该是没有引入

中间件失效的问题

使用的 group路由 添加的中间件
swoole 模式下,我这里测试中间件拦截失效

中间件部分我设置

public function handle($request, \Closure $next)
{
return response()->data('xxx');
}

第一次拦截成功返回xxx
第二次不拦截直接执行后续的方法
第三次拦截成功返回xxx
第四次不拦截直接执行后续的方法

一直这样循环

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.