├── .gitignore
├── composer.json
├── config
└── echo.php
├── readme.md
└── src
├── BroadcastServerServiceProvider.php
├── Commands
└── EchoCommand.php
├── EchoMessage.php
├── RedisOperation.php
├── Request.php
├── Server.php
└── SocketServer.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zhaohehe/laravel-echo-server",
3 | "license": "MIT",
4 | "authors": [
5 | {
6 | "name": "zhaohehe",
7 | "email": "zhaohehedola@gmail.com"
8 | }
9 | ],
10 | "autoload": {
11 | "psr-4": {
12 | "EchoServer\\": "src/"
13 | }
14 | },
15 | "minimum-stability": "dev",
16 | "require": {}
17 | }
18 |
--------------------------------------------------------------------------------
/config/echo.php:
--------------------------------------------------------------------------------
1 | '127.0.0.1',
12 | /*
13 | |--------------------------------------------------------------------------
14 | | Socket server port
15 | |--------------------------------------------------------------------------
16 | |
17 | |
18 | |
19 | */
20 | 'port' => '3523',
21 | ];
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## laravel-echo-server
2 | >这是一个用来支持laravel的事件广播的socket服务器
3 |
4 | ## 安装
5 | 首先,你必须为你的php安装swoole扩展以及redis扩展,推荐使用php7
6 |
7 | 直接用composer安装
8 | ```
9 | composer require zhaohehe/laravel-echo-server
10 | ```
11 | 然后在```app.php```中的providers数组中加入下面的一项
12 | ```
13 | \EchoServer\BroadcastServerServiceProvider::class,
14 | ```
15 | 最后运行下面的命令,发布配置文件
16 | ```
17 | php artisan vendor:publish
18 | ```
19 |
20 | ## 使用
21 | 开启socket服务器
22 | ```
23 | php artisan echo start
24 | ```
25 | 你可以在echo.php文件中配置服务器监听的端口,默认是:3523
26 |
27 | 你需要在.env中设置BROADCAST_DRIVER=redis
28 |
29 | 前端代码:
30 | ```html
31 |
32 |
33 |
34 |
35 | Title
36 |
37 |
38 |
39 |
40 |
41 |
66 |
67 | ```
68 |
69 | 你的event必须实现ShouldBroadcast接口,那么,当你的事件被触发的时候,前端页面会获取到实时的message
70 |
71 | ## 最后
72 |
73 | 这是一个非常简陋的事件广播服务,只实现了最基本的功能,验证一下想法,我会去仔细研究下reids和laravel的广播以及swoole然后来完善它。
74 |
--------------------------------------------------------------------------------
/src/BroadcastServerServiceProvider.php:
--------------------------------------------------------------------------------
1 | publishes([
22 | __DIR__ . '/../config/echo.php' => config_path('echo.php'),
23 | ]);
24 | }
25 |
26 |
27 | /**
28 | * Register services.
29 | *
30 | * @return void
31 | */
32 | public function register()
33 | {
34 | $this->mergeConfigFrom(
35 | __DIR__ . '/../config/echo.php', 'echo'
36 | );
37 | $this->commands([
38 | Commands\EchoCommand::class,
39 | ]);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Commands/EchoCommand.php:
--------------------------------------------------------------------------------
1 | argument('action');
46 |
47 | switch ($action) {
48 |
49 | case 'start':
50 | $this->start();
51 | break;
52 | }
53 | }
54 |
55 |
56 | public function start()
57 | {
58 | $serv = new Server();
59 | }
60 | }
--------------------------------------------------------------------------------
/src/EchoMessage.php:
--------------------------------------------------------------------------------
1 | request = new Request();
19 |
20 | $redisOperate = new RedisOperation();
21 | $this->redis = $redisOperate->getRedis();
22 |
23 | }
24 |
25 | public function message($socketServer, $frame)
26 | {
27 | $fd = $frame->fd;
28 | $this->request->parse($frame->data);
29 |
30 | $event = $this->request->getEvent();
31 | $channel = $this->request->getChannel();
32 |
33 | $this->redis->subscribe([$channel], function ($instance, $channelName, $message) use ($socketServer, $fd, $event, $channel) {
34 |
35 | $message = json_decode($message);
36 | $eventName = $message->event;
37 |
38 | if ($eventName == $event && $channelName == $channel) {
39 | $socketServer->push($fd, json_encode($message->data));
40 | }
41 |
42 | });
43 |
44 | }
45 | }
--------------------------------------------------------------------------------
/src/RedisOperation.php:
--------------------------------------------------------------------------------
1 | redis = new Redis();
17 |
18 | $host = config('database.redis.default.host');
19 |
20 | $port = config('database.redis.default.port');
21 |
22 | $database = config('database.redis.default.database');
23 |
24 | $this->redis->pconnect($host, $port, $database);
25 |
26 | }
27 |
28 | public function getRedis()
29 | {
30 | return $this->redis;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Request.php:
--------------------------------------------------------------------------------
1 | data = json_decode($data);
29 | }
30 |
31 | public function getChannel()
32 | {
33 | try {
34 | $channel = $this->data->channel;
35 | return $channel;
36 | } catch (\Exception $e) {
37 |
38 | }
39 | }
40 |
41 | public function getEvent()
42 | {
43 | try {
44 | $event = $this->data->event;
45 | return $this->getEventNameSpace().$event;
46 | } catch (\Exception $e) {
47 |
48 | }
49 | }
50 |
51 | protected function getEventNameSpace()
52 | {
53 | try {
54 | return $this->data->namespace;
55 | } catch (\Exception $e) {
56 |
57 | }
58 | return $this->eventNameSpace;
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Server.php:
--------------------------------------------------------------------------------
1 | serv = new SocketServer();
26 |
27 | $this->serv->start();
28 | }
29 | }
--------------------------------------------------------------------------------
/src/SocketServer.php:
--------------------------------------------------------------------------------
1 | socketServer = new swoole_websocket_server(config('echo.host'), config('echo.port'));
26 |
27 | $this->socketServer->set([
28 | 'worker_num' => 8,
29 | 'daemonize' => false,
30 | ]);
31 |
32 | $this->echoMessage = new EchoMessage();
33 |
34 | $this->socketServer->on('open', [$this, 'onOpen']);
35 | $this->socketServer->on('message', [$this->echoMessage, 'message']);
36 | $this->socketServer->on('close', [$this, 'onClose']);
37 |
38 | }
39 |
40 |
41 | public function start()
42 | {
43 | $this->socketServer->start();
44 | }
45 |
46 |
47 |
48 | public function onOpen($socketServer, $request)
49 | {
50 | // $fd[] = $request->fd;
51 | // $fds[] = $fd;
52 | // $this->echoMessage->setFd($fds);
53 | }
54 |
55 |
56 | public function onClose($socketServer, $fd)
57 | {
58 | echo "client-{$fd} is closed\n";
59 | }
60 |
61 | }
--------------------------------------------------------------------------------