Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Broadcasting\Broadcasters;
4
 
5
use Illuminate\Broadcasting\BroadcastException;
6
use Illuminate\Contracts\Redis\Factory as Redis;
7
use Illuminate\Support\Arr;
8
use Predis\Connection\ConnectionException;
9
use RedisException;
10
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
11
 
12
class RedisBroadcaster extends Broadcaster
13
{
14
    use UsePusherChannelConventions;
15
 
16
    /**
17
     * The Redis instance.
18
     *
19
     * @var \Illuminate\Contracts\Redis\Factory
20
     */
21
    protected $redis;
22
 
23
    /**
24
     * The Redis connection to use for broadcasting.
25
     *
150 lars 26
     * @var string|null
148 lars 27
     */
28
    protected $connection = null;
29
 
30
    /**
31
     * The Redis key prefix.
32
     *
33
     * @var string
34
     */
35
    protected $prefix = '';
36
 
37
    /**
38
     * Create a new broadcaster instance.
39
     *
40
     * @param  \Illuminate\Contracts\Redis\Factory  $redis
41
     * @param  string|null  $connection
42
     * @param  string  $prefix
43
     * @return void
44
     */
45
    public function __construct(Redis $redis, $connection = null, $prefix = '')
46
    {
47
        $this->redis = $redis;
48
        $this->prefix = $prefix;
49
        $this->connection = $connection;
50
    }
51
 
52
    /**
53
     * Authenticate the incoming request for a given channel.
54
     *
55
     * @param  \Illuminate\Http\Request  $request
56
     * @return mixed
57
     *
58
     * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
59
     */
60
    public function auth($request)
61
    {
62
        $channelName = $this->normalizeChannelName(
63
            str_replace($this->prefix, '', $request->channel_name)
64
        );
65
 
66
        if (empty($request->channel_name) ||
67
            ($this->isGuardedChannel($request->channel_name) &&
68
            ! $this->retrieveUser($request, $channelName))) {
69
            throw new AccessDeniedHttpException;
70
        }
71
 
72
        return parent::verifyUserCanAccessChannel(
73
            $request, $channelName
74
        );
75
    }
76
 
77
    /**
78
     * Return the valid authentication response.
79
     *
80
     * @param  \Illuminate\Http\Request  $request
81
     * @param  mixed  $result
82
     * @return mixed
83
     */
84
    public function validAuthenticationResponse($request, $result)
85
    {
86
        if (is_bool($result)) {
87
            return json_encode($result);
88
        }
89
 
90
        $channelName = $this->normalizeChannelName($request->channel_name);
91
 
92
        $user = $this->retrieveUser($request, $channelName);
93
 
94
        $broadcastIdentifier = method_exists($user, 'getAuthIdentifierForBroadcasting')
95
                        ? $user->getAuthIdentifierForBroadcasting()
96
                        : $user->getAuthIdentifier();
97
 
98
        return json_encode(['channel_data' => [
99
            'user_id' => $broadcastIdentifier,
100
            'user_info' => $result,
101
        ]]);
102
    }
103
 
104
    /**
105
     * Broadcast the given event.
106
     *
107
     * @param  array  $channels
108
     * @param  string  $event
109
     * @param  array  $payload
110
     * @return void
111
     *
112
     * @throws \Illuminate\Broadcasting\BroadcastException
113
     */
114
    public function broadcast(array $channels, $event, array $payload = [])
115
    {
116
        if (empty($channels)) {
117
            return;
118
        }
119
 
120
        $connection = $this->redis->connection($this->connection);
121
 
122
        $payload = json_encode([
123
            'event' => $event,
124
            'data' => $payload,
125
            'socket' => Arr::pull($payload, 'socket'),
126
        ]);
127
 
128
        try {
129
            $connection->eval(
130
                $this->broadcastMultipleChannelsScript(),
131
                0, $payload, ...$this->formatChannels($channels)
132
            );
133
        } catch (ConnectionException|RedisException $e) {
134
            throw new BroadcastException(
135
                sprintf('Redis error: %s.', $e->getMessage())
136
            );
137
        }
138
    }
139
 
140
    /**
141
     * Get the Lua script for broadcasting to multiple channels.
142
     *
143
     * ARGV[1] - The payload
144
     * ARGV[2...] - The channels
145
     *
146
     * @return string
147
     */
148
    protected function broadcastMultipleChannelsScript()
149
    {
150
        return <<<'LUA'
151
for i = 2, #ARGV do
152
  redis.call('publish', ARGV[i], ARGV[1])
153
end
154
LUA;
155
    }
156
 
157
    /**
158
     * Format the channel array into an array of strings.
159
     *
160
     * @param  array  $channels
161
     * @return array
162
     */
163
    protected function formatChannels(array $channels)
164
    {
165
        return array_map(function ($channel) {
166
            return $this->prefix.$channel;
167
        }, parent::formatChannels($channels));
168
    }
169
}