public synchronized InternalConnection getConnection( final String apiKey, final PusherOptions options) { if (connection == null) { try { connection = new WebSocketConnection( options.buildUrl(apiKey), options.getActivityTimeout(), options.getPongTimeout(), options.getProxy(), this); } catch (final URISyntaxException e) { throw new IllegalArgumentException("Failed to initialise connection", e); } } return connection; }
/** * Constructs a new PusherClientEndpoint based on the given URI and parameters. The URI should be * of the form * * <pre> * pusher-client://{app-key}/{channel_name}?events=event1,event2... * </pre> * * To create an endpoint for a private or presence channel (i.e. one where the channel name being * with 'private-' or 'presence-'), there must be an {@link com.pusher.client.Authorizer} instance * (e.g. {@link com.pusher.client.util.HttpAuthorizer}) registered in the {@link * org.apache.camel.spi.Registry} of the current {@link org.apache.camel.CamelContext}. If more * than one Authorizer is registered, the one whose name includes the app-key present in the URI * will be chosen. * * <p>A presence channel endpoint will automatically receive events when a member is added or * removed; no need to register for these events explicitly. * * @param uri the URI of the endpoint * @param remaining the un-matched portion of the URI * @param parameters a map of any query parameters on the endpoint URI * @return a PusherClientEndpoint constructed from the given URI * @throws Exception */ protected PusherClientEndpoint createEndpoint( String uri, String remaining, Map<String, Object> parameters) throws Exception { // Extract app key and channel name from endpoint URI String[] path = remaining.split("/"); if (path.length != 2) { throw new IllegalArgumentException( "Pusher uri path must contain app key and channel name: " + SCHEME + "://{app-key}/{channel_name}"); } final String appKey = path[0]; final String channelName = path[1]; final String channelId = getChannelId(appKey, channelName); // Set Pusher options - first, try to find an Authorizer instance in the registry PusherOptions options = new PusherOptions(); Map<String, Authorizer> authorizers = getCamelContext().getRegistry().findByTypeWithName(Authorizer.class); if (authorizers.size() == 1) { LOG.debug("Found 1 authorizer: {}", authorizers.keySet().iterator().next()); options.setAuthorizer(authorizers.values().iterator().next()); } else if (authorizers.size() > 1) { LOG.debug("Found {} authorizers", authorizers.size()); for (String name : authorizers.keySet()) { if (name.contains(appKey)) { LOG.debug("Setting authorizer: " + name); options.setAuthorizer(authorizers.get(name)); break; } } options.setAuthorizer(authorizers.values().iterator().next()); } // set options from the endpoint parameters setProperties(options, parameters); // Create a new pusher from these options, and add to our collection of apps if not // already there Pusher pusher = apps.putIfAbsent(appKey, new Pusher(appKey, options)); if (pusher == null) { LOG.debug("Creating new Pusher instance for appKey: {}", appKey); pusher = apps.get(appKey); // Connect to the app pusher.connect( new ConnectionEventListener() { @Override public void onConnectionStateChange(ConnectionStateChange change) { LOG.info( "Pusher app {} connection state change from {} to {}", new Object[] {appKey, change.getPreviousState(), change.getCurrentState()}); if (change.getCurrentState() == ConnectionState.CONNECTED) { finished(change.getCurrentState()); } } @Override public void onError(String message, String code, Exception e) { LOG.error( "Pusher could not connect to app {}: {} ({})", new Object[] {appKey, message, code}); finished(e); } }, ConnectionState.ALL); join(); // Wait for connection LOG.info("Pusher connected to app {}", appKey); // Listen for disconnections, and re-connect if they occur. final Pusher finalPusher = pusher; pusher .getConnection() .bind( ConnectionState.DISCONNECTED, new ConnectionEventListener() { @Override public void onConnectionStateChange(ConnectionStateChange change) { if (change.getCurrentState() == ConnectionState.DISCONNECTED && !isStoppingOrStopped()) { LOG.info("App {} disconnected. Reconnecting..."); finalPusher.connect(); } } @Override public void onError(String message, String code, Exception e) { LOG.error("Message: {}, code: {}", message, code); } }); } Channel channel = channels.get(channelId); if (subscriptions.add(channelId)) { // Subscribe to the channel LOG.debug("Subscribing to channel {}", channelId); // Set up callbacks appropriate to the type of channel - public, private or presence PresenceChannelEventListener presenceListener = subscriptionListener(channelId); if (channelName.startsWith("private-")) { channel = pusher.subscribePrivate(channelName, presenceListener); } else if (channelName.startsWith("presence-")) { channel = pusher.subscribePresence(channelName, presenceListener); } else { channel = pusher.subscribe(channelName, presenceListener); } join(); // Wait for channel subscription LOG.info("Subscribed to channel {}", channelId); channels.put(channelId, channel); } // Create a new endpoint for this URI, and set properties on it final PusherClientEndpoint endpoint = new PusherClientEndpoint(uri, this, appKey, channel); setProperties(endpoint, parameters); return endpoint; }