Merge pull request #5907 from tkqubo/pusher-js

Add pusher-js
This commit is contained in:
Masahiro Wakame
2015-09-20 19:20:16 +09:00
2 changed files with 584 additions and 0 deletions
+353
View File
@@ -0,0 +1,353 @@
/// <reference path="pusher-js.d.ts" />
import Pusher = require('pusher-js');
import { PresenceChannel } from "pusher-js";
var API_KEY: string;
var pusher: Pusher.Pusher;
//
// Configuration
//
pusher = new Pusher(API_KEY, {
authEndpoint: "http://example.com/pusher/auth"
});
pusher = new Pusher(API_KEY, {
auth: {
params: { foo: "bar" },
headers: { baz: "boo" }
}
});
pusher = new Pusher(API_KEY, {
auth: {
params: { foo: "bar" },
headers: { "X-CSRF-Token": "SOME_CSRF_TOKEN" }
}
});
pusher = new Pusher(API_KEY, { cluster: "eu" });
pusher = new Pusher(API_KEY, { enabledTransports: ["ws"] });
pusher = new Pusher(API_KEY, { disabledTransports: ["sockjs"] });
// will only use WebSockets
pusher = new Pusher(API_KEY, {
enabledTransports: ["ws", "xhr_streaming"],
disabledTransports: ["xhr_streaming"]
});
//
// Connection
//
var socket: Pusher.Pusher;
var my_channel: Pusher.Channel;
var channels: Pusher.Channel[];
socket = new Pusher(API_KEY);
//
// Subscribing to channels
//
my_channel = socket.subscribe('my-channel');
my_channel = socket.subscribe('private-my-channel');
channels = socket.allChannels();
console.group('Pusher - subscribed to:');
for (var i = 0; i < channels.length; i++) {
var channel = channels[i];
console.log(channel.name);
}
console.groupEnd();
my_channel = socket.subscribe('my-channel');
socket.bind('new-comment',
function(data: any) {
// add comment into page
}
);
var channel: Pusher.Channel;
var context = { title: 'Pusher' };
var handler = function(){
console.log('My name is ' + this.title);
};
channel.bind('new-comment', handler, context);
channel.unbind('new-comment', handler); // removes just `handler` for the `new-comment` event
channel.unbind('new-comment'); // removes all handlers for the `new-comment` event
channel.unbind(null, handler); // removes `handler` for all events
channel.unbind(null, null, context); // removes all handlers for `context`
channel.unbind(); // removes all handlers on `channel`
//
//
// Samples from Pusher Documentation
//
//
//
// JavaScript Quick Start Guide
//
channel.bind('my-event', function(data: any) {
alert('An event was triggered with message: ' + data.message);
});
//
// Client API Overview
//
var options: Pusher.Config;
var channelName: string;
var privateChannelName: string;
var presenceChannelName: string;
var add_member: Function;
var remove_member: Function;
var update_member_count: Function;
var eventName: string;
var callback: Function;
var applicationKey: string;
var log: Function;
var $: any;
var data: any;
// Connecting to Pusher
pusher = new Pusher(applicationKey, options);
options = {
encrypted: true, // true/false
auth: {
params: { // {key: value} pairs
param1: 'value1',
param2: 'value2'
},
headers: { // {key: value} pairs
header1: 'value1',
header2: 'value2'
}
}
};
pusher = new Pusher('app_key', {
auth: {
params: {
CSRFToken: 'some_csrf_token'
}
}
});
pusher = new Pusher('app_key', {
auth: {
headers: {
'X-CSRF-Token': 'some_csrf_token'
}
}
});
pusher = new Pusher('app_key', { cluster: 'eu' });
pusher = new Pusher('app_key', { encrypted: true } );
pusher = new Pusher('app_key');
pusher.connection.bind( 'error', function( err: any ) {
if( err.data.code === 4004 ) {
log('>>> detected limit error');
}
});
// Disconnecting from Pusher
pusher.disconnect();
// Connection States
pusher = new Pusher('YOUR_APP_KEY');
pusher.connection.bind('connected', function() {
$('div#status').text('Real time is go!');
});
pusher.connection.bind('connecting_in', function(delay: any) {
alert("I haven't been able to establish a connection for this feature. " +
"I will try again in " + delay + " seconds.")
});
pusher.connection.bind('state_change', function(states: any) {
// states = {previous: 'oldState', current: 'newState'}
$('div#status').text("Pusher's current state is " + states.current);
});
var connectionState: string = pusher.connection.state;
// Accessing channels
channel = pusher.channel(channelName);
// Public channels
channel = pusher.subscribe(channelName);
pusher.unsubscribe(channelName);
// Private channels
var privateChannel = pusher.subscribe(privateChannelName);
// Presence channels
var presenceChannel: PresenceChannel<any> = <any>pusher.subscribe(presenceChannelName);
var count: number = presenceChannel.members.count;
presenceChannel.members.each(function(member: Pusher.UserInfo<any>) {
var userId = member.id;
var userInfo = member.info;
});
var some_user_id: number;
var user = presenceChannel.members.get(some_user_id);
var me = presenceChannel.members.me;
pusher = new Pusher('app_key');
presenceChannel = <any>pusher.subscribe('presence-example');
presenceChannel.bind('pusher:subscription_succeeded', function() {
var me = presenceChannel.members.me;
var userId = me.id;
var userInfo = me.info;
});
channel = pusher.subscribe('presence-meeting-11');
channel.bind('pusher:subscription_succeeded', function(members: Pusher.Members<any>) {
// for example
update_member_count(members.count);
members.each(function(member) {
// for example:
add_member(member.id, member.info);
});
});
channel.bind('pusher:member_added', function(member: Pusher.UserInfo<any>) {
// for example:
add_member(member.id, member.info);
});
channel.bind('pusher:member_removed', function(member: Pusher.UserInfo<any>) {
// for example:
remove_member(member.id, member.info);
});
// Pusher Events
channel.bind(eventName, callback);
pusher = new Pusher('APP_KEY');
channel = pusher.subscribe('APPL');
channel.bind('new-price',
function(data: any) {
// add new price into the APPL widget
}
);
var context = { title: 'Pusher' };
var handler = function(){
console.log('My name is ' + this.title);
};
channel.bind('new-comment', handler, context);
pusher.bind(eventName, callback);
pusher = new Pusher('APP_KEY');
var channel1 = pusher.subscribe('test_channel_1');
var channel2 = pusher.subscribe('test_channel_2');
var channel3 = pusher.subscribe('test_channel_3');
var eventName = 'new-comment';
callback = function(data: any) {
// add comment into page
};
// listen for 'new-comment' event on channel 1, 2 and 3
pusher.bind(eventName, callback);
// Unbinding from Events
channel.unbind(eventName, callback);
pusher = new Pusher('APP_KEY');
channel = pusher.subscribe('APPL');
callback = function(data: any) {};
channel.bind('new-price', callback);
channel.unbind('new-price', callback);
// Pusher channel events
channel.bind('pusher:subscription_succeeded', function() {
});
pusher = new Pusher('APP_KEY');
channel = pusher.subscribe('private-channel');
channel.bind('pusher:subscription_error', function(status: number) {
if(status == 408 || status == 503){
// retry?
}
});
// Triggering Client Events
var triggered = channel.trigger(eventName, data);
pusher = new Pusher('YOUR_APP_KEY');
channel = pusher.subscribe('private-channel');
channel.bind('pusher:subscription_succeeded', function() {
var triggered = channel.trigger('client-someeventname', { your: data });
});
// Best practice when sending client events
var outputEl = document.getElementById('client_event_example_log');
var state: any = {
currentX: 0,
currentY: 0,
lastX: undefined,
lastY: undefined
};
pusher = new Pusher("YOUR_APP_KEY");
channel = pusher.subscribe("private-mousemoves");
// this method should be bound as a 'mousemove' event listener
document.body.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(ev: any){
ev = ev || window.event;
state.currentX = ev.pageX || ev.clientX;
state.currentY = ev.pageY || ev.clientY;
}
setInterval(function(){
if(state.currentX !== state.lastX || state.currentY !== state.lastY){
state.lastX = state.currentX;
state.lastY = state.currentY;
var text = document.createTextNode(
'Triggering event due to state change: x: ' + state.currentX + ', y: ' + state.currentY
);
outputEl.replaceChild( text, outputEl.firstChild );
channel.trigger("client-mouse-moved", {x:state.currentX, y: state.currentY});
}
}, 300); // send every 300 milliseconds if position has changed
+231
View File
@@ -0,0 +1,231 @@
// Type definitions for pusher-js 3.0.0
// Project: https://github.com/pusher/pusher-js
// Definitions by: Qubo <https://github.com/tkqubo>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare module "pusher-js" {
namespace pusher {
interface PusherStatic {
new(apiKey: string, config?: Config): Pusher;
}
interface Pusher {
subscribe(name: string): Channel;
subscribeAll(): void;
unsubscribe(name: string): void;
channel(name: string): Channel;
allChannels(): Channel[];
bind(eventName: string, callback: Function): Pusher;
bind_all(callback: Function): Pusher;
disconnect(): void;
key: string;
config: Config; //TODO: add GlobalConfig typings
channels: any; //TODO: Type this
global_emitter: EventsDispatcher;
sessionId: number;
timeline: any; //TODO: Type this
connection: ConnectionManager;
}
interface Config {
/**
* Forces the connection to use encrypted transports.
*/
encrypted?: boolean;
/**
* Endpoint on your server that will return the authentication signature needed for private channels.
*/
authEndpoint?: string;
/**
* Defines how the authentication endpoint, defined using authEndpoint, will be called.
* There are two options available: ajax and jsonp.
*/
authTransport?: string;
/**
* Allows passing additional data to authorizers. Supports query string params and headers (AJAX only).
* For example, following will pass foo=bar via the query string and baz: boo via headers:
*/
auth?: AuthConfig;
/**
* Allows connecting to a different datacenter by setting up correct hostnames and ports for the connection.
*/
cluster?: string;
/**
* Disables stats collection, so that connection metrics are not submitted to Pushers servers.
*/
disableStats?: boolean;
/**
* Specifies which transports should be used by Pusher to establish a connection.
* Useful for applications running in controlled, well-behaving environments.
* Available transports: ws, wss, xhr_streaming, xhr_polling, sockjs.
* Additional transports may be added in the future and without adding them to this list, they will be disabled.
*/
enabledTransports?: string[];
/**
* Specified which transports must not be used by Pusher to establish a connection.
* This settings overwrites transports whitelisted via the enabledTransports options.
* Available transports: ws, wss, xhr_streaming, xhr_polling, sockjs.
* Additional transports may be added in the future and without adding them to this list, they will be enabled.
*/
disabledTransports?: string[];
/**
* Ignores null origin checks for HTTP fallbacks. Use with care, it should be disabled only if necessary (i.e. PhoneGap).
*/
ignoreNullOrigin?: boolean;
/**
* After this time (in miliseconds) without any messages received from the server,
* a ping message will be sent to check if the connection is still working.
* Default value is is supplied by the server, low values will result in unnecessary traffic.
*/
activityTimeout?: number;
/**
* Time before the connection is terminated after sending a ping message.
* Default is 30000 (30s). Low values will cause false disconnections, if latency is high.
*/
pongTimeout?: number;
wsHost?: string;
wsPort?: number;
wssPort?: number;
httpHost?: string;
httpPort?: number;
httpsPort?: number;
}
interface AuthConfig {
params?: { [key: string]: any };
headers?: { [key: string]: any };
}
interface GenericEventsDispatcher<Self extends EventsDispatcher> extends EventsDispatcher {
bind(eventName: string, callback: Function, context?: any): Self;
bind_all(callback: Function): Self;
unbind(eventName?: string, callback?: Function, context?: any): Self;
unbind_all(eventName?: string, callback?: Function): Self;
emit(eventName: string, data?: any): Self;
}
interface Channel extends GenericEventsDispatcher<Channel> {
/** Triggers an event */
trigger(eventName: string, data?: any): boolean;
pusher: Pusher;
name: string;
subscribed: boolean;
/**
* Authenticates the connection as a member of the channel.
* @param {String} socketId
* @param {Function} callback
*/
authorize(socketId: string, callback: (data: any) => void): void;
}
interface EventsDispatcher {
bind(eventName: string, callback: Function, context?: any): EventsDispatcher;
bind_all(callback: Function): EventsDispatcher;
unbind(eventName?: string, callback?: Function, context?: any): EventsDispatcher;
unbind_all(eventName?: string, callback?: Function): EventsDispatcher;
emit(eventName: string, data?: any): EventsDispatcher;
}
interface ConnectionManager extends GenericEventsDispatcher<ConnectionManager> {
key: string;
options: any; //TODO: Timeline.js
state: string;
connection: any; //TODO: Type this
encrypted: boolean;
timeline: any; //TODO: Type this
connectionCallbacks: {
message: (message: string) => void;
ping: () => void;
activity: () => void;
error: (error: any) => void;
closed: () => void;
};
errorCallbacks: {
ssl_only: () => void;
refused: () => void;
backoff: () => void;
retry: () => void;
};
handshakeCallbacks: {
ssl_only: () => void;
refused: () => void;
backoff: () => void;
retry: () => void;
connected: (handshake: any) => void; //TODO: Type this
};
/**
* Establishes a connection to Pusher.
*
* Does nothing when connection is already established. See top-level doc
* to find events emitted on connection attempts.
*/
connect(): void;
/**
* Sends raw data.
* @param {String} data
*/
send(data: string): boolean;
/** Sends an event.
*
* @param {String} name
* @param {String} data
* @param {String} [channel]
* @returns {Boolean} whether message was sent or not
*/
send_event(name: string, data: string, channel: string): boolean;
/** Closes the connection. */
disconnect(): void;
isEncrypted(): boolean;
}
interface PresenceChannel<T> extends Channel {
members: Members<T>;
}
interface Members<T> {
/**
* Returns member's info for given id.
*
* Resulting object containts two fields - id and info.
*
* @param {Number} id
* @return {Object} member's info or null
*/
get(id: number): T;
/**
* Calls back for each member in unspecified order.
*
* @param {Function} callback
*/
each(callback: (member: any) => void): void;
members: { [id: number]: UserInfo<T> };
count: number;
myID: number;
me: UserInfo<T>;
}
interface UserInfo<T> {
id: number;
info: T;
}
}
var pusher: pusher.PusherStatic;
export = pusher;
}