All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src-html.com.pusher.client.Pusher.html Maven / Gradle / Ivy




Source code



001package com.pusher.client;
002
003import com.pusher.client.channel.Channel;
004import com.pusher.client.channel.ChannelEventListener;
005import com.pusher.client.channel.PresenceChannel;
006import com.pusher.client.channel.PresenceChannelEventListener;
007import com.pusher.client.channel.PrivateChannel;
008import com.pusher.client.channel.PrivateChannelEventListener;
009import com.pusher.client.channel.SubscriptionEventListener;
010import com.pusher.client.channel.impl.ChannelManager;
011import com.pusher.client.channel.impl.InternalChannel;
012import com.pusher.client.channel.impl.PresenceChannelImpl;
013import com.pusher.client.channel.impl.PrivateChannelImpl;
014import com.pusher.client.connection.Connection;
015import com.pusher.client.connection.ConnectionEventListener;
016import com.pusher.client.connection.ConnectionState;
017import com.pusher.client.connection.impl.InternalConnection;
018import com.pusher.client.util.Factory;
019
020/**
021 * This class is the main entry point for accessing Pusher.
022 *
023 * <p>
024 * By creating a new {@link Pusher} instance and calling {@link
025 * Pusher#connect()} a connection to Pusher is established.
026 * </p>
027 *
028 * <p>
029 * Subscriptions for data are represented by
030 * {@link com.pusher.client.channel.Channel} objects, or subclasses thereof.
031 * Subscriptions are created by calling {@link Pusher#subscribe(String)},
032 * {@link Pusher#subscribePrivate(String)},
033 * {@link Pusher#subscribePresence(String)} or one of the overloads.
034 * </p>
035 */
036public class Pusher implements Client {
037
038    private final PusherOptions pusherOptions;
039    private final InternalConnection connection;
040    private final ChannelManager channelManager;
041    private final Factory factory;
042
043    /**
044     * Creates a new instance of Pusher.
045     *
046     * <p>
047     * Note that if you use this constructor you will not be able to subscribe
048     * to private or presence channels because no {@link Authorizer} has been
049     * set. If you want to use private or presence channels:
050     * <ul>
051     * <li>Create an implementation of the {@link Authorizer} interface, or use
052     * the {@link com.pusher.client.util.HttpAuthorizer} provided.</li>
053     * <li>Create an instance of {@link PusherOptions} and set the authorizer on
054     * it by calling {@link PusherOptions#setAuthorizer(Authorizer)}.</li>
055     * <li>Use the {@link #Pusher(String, PusherOptions)} constructor to create
056     * an instance of Pusher.</li>
057     * </ul>
058     *
059     * <p>
060     * The {@link com.pusher.client.example.PrivateChannelExampleApp} and
061     * {@link com.pusher.client.example.PresenceChannelExampleApp} example
062     * applications show how to do this.
063     * </p>
064     *
065     * @param apiKey
066     *            Your Pusher API key.
067     */
068    public Pusher(final String apiKey) {
069
070        this(apiKey, new PusherOptions());
071    }
072
073    /**
074     * Creates a new instance of Pusher.
075     *
076     * @param apiKey
077     *            Your Pusher API key.
078     * @param pusherOptions
079     *            Options for the Pusher client library to use.
080     */
081    public Pusher(final String apiKey, final PusherOptions pusherOptions) {
082
083        this(apiKey, pusherOptions, new Factory());
084    }
085
086    /**
087     * Creates a new Pusher instance using the provided Factory, package level
088     * access for unit tests only.
089     */
090    Pusher(final String apiKey, final PusherOptions pusherOptions, final Factory factory) {
091
092        if (apiKey == null || apiKey.length() == 0) {
093            throw new IllegalArgumentException("API Key cannot be null or empty");
094        }
095
096        if (pusherOptions == null) {
097            throw new IllegalArgumentException("PusherOptions cannot be null");
098        }
099
100        this.pusherOptions = pusherOptions;
101        this.factory = factory;
102        connection = factory.getConnection(apiKey, this.pusherOptions);
103        channelManager = factory.getChannelManager();
104        channelManager.setConnection(connection);
105    }
106
107    /* Connection methods */
108
109    /**
110     * Gets the underlying {@link Connection} object that is being used by this
111     * instance of {@linkplain Pusher}.
112     *
113     * @return The {@link Connection} object.
114     */
115    public Connection getConnection() {
116        return connection;
117    }
118
119    /**
120     * Connects to Pusher. Any {@link ConnectionEventListener}s that have
121     * already been registered using the
122     * {@link Connection#bind(ConnectionState, ConnectionEventListener)} method
123     * will receive connection events.
124     *
125     * <p>Calls are ignored (a connection is not attempted) if the {@link Connection#getState()} is not {@link com.pusher.client.connection.ConnectionState#DISCONNECTED}.</p>
126     */
127    public void connect() {
128        connect(null);
129    }
130
131    /**
132     * Binds a {@link ConnectionEventListener} to the specified events and then
133     * connects to Pusher. This is equivalent to binding a
134     * {@link ConnectionEventListener} using the
135     * {@link Connection#bind(ConnectionState, ConnectionEventListener)} method
136     * before connecting.
137     *
138     <p>Calls are ignored (a connection is not attempted) if the {@link Connection#getState()} is not {@link com.pusher.client.connection.ConnectionState#DISCONNECTED}.</p>
139     *
140     * @param eventListener
141     *            A {@link ConnectionEventListener} that will receive connection
142     *            events. This can be null if you are not interested in
143     *            receiving connection events, in which case you should call
144     *            {@link #connect()} instead of this method.
145     * @param connectionStates
146     *            An optional list of {@link ConnectionState}s to bind your
147     *            {@link ConnectionEventListener} to before connecting to
148     *            Pusher. If you do not specify any {@link ConnectionState}s
149     *            then your {@link ConnectionEventListener} will be bound to all
150     *            connection events. This is equivalent to calling
151     *            {@link #connect(ConnectionEventListener, ConnectionState...)}
152     *            with {@link ConnectionState#ALL}.
153     * @throws IllegalArgumentException
154     *             If the {@link ConnectionEventListener} is null and at least
155     *             one connection state has been specified.
156     */
157    public void connect(final ConnectionEventListener eventListener, ConnectionState... connectionStates) {
158
159        if (eventListener != null) {
160            if (connectionStates.length == 0) {
161                connectionStates = new ConnectionState[] { ConnectionState.ALL };
162            }
163
164            for (final ConnectionState state : connectionStates) {
165                connection.bind(state, eventListener);
166            }
167        }
168        else {
169            if (connectionStates.length > 0) {
170                throw new IllegalArgumentException(
171                        "Cannot bind to connection states with a null connection event listener");
172            }
173        }
174
175        connection.connect();
176    }
177
178    /**
179     * Disconnect from Pusher.
180     *
181     * <p>
182     * Calls are ignored if the {@link Connection#getState()}, retrieved from {@link Pusher#getConnection}, is not
183     * {@link com.pusher.client.connection.ConnectionState#CONNECTED}.
184     * </p>
185     */
186    public void disconnect() {
187        if (connection.getState() == ConnectionState.CONNECTED) {
188            connection.disconnect();
189        }
190    }
191
192    /* Subscription methods */
193
194    /**
195     * Subscribes to a public {@link Channel}.
196     *
197     * Note that subscriptions should be registered only once with a Pusher
198     * instance. Subscriptions are persisted over disconnection and
199     * re-registered with the server automatically on reconnection. This means
200     * that subscriptions may also be registered before connect() is called,
201     * they will be initiated on connection.
202     *
203     * @param channelName
204     *            The name of the {@link Channel} to subscribe to.
205     * @return The {@link Channel} object representing your subscription.
206     */
207    public Channel subscribe(final String channelName) {
208        return subscribe(channelName, null);
209    }
210
211    /**
212     * Binds a {@link ChannelEventListener} to the specified events and then
213     * subscribes to a public {@link Channel}.
214     *
215     * @param channelName
216     *            The name of the {@link Channel} to subscribe to.
217     * @param listener
218     *            A {@link ChannelEventListener} to receive events. This can be
219     *            null if you don't want to bind a listener at subscription
220     *            time, in which case you should call {@link #subscribe(String)}
221     *            instead of this method.
222     * @param eventNames
223     *            An optional list of event names to bind your
224     *            {@link ChannelEventListener} to before subscribing.
225     * @return The {@link Channel} object representing your subscription.
226     * @throws IllegalArgumentException
227     *             If any of the following are true:
228     *             <ul>
229     *             <li>The channel name is null.</li>
230     *             <li>You are already subscribed to this channel.</li>
231     *             <li>The channel name starts with "private-". If you want to
232     *             subscribe to a private channel, call
233     *             {@link #subscribePrivate(String, PrivateChannelEventListener, String...)}
234     *             instead of this method.</li>
235     *             <li>At least one of the specified event names is null.</li>
236     *             <li>You have specified at least one event name and your
237     *             {@link ChannelEventListener} is null.</li>
238     *             </ul>
239     */
240    public Channel subscribe(final String channelName, final ChannelEventListener listener, final String... eventNames) {
241
242        final InternalChannel channel = factory.newPublicChannel(channelName);
243        channelManager.subscribeTo(channel, listener, eventNames);
244
245        return channel;
246    }
247
248    /**
249     * Subscribes to a {@link com.pusher.client.channel.PrivateChannel} which
250     * requires authentication.
251     *
252     * @param channelName
253     *            The name of the channel to subscribe to.
254     * @return A new {@link com.pusher.client.channel.PrivateChannel}
255     *         representing the subscription.
256     * @throws IllegalStateException
257     *             if a {@link com.pusher.client.Authorizer} has not been set
258     *             for the {@link Pusher} instance via
259     *             {@link #Pusher(String, PusherOptions)}.
260     */
261    public PrivateChannel subscribePrivate(final String channelName) {
262        return subscribePrivate(channelName, null);
263    }
264
265    /**
266     * Subscribes to a {@link com.pusher.client.channel.PrivateChannel} which
267     * requires authentication.
268     *
269     * @param channelName The name of the channel to subscribe to.
270     * @param listener A listener to be informed of both Pusher channel protocol events and subscription data events.
271     * @param eventNames An optional list of names of events to be bound to on the channel. The equivalent of calling {@link com.pusher.client.channel.Channel#bind(String, SubscriptionEventListener)} one or more times.
272     * @return A new {@link com.pusher.client.channel.PrivateChannel} representing the subscription.
273     * @throws IllegalStateException if a {@link com.pusher.client.Authorizer} has not been set for the {@link Pusher} instance via {@link #Pusher(String, PusherOptions)}.
274     */
275    public PrivateChannel subscribePrivate(final String channelName, final PrivateChannelEventListener listener,
276            final String... eventNames) {
277
278        throwExceptionIfNoAuthorizerHasBeenSet();
279
280        final PrivateChannelImpl channel = factory.newPrivateChannel(connection, channelName,
281                pusherOptions.getAuthorizer());
282        channelManager.subscribeTo(channel, listener, eventNames);
283
284        return channel;
285    }
286
287    /**
288     * Subscribes to a {@link com.pusher.client.channel.PresenceChannel} which
289     * requires authentication.
290     *
291     * @param channelName
292     *            The name of the channel to subscribe to.
293     * @return A new {@link com.pusher.client.channel.PresenceChannel}
294     *         representing the subscription.
295     * @throws IllegalStateException
296     *             if a {@link com.pusher.client.Authorizer} has not been set
297     *             for the {@link Pusher} instance via
298     *             {@link #Pusher(String, PusherOptions)}.
299     */
300    public PresenceChannel subscribePresence(final String channelName) {
301        return subscribePresence(channelName, null);
302    }
303
304    /**
305     * Subscribes to a {@link com.pusher.client.channel.PresenceChannel} which
306     * requires authentication.
307     *
308     * @param channelName The name of the channel to subscribe to.
309     * @param listener A listener to be informed of Pusher channel protocol, including presence-specific events, and subscription data events.
310     * @param eventNames An optional list of names of events to be bound to on the channel. The equivalent of calling {@link com.pusher.client.channel.Channel#bind(String, SubscriptionEventListener)} one or more times.
311     * @return A new {@link com.pusher.client.channel.PresenceChannel} representing the subscription.
312     * @throws IllegalStateException if a {@link com.pusher.client.Authorizer} has not been set for the {@link Pusher} instance via {@link #Pusher(String, PusherOptions)}.
313     */
314    public PresenceChannel subscribePresence(final String channelName, final PresenceChannelEventListener listener,
315            final String... eventNames) {
316
317        throwExceptionIfNoAuthorizerHasBeenSet();
318
319        final PresenceChannelImpl channel = factory.newPresenceChannel(connection, channelName,
320                pusherOptions.getAuthorizer());
321        channelManager.subscribeTo(channel, listener, eventNames);
322
323        return channel;
324    }
325
326    /**
327     * Unsubscribes from a channel using via the name of the channel.
328     *
329     * @param channelName
330     *            the name of the channel to be unsubscribed from.
331     */
332    public void unsubscribe(final String channelName) {
333
334        channelManager.unsubscribeFrom(channelName);
335    }
336
337    /* implementation detail */
338
339    private void throwExceptionIfNoAuthorizerHasBeenSet() {
340        if (pusherOptions.getAuthorizer() == null) {
341            throw new IllegalStateException(
342                    "Cannot subscribe to a private or presence channel because no Authorizer has been set. Call PusherOptions.setAuthorizer() before connecting to Pusher");
343        }
344    }
345
346    /**
347     *
348     * @param channelName The name of the public channel to be retrieved
349     * @return A public channel, or null if it could not be found
350     * @throws IllegalArgumentException if you try to retrieve a private or presence channel.
351     */
352    public Channel getChannel(String channelName){
353        return channelManager.getChannel(channelName);
354    }
355
356    /**
357     *
358     * @param channelName The name of the private channel to be retrieved
359     * @return A private channel, or null if it could not be found
360     * @throws IllegalArgumentException if you try to retrieve a public or presence channel.
361     */
362    public PrivateChannel getPrivateChannel(String channelName){
363        return channelManager.getPrivateChannel(channelName);
364    }
365
366    /**
367     *
368     * @param channelName The name of the presence channel to be retrieved
369     * @return A presence channel, or null if it could not be found
370     * @throws IllegalArgumentException if you try to retrieve a public or private channel.
371     */
372    public PresenceChannel getPresenceChannel(String channelName){
373        return channelManager.getPresenceChannel(channelName);
374    }
375
376}
































































© 2015 - 2025 Weber Informatics LLC | Privacy Policy