Skip to content
This repository has been archived by the owner on Sep 10, 2024. It is now read-only.

Auth error in laravel 5.8 with swoole 2.6 #371

Closed
MostafaRabia opened this issue Feb 3, 2020 · 22 comments
Closed

Auth error in laravel 5.8 with swoole 2.6 #371

MostafaRabia opened this issue Feb 3, 2020 · 22 comments

Comments

@MostafaRabia
Copy link

Make sure you read Issues Guideline and answer these questions before submitting your issue. Thanks!
(Any non-English issues will be closed immediately.)

  1. Please provide your PHP and Swoole version. (php -v and php --ri swoole)
    PHP 7.2.24-0ubuntu0.18.04.2 (cli) (built: Jan 13 2020 18:39:59) ( NTS )
    Version => 4.4.15

  2. Please provide your Laravel/Lumen version.
    Laravel: 5.8

  3. Which release version of this package are you using?
    2.6

  4. What did you do? If possible, provide a recipe for reproducing the error.

Websocket::on('connect',function($websocket,$request){
var_dump($request->user());
});
  1. What did you expect to see?
    User function

  2. What did you see instead?
    NULL!

@codercms
Copy link
Contributor

@MostafaRabia can you share your swoole_http and swoole_websocket config files?
And check that your config contains the following lines in the "providers" section:

    /*
    |--------------------------------------------------------------------------
    | Providers here will be registered on every request.
    |--------------------------------------------------------------------------
    */
    'providers' => [
        Illuminate\Auth\AuthServiceProvider::class,
        App\Providers\AuthServiceProvider::class,

@lilianjin
Copy link
Contributor

  1. Check if the middleware is enabled
  2. Check the session driver and the limits of the sesion

@MostafaRabia
Copy link
Author

@codercms

websocket:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Websocket handler for onOpen and onClose callback
    | Replace this handler if you want to customize your websocket handler
    |--------------------------------------------------------------------------
    */
    'handler' => SwooleTW\Http\Websocket\SocketIO\WebsocketHandler::class,

    /*
    |--------------------------------------------------------------------------
    | Default frame parser
    | Replace it if you want to customize your websocket payload
    |--------------------------------------------------------------------------
    */
    'parser' => SwooleTW\Http\Websocket\SocketIO\SocketIOParser::class,

    /*
    |--------------------------------------------------------------------------
    | Websocket route file path
    |--------------------------------------------------------------------------
    */
    'route_file' => base_path('routes/websocket.php'),

    /*
    |--------------------------------------------------------------------------
    | Default middleware for on connect request
    |--------------------------------------------------------------------------
    */
    'middleware' => [
        SwooleTW\Http\Websocket\Middleware\DecryptCookies::class,
        SwooleTW\Http\Websocket\Middleware\StartSession::class,
        SwooleTW\Http\Websocket\Middleware\Authenticate::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Websocket handler for customized onHandShake callback
    |--------------------------------------------------------------------------
    */
    'handshake' => [
        'enabled' => false,
        'handler' => SwooleTW\Http\Websocket\HandShakeHandler::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Default websocket driver
    |--------------------------------------------------------------------------
    */
    'default' => 'table',

    /*
    |--------------------------------------------------------------------------
    | Websocket client's heartbeat interval (ms)
    |--------------------------------------------------------------------------
    */
    'ping_interval' => 25000,

    /*
    |--------------------------------------------------------------------------
    | Websocket client's heartbeat interval timeout (ms)
    |--------------------------------------------------------------------------
    */
    'ping_timeout' => 60000,

    /*
    |--------------------------------------------------------------------------
    | Room drivers mapping
    |--------------------------------------------------------------------------
    */
    'drivers' => [
        'table' => SwooleTW\Http\Websocket\Rooms\TableRoom::class,
        'redis' => SwooleTW\Http\Websocket\Rooms\RedisRoom::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Room drivers settings
    |--------------------------------------------------------------------------
    */
    'settings' => [

        'table' => [
            'room_rows' => 4096,
            'room_size' => 2048,
            'client_rows' => 8192,
            'client_size' => 2048,
        ],

        'redis' => [
            'server' => [
                'host' => env('REDIS_HOST', '127.0.0.1'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => 0,
                'persistent' => true,
            ],
            'options' => [
                //
            ],
            'prefix' => 'swoole:',
        ],
    ],
];

http:

<?php

if (env('APP_ENV')=='production'){
    $socket_type = SWOOLE_SOCK_TCP | SWOOLE_SSL;
}else{
    $socket_type = SWOOLE_SOCK_TCP;
}

return [
    /*
    |--------------------------------------------------------------------------
    | HTTP server configurations.
    |--------------------------------------------------------------------------
    |
    | @see https://www.swoole.co.uk/docs/modules/swoole-server/configuration
    |
    */
    'server' => [
        'host' => env('SWOOLE_HTTP_HOST', '127.0.0.1'),
        'port' => env('SWOOLE_HTTP_PORT', '1215'),
        'public_path' => base_path('public'),
        // Determine if to use swoole to respond request for static files
        'handle_static_files' => env('SWOOLE_HANDLE_STATIC', true),
        'access_log' => env('SWOOLE_HTTP_ACCESS_LOG', false),
        // You must add --enable-openssl while compiling Swoole
        // Put `SWOOLE_SOCK_TCP | SWOOLE_SSL` if you want to enable SSL
        'socket_type' => $socket_type,
        'process_type' => SWOOLE_PROCESS,
        'options' => [
            'pid_file' => env('SWOOLE_HTTP_PID_FILE', base_path('storage/logs/swoole_http.pid')),
            'log_file' => env('SWOOLE_HTTP_LOG_FILE', base_path('storage/logs/swoole_http.log')),
            'daemonize' => env('SWOOLE_HTTP_DAEMONIZE', true),
            // Normally this value should be 1~4 times larger according to your cpu cores.
            'reactor_num' => env('SWOOLE_HTTP_REACTOR_NUM', swoole_cpu_num()),
            'worker_num' => env('SWOOLE_HTTP_WORKER_NUM', swoole_cpu_num()),
            'task_worker_num' => env('SWOOLE_HTTP_TASK_WORKER_NUM', swoole_cpu_num()),
            // The data to receive can't be larger than buffer_output_size.
            'package_max_length' => 20 * 1024 * 1024,
            // The data to send can't be larger than buffer_output_size.
            'buffer_output_size' => 10 * 1024 * 1024,
            // Max buffer size for socket connections
            'socket_buffer_size' => 128 * 1024 * 1024,
            // Worker will restart after processing this number of requests
            'max_request' => 3000,
            // Enable coroutine send
            'send_yield' => true,
            // You must add --enable-openssl while compiling Swoole
            'ssl_cert_file' => env('ssl_cert_file'),
            'ssl_key_file' => env('ssl_key_file'),
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Enable to turn on websocket server.
    |--------------------------------------------------------------------------
    */
    'websocket' => [
        'enabled' => env('SWOOLE_HTTP_WEBSOCKET', true),
    ],

    /*
    |--------------------------------------------------------------------------
    | Hot reload configuration
    |--------------------------------------------------------------------------
    */
    'hot_reload' => [
        'enabled' => env('SWOOLE_HOT_RELOAD_ENABLE', false),
        'recursively' => env('SWOOLE_HOT_RELOAD_RECURSIVELY', true),
        'directory' => env('SWOOLE_HOT_RELOAD_DIRECTORY', base_path()),
        'log' => env('SWOOLE_HOT_RELOAD_LOG', true),
        'filter' => env('SWOOLE_HOT_RELOAD_FILTER', '.php'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Console output will be transferred to response content if enabled.
    |--------------------------------------------------------------------------
    */
    'ob_output' => env('SWOOLE_OB_OUTPUT', true),

    /*
    |--------------------------------------------------------------------------
    | Pre-resolved instances here will be resolved when sandbox created.
    |--------------------------------------------------------------------------
    */
    'pre_resolved' => [
        'view', 'files', 'session', 'session.store', 'routes',
        'db', 'db.factory', 'cache', 'cache.store', 'config', 'cookie',
        'encrypter', 'hash', 'router', 'translator', 'url', 'log',
    ],

    /*
    |--------------------------------------------------------------------------
    | Instances here will be cleared on every request.
    |--------------------------------------------------------------------------
    */
    'instances' => [
        'log'=>'cache',
    ],

    /*
    |--------------------------------------------------------------------------
    | Providers here will be registered on every request.
    |--------------------------------------------------------------------------
    */
    'providers' => [
        Illuminate\Pagination\PaginationServiceProvider::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetters for sandbox app.
    |--------------------------------------------------------------------------
    */
    'resetters' => [
        SwooleTW\Http\Server\Resetters\ResetConfig::class,
        SwooleTW\Http\Server\Resetters\ResetSession::class,
        SwooleTW\Http\Server\Resetters\ResetCookie::class,
        SwooleTW\Http\Server\Resetters\ClearInstances::class,
        SwooleTW\Http\Server\Resetters\BindRequest::class,
        SwooleTW\Http\Server\Resetters\RebindKernelContainer::class,
        SwooleTW\Http\Server\Resetters\RebindRouterContainer::class,
        SwooleTW\Http\Server\Resetters\RebindViewContainer::class,
        SwooleTW\Http\Server\Resetters\ResetProviders::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Define your swoole tables here.
    |
    | @see https://www.swoole.co.uk/docs/modules/swoole-table
    |--------------------------------------------------------------------------
    */
    'tables' => [
        /*'table_name' => [
            'size' => 1024,
            'columns' => [
                ['name' => 'column_name', 'type' => Table::TYPE_STRING, 'size' => 1024],
            ]
        ],*/
    ],
];

@codercms
Copy link
Contributor

@MostafaRabia you should add these lines:

        Illuminate\Auth\AuthServiceProvider::class,
        App\Providers\AuthServiceProvider::class,

To the providers section in your http config.

Also you have misconfigured the instances section - that is not an associative array. Why do you want to reset log and cache instances after each request?

And pls read this issue - #123 (comment)

@MostafaRabia
Copy link
Author

@codercms
ErrorException: Trying to get property 'id' of non-object
After adding providers
By auth()->user()->id

Websocket::getUserId();
working, but auth() not working.

i saw and searched too much, what worked was: #320

@codercms
Copy link
Contributor

codercms commented Feb 14, 2020

@MostafaRabia hmm ... Probably this is related to - #368
Can you try to create your own middleware with this fix?
And replace SwooleTW\Http\Websocket\Middleware\StartSession :: class, with the new one.

P.S did you try to call $request->user() ?

@MostafaRabia
Copy link
Author

@codercms
Yes, that's what solved it and i can get userId from websocket.

when i send data to socket, $request switch to array with those inputs just.
Look: Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function user() on array
that's $request()->user

@codercms
Copy link
Contributor

@MostafaRabia can you show how do you send data to socket?

@MostafaRabia
Copy link
Author

socket.emit('test',{
type: type,
user: user,
text, text,
});
@codercms

@codercms
Copy link
Contributor

codercms commented Feb 14, 2020

@MostafaRabia I mean the server side, not the client side

@MostafaRabia
Copy link
Author

$namespace = '\App\Http\Controllers\';

Websocket::on('connect',function($websocket,$request){
if (auth()->check()){
Websocket::loginUsing(auth()->user());
}
});

Websocket::on('MSGs',$namespace.'Messages\Send@Send');

public function Send($websocket,$request){...}

@codercms

@codercms
Copy link
Contributor

@MostafaRabia actually you don't need to authenticate user manually, this work is delegated to the middleware layer:

        SwooleTW\Http\Websocket\Middleware\DecryptCookies::class,
        SwooleTW\Http\Websocket\Middleware\StartSession::class,
        SwooleTW\Http\Websocket\Middleware\Authenticate::class, (this one should be replaced with your own middleware)

Can you add logging to the onConnect handler?

Websocket::on('connect', function($websocket, $request) {
    \Log::info('onConnect', ['user' => $request->user()]);
});

@MostafaRabia
Copy link
Author

Worked, got the user.
@codercms

@codercms
Copy link
Contributor

@MostafaRabia nice, now you can write your application's business logic.
P.S. Avoid using of any global context in your app, this can save a lot of time for you.
If your issue is solved now, you can close it.

@MostafaRabia
Copy link
Author

@codercms
wait, how to use $request->user() in my function that i sent to it some data?
that's not solved yet.

@codercms
Copy link
Contributor

@MostafaRabia If I understand you correctly, You wanna send some data back to the user?

@MostafaRabia
Copy link
Author

@codercms no, send data to function that will send to user

Look

@codercms
Copy link
Contributor

@MostafaRabia try this:

$user = $request->user();

Websocket::toUserId($user->id)->emit('message', 'hi there');
// Possible this can work too: $websocket->emit('message', 'hi there');

@MostafaRabia
Copy link
Author

$request->user();

My request var is:
[
'msg' => 'Hi',
]

not anything else, so i can't get user()
that if i sent data from client side to server side as i said.

@codercms

@codercms
Copy link
Contributor

codercms commented Feb 14, 2020

@MostafaRabia now I see what you want to do.
Try this:

Websocket::on('connect', function($websocket, $request) {
    $user = $request->user();

    \Log::info('onConnect', ['user' => $user]);

    Websocket::loginUsing($user); // or maybe it should be $websocket->loginUsing($user);
});

Websocket::on('msg', function($websocket, $request) {
    // now you should have user here
    \Log::info('onMsg', ['user' => $request->user()]);
});

@MostafaRabia
Copy link
Author

@codercms
Sorry for my late.

that's come from the second:
Call to a member function user() on null at /mnt/342C1A272C19E520/htdocs/Condrx/routes/websocket.php:40)

in websocket on connect it comes correctly.

@netdown
Copy link
Contributor

netdown commented Jun 10, 2020

After you authenticated your user (in middleware):

$request->setUserResolver(function () use ($user) {
    return $user;
});

I guess you have an older version as this is already merged into the default middleware.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants