Socket.io 在带有 redis 和 Laravel-echo-server 的 Web 浏览器 chrome 中没有显示任何内容

Posted

技术标签:

【中文标题】Socket.io 在带有 redis 和 Laravel-echo-server 的 Web 浏览器 chrome 中没有显示任何内容【英文标题】:Socket.io shows nothing in web browser chrome with redis and Laravel-echo-server 【发布时间】:2021-05-09 02:24:18 【问题描述】:

我配置了 Laravel Echo、Laravel-echo-server、Redis、Socket.io,但是经过三周的尝试和阅读堆栈overflow上发布的每个问题以及我找到的文档后,我无法让它在浏览器中工作,chrome 不显示任何内容,尽管 Redis 和 Laravel-echo-server 一切正常。有什么帮助吗?

查看我上次的配置:

/routes/Web.php

Auth::routes();

Route::get('/', function() 
    return view('welcome');
);

Route::get('/welcome', function() 
    return view('welcome');
);

Route::post('/messages', function () 
    $data = request()->all();
    $message = \App\Message::create($data);
    broadcast(new \App\Events\SendMessage($message));
    return redirect('/messages');
);

Route::get('/messages', function () 
    $data = request()->all();
    \App\Message::create($data);
    return view('message');
);

/resources/views/Messages.blade.php

@extends('layouts.app')
@section('content')
<form action="" method="post" class="container">
    @csrf
    <input type='hidden' value=csrfToken id='js-csrf' />
    <input type="text" name="title" class="form-control" placeholder="Title"> 
    <textarea type="text" name="body" class="form-control" placeholder="Message...">
    </textarea>
    <input type="submit" value="Send" class="btn btn-primary">
</form>
@endsection

/resources/js/App.js

require('./bootstrap');

window.Vue = require('vue').default;

Vue.component('example-component', 

require('./components/ExampleComponent.vue').default);

const app = new Vue(
    el: '#app',
);

/resources/js/bootstrap.js

        window._ = require('lodash');

        try 
            window.Popper = require('popper.js').default;
            window.$ = window.jQuery = require('jquery');
            require('bootstrap');
         catch (e) 

        window.axios = require('axios');
        window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

        import Echo from 'laravel-echo';
        window.io = require('socket.io-client');
    
        window.Echo = new Echo(
            broadcaster: 'socket.io',
            host: window.location.hostname + ':6001'
        )

/resources/js/components/ExampleComponent.vue

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Messagens</div>
                    <div class="card-body">
                        <div class="alert alert-info" v-if="messages.length <= 0"></div>
                        <p v-for="(message, index) in messages" :key="index">
                            <strong> message.title</strong> <br />
                            message.body <br />
                            <small>  message.created_at  </small>
                        </p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
        export default 
            data() 
                return 
                    messages: []
                
            ,
            mounted() 
                
                window.Echo.channel('message-received')
                    .listen('.message', (e) => 
                        this.messages.push(e);
                    
                );
            
        
    </script>

/config/App.php

'providers' => [
    App\Providers\BroadcastServiceProvider::class,

'aliases' => [
    'Redis' => Illuminate\Support\Facades\Redis::class,

/config/broadcasting.php

  'redis' => [
            'driver' => 'redis',
            'client' => env('REDIS_CLIENT', 'predis'),
            'options' => [
                'cluster' => env('REDIS_CLUSTER', 'redis'),
                'prefix' => env('REDIS_PREFIX', ''),
            ],
            'default' => [
                'url' => env('REDIS_URL'),
                'host' => env('REDIS_HOST', '127.0.0.1'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => env('REDIS_DB', 0),
            ],
            'cache' => [
                'url' => env('REDIS_URL'),
                'host' => env('REDIS_HOST', '127.0.0.1'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => env('REDIS_CACHE_DB', 1),
            ],
        ],

.ENV

LARAVEL_ECHO_PORT=6001

QUEUE_CONNECTION=sync
QUEUE_DRIVER=redis
BROADCAST_DRIVER=redis

CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

ECHO_HOST=192.241.159.78
ECHO_PORT=6001
ECHO_SCHEME=http

/routes/channels.php

Broadcast::channel('message-received', function ($user) 
    return $user;
);

/App/Events/SendMessage.php

class SendMessage implements ShouldBroadcast 
    use Dispatchable, InteractsWithSockets, SerializesModels;
    private $message;

    public function __construct(Message $message) 
        $this->message = $message;
    

    public function broadcastOn()                        
        return new Channel('message-received');
    

    public function broadcastWith()  
        var_dump($this->message->toArray());
        return $this->message->toArray(); 
    

    public function broadcastAs() 
        return 'message';
    


依赖关系

php -v
PHP 7.3.26-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Jan 13 2021 08:00:44) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.26, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.26-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

Laravel Framework: 8.24.0
laravel-echo-server: 1.6.2
redis-cli: 4.0.9
laravel-echo: 1.10.0
socket.io: 3.1.0
socket.io-client: 3.1.0 fix with: 2.3.0
vue-axios: 3.2.4"
vuex: 4.0.0-rc.2**

Package.json


    "private": true,
    "scripts": 
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    ,
    "devDependencies": 
        "@vue/compiler-sfc": "^3.0.5",
        "axios": "^0.21.1",
        "bootstrap": "^4.0.0",
        "jquery": "^3.2",
        "laravel-mix": "^6.0.11",
        "lodash": "^4.17.19",
        "popper.js": "^1.12",
        "postcss": "^8.1.14",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.20.1",
        "sass-loader": "^8.0.0",
        "vue": "^2.6.12",
        "vue-loader": "^15.9.5",
        "vue-template-compiler": "^2.6.10"
    ,
    "dependencies": 
        "karma": "^0.13.19",
        "laravel-echo": "^1.10.0",
        "socket.io": "^3.1.0",
        "socket.io-client": "^3.1.0", fix with 2.3.0
        "vue-axios": "^3.2.4",
        "vuex": "^4.0.0-rc.2"
    ,

php artisan queue:work

** 安装 Redis **

sudo apt install php-pear
sudo apt install php-dev
sudo pecl install redis
extension = redis.io
sudo service apache2 restart

** Redis-cli 监控器 **

1612460665.656384 [0 192.241.159.78:33820] "SELECT" "0"
1612460665.656635 [0 192.241.159.78:33820] "EVAL" "for i = 2, #ARGV do\n  redis.call('publish', ARGV[i], ARGV[1])\nend" "0" 
    "
        \"event\":\"message\",
        \"data\":
        
            \"id\":560,
            \"title\":\"Message title\",
            \"body\":\"Message Content, here are all the details of the message that does not appear in the browser at all.\",
            \"content\":null,
            \"created_at\":\"2021-02-04T17:44:25.000000Z\",
            \"updated_at\":\"2021-02-04T17:44:25.000000Z\",
            \"socket\":null
        ,
        \"socket\":null
    " 
    "message-received"

1612460665.656691 [0 lua] "publish" "message-received" 
    "
        \"event\":\"message\",
        \"data\":
        
            \"id\":560,
            \"title\":\"Message title\",
            \"body\":\"Message Content, here are all the details of the message that does not appear in the browser at all.\",
            \"content\":null,
            \"created_at\":\"2021-02-04T17:44:25.000000Z\",
            \"updated_at\":\"2021-02-04T17:44:25.000000Z\",
            \"socket\":null
        ,
        \"socket\":null
    "

允许收听 6001

为了让 Laravel 和 Redis 完美运行,我发布了 6001 端口,但在生产中你必须小心。

sudo ufw allow 6001

L A R A V E L E C H O S E R V E R 版本 1.6.2

⚠ Starting server in DEV mode...

✔  Running at localhost on port 6001
✔  Channels are ready.
✔  Listening for http events...
✔  Listening for redis events...

Server ready!

Channel: message-received
Event: message
Channel: message-received
Event: message

Laravel-echo-server.json


    "authHost": "http://192.241.159.78",
    "authEndpoint": "/broadcasting/auth",
    "clients": [
        
            "appId": "***",
            "key": "***"
        
    ],
    "database": "redis",
    "databaseConfig": 
        "redis": 
            "port": "6379",
            "host": "localhost"
        ,
        "sqlite": 
            "databasePath": "/database/laravel-echo-server.sqlite"
        
    ,
    "devMode": true,
    "host": null,
    "port": "6001",
    "protocol": "http",
    "socketio": ,
    "secureOptions": 67108864,
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "subscribers": 
        "http": true,
        "redis": true
    ,
    "apiOriginAllow": 
        "allowCors": true,
        "allowOrigin": "*",
        "allowMethods": "GET, POST",
        "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
    

我执行这个队列

php artisan queue:work 

浏览器中不显示任何内容。当我切换到 Socket.Io 和 Socket.io-client 的第 2 版时,出现了一个更奇怪的错误:TypeError: cb is not a function 我还在频道名称中加了一个点,但没有解决任何问题。 请帮帮我

**看这张照片:@MaartenVeerman ** chrome inspect

【问题讨论】:

在您的 javascript 中,您强制使用 TLS(安全)连接,但您的回显服务器配置未显示 HTTPS 设置,例如缺少证书。也许因此您的浏览器无法连接到服务器?还要确保端口 6001 已打开。 非常感谢@MaartenVeerman Veerman 我按照您的建议接受了凭据,但我仍然无法在浏览器中读取任何内容。请注意,我也更改了问题。 在您的 echo 配置中添加 forceTLS: false 您的回显服务器输出确实显示已建立连接。你能验证一下吗? 请为 ypu 添加图片...@MaartenVeerman 【参考方案1】:

我不知道这是否是 Laravel-echo 和 Socket.io 之间的错误或不兼容,但是当我将 Socket.io-client 从版本 3.0.3 降级到 2.3.0 时一切正常完美。我之前尝试过这个,但是它给出了另一个错误,我相信它是带有 socket.io 的版本,Socket.io 和 Socket.io-client 之间的不兼容。反正我没有深入研究这个,但值得一个月的研究。谢谢大家的帮助!

这很奇怪,但现在它工作得很好。

解决方案在这里 --> [https://github.com/tlaverdure/laravel-echo-server/issues/550]

这里 --> [https://***.com/questions/65026362/laravel-echo-listener-not-working-on-frontend]

感谢 Maarten Veerman 和 Mihai 以及你们所有人!

【讨论】:

以上是关于Socket.io 在带有 redis 和 Laravel-echo-server 的 Web 浏览器 chrome 中没有显示任何内容的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io & Redis - 适合 io 游戏的架构?

我在集群 node.js/socket.io/redis pub/sub 应用程序中收到重复消息

Connect-redis 商店不适用于 socket.io

带有套接字 io 和 redis 的 laravel echo 服务器

在多核服务器中使用带有集群的 socket.io 的好方法?

Socket.io 在 Node.js + Redis + Heroku(多个测功机)环境中发出并不总是收到