Docs

  • Channels Channels
  • Beams Beams
  • Developers
  • Support
  • Blog
  • Sign up
    • Search powered by Algolia
    • Sign in
    • Sign up
    • Channels
    • Getting started
      • SDK quick starts
        • JavaScript quick start
        • iOS quick start
        • Android quick start
        • Flutter quick start
      • Use case quick starts
        • Javascript realtime chart
        • Javascript realtime user list
      • Debugging
    • Using channels
      • Client API overview
      • Connection
      • User authentication
      • Authorized connections
      • Channels
      • Public channels
      • Private channels
      • Encrypted channels
      • Presence channels
      • Cache channels
      • Events
      • Global configuration
      • Websocket fallbacks
      • Device compatibility
    • Server api
      • Overview
      • HTTP API interaction
      • Webhooks
      • Authenticating users
      • Authorizing users
      • Sending events to authenticated users
      • Terminating user connections
      • Excluding event recipients
    • Channels libraries
      • API libraries
    • Pusher cli
      • Overview
      • Installation
      • Documentation
    • Miscellaneous
      • Clusters
      • Integrations
      • Resources
    • Library auth reference
      • Authentication and authorization signatures
      • HTTP API reference
      • Pusher Channels Protocol
      • Server library reference specification
      • Logging
    • Beams
    • Pusher lab

    Events

    Events are the primary method of packaging messages in the Channels system. They form the basis of all communication.

    They are essentially ‘named messages’ which means you can set up ‘handlers’ in your client code to deal with the various types. As such they are used for ‘client-side’ routing, and should not be used as filters (channels can do this much more efficiently on the server side).

    Events can be seen as a notification of something happening on your system, and they are often named in the past tense. For example: message-created, todo-finished.

    ∞ Binding to events

    Most binding and triggering behaviour is attached to channels the client is subscribed to (see binding on the channel below). It is also possible to bind to the user object to handle messages addressed to the authenticated user. All published messages can be bound to in aggregate via the connection object itself. This aggregated binding triggers for both channel messages and user messages (for the currently authenticated user).

    ∞ Binding on the channel

    Events can be bound to directly on a channel which means you will only received an event if it is sent on that specific channel.

    channel.bind(eventName, callback);
    let myChannel = pusher.subscribe("chat")
    myChannel.bind(eventName: "new-message", eventCallback: { (event: PusherEvent) -> Void in
    if let data: String = event.data {
    // `data` is a string that you can parse if necessary.
    }
    })
    channel.listen(eventName, callback);
    ∞ eventNameString Required

    The name of the event to bind to.

    ∞ callbackFunction Required

    A function to be called whenever the event is triggered.

    ∞ Example

    The following might be an example of a stock tracking app where several channels are opened for different companies:

    var pusher = new Pusher("APP_KEY");
    var channel = pusher.subscribe("APPL");
    channel.bind("new-price", (data) => {
    // add new price into the APPL widget
    });
    ∞ Binding with optional this context

    It is possible to provide a third, optional parameter that is used as the this value when calling a handler.

    var context = { title: "Pusher" };
    var handler = () => {
    console.log(`My name is ${this.title}`);
    };
    channel.bind("new-comment", handler, context);
    ∞ PusherChannelString Required

    Once you have created an instance of PusherChannel, you can set up event bindings. There is no need to wait for the PusherSwift client connection to be established.

    When you bind to events on a single channel, you will only receive events with that name if they are sent over this channel.

    ∞ eventNameString Required

    The name of the event to bind to.

    ∞ callbackFunction Required

    A function to be called whenever the event is triggered.

    ∞ Example

    The following might be an example of a stock tracking app where several channels are opened for different companies:

    window.Echo = new Echo({
    broadcaster: "pusher",
    key: "APP_KEY",
    cluster: "eu",
    forceTLS: true,
    });
    var channel = Echo.channel("APPL");
    channel.listen("new-price", (data) => {
    // add new price into the APPL widget
    });

    ∞ Binding on the user object

    It is possible to bind to events on the pusher.user object. That means you will receive events sent to the user that has authenticated on that connection. Check the User authentication docs for more information on authenticating the user and the Sending events to users docs for more information on how to send events to specific users based on user id.

    pusher.user.bind(eventName, callback);

    ∞ Binding on the client

    You can also bind to events regardless of the channel the event is broadcast to. By using the pusher.bind() method rather than channel.bind(), you can listen for an event on all the channels that you are currently subscribed to.

    The following is an example of an app that binds to a new-comment event from all channels that we’re currently subscribed to:

    pusher.bind(eventName, callback);
    // `binding` is a unique string that can be used to unbind the event callback later
    let binding = pusher.bind(eventCallback: { (event: PusherEvent) -> Void in
    if event.eventName == "new-comment" {
    // Handle the global event
    }
    })
    ∞ eventNameString Required

    The name of the event to bind to.

    ∞ Example
    var pusher = new Pusher("APP_KEY");
    var channel1 = pusher.subscribe("my-channel-1");
    var channel2 = pusher.subscribe("my-channel-2");
    var channel3 = pusher.subscribe("my-channel-3");
    var eventName = "new-comment";
    var callback = (data) => {
    // add comment into page
    };
    // listen for 'new-comment' event on channel 1, 2 and 3
    pusher.bind(eventName, callback);
    ∞ callbackFunction Required

    A function to be called whenever the event is triggered.

    ∞ PusherSwiftPusherSwift Required

    Once you have created an instance of the PusherSwift client, you can set up event bindings. There is no need to wait for the connection to be established.

    When you bind to events on the client, you will receive all events with that name, regardless of the channel from which they originated.

    ∞ Binding to all events from the connection

    It is possible to bind to all events at the global level by using the method bind_global.

    pusher.bind_global(callback);
    ∞ callbackFunction Required

    A function to be called whenever the event is triggered. Your callback will be passed the parameters:

    • eventName (String) The name of the received event
    • data (Object) The payload of the received event
    ∞ Example
    var pusher = new Pusher("APP_KEY");
    var callback = (eventName, data) => {
    console.log(
    `bind global: The event ${eventName} was triggered with data ${JSON.stringify(
    data
    )}
    `

    );
    };
    // bind to all events on the connection
    pusher.bind_global(callback);

    You can also use bind_global at the channel level to bind to all events on the channel, regardless of the event name.

    var pusher = new Pusher("APP_KEY");
    var channel = pusher.subscribe("my-channel");
    var callback = (eventName, data) => {
    console.log(
    `bind global channel: The event ${eventName} was triggered with data ${JSON.stringify(
    data
    )}
    `

    );
    };
    // bind to all events on the channel
    channel.bind_global(callback);

    ∞ Unbinding from events

    It’s possible to remove a binding to an event on a channel.

    channel.unbind(eventName, callback);
    channel.unbind(eventName: eventName, callbackId: binding)
    channel.stopListening(eventName);
    ∞ eventNameString Required

    The name of the event that the binding is to be removed from.

    ∞ callbackFunction Required

    A function event handler used when binding to the event. If no callback function is supplied, all handlers on eventName will be removed.

    ∞ Example
    var pusher = new Pusher("APP_KEY");
    var channel = pusher.subscribe("APPL");
    var callback = (data) => {
    // Do something with the data here
    };
    channel.bind("new-price", callback);

    // Remove just 'handler' for the 'new-price' event
    channel.unbind("new-price", handler);

    // Remove all handlers for the 'new-price' event
    channel.unbind("new-price");

    // Remove all handlers on 'channel'
    channel.unbind();
    ∞ bindingString Optional

    Represents the binding to be removed.

    ∞ Example

    If you no longer want to receive events with a specific name, you can remove the binding. Removing a binding is as simple as storing a reference to the binding object, then passing that as an argument to unbind(callbackId:) at a later point.

    let binding = pusher.bind(eventCallback: { (event: PusherEvent) -> Void in
    if event.eventName == "new-message" {
    // Handle the global event
    }
    })

    pusher.unbind(callbackId: binding)
    ∞ eventNameString Required

    The name of the event that the binding is to be removed from.

    ∞ Example
    window.Echo = new Echo({
    broadcaster: "pusher",
    key: "APP_KEY",
    cluster: "eu",
    forceTLS: true,
    });
    var channel = Echo.channel("APPL");
    var callback = (data) => {
    // Do something with the data here
    };
    channel.listen("new-price", callback);

    // Remove all handlers for the 'new-price' event
    channel.stopListening("new-price");

    ∞ Channel events

    Some events are triggered by Channels and to clearly indicate this, these are prefixed with pusher:.

    ∞ pusher:subscription_succeededEvent

    Once you have subscribed to a channel you can bind to the pusher:subscription_succeeded event so that you know when the subscription has been registered within Channels.

    channel.bind("pusher:subscription_succeeded", () => {});

    This is particularly useful for private and presence channels if you are using client events because you can only trigger an event once a successful subscription has occurred.

    For example, if the channel is a Presence Channel a members event argument is also passed to the pusher:subscription_succeeded event handler. The presence channel also introduces a number of other events that can be bound to. For information please see the presence events docs.

    ∞ pusher:subscription_errorEvent

    Sometimes things go wrong so we have exposed a pusher:subscription_error event that is triggered when an authorization request for a private or presence channels fails. This event is bound to on the channel that is to be authorized.

    The event is triggered either when the authorization endpoint returns a HTTP status code that is not 200 or if there is a problem parsing the JSON that the endpoint returned.

    Note: if the library is unable to create a websocket connection at all, this event will not be emitted. In order to catch events at the connection level you must bind to error events on the connection as described here

    channel.bind("pusher:subscription_error", (error) => {});
    ∞ errorObject

    An error object with the following properties:

    • type (String)
      Category of error that occured, e.g. AuthError
    • error (String)
      Human readable details of error that occurred.
    • status (Number)
      The HTTP Status code of the error response from the authorization call.

    ∞ Example

    var pusher = new Pusher("APP_KEY");
    var channel = pusher.subscribe("private-channel");
    channel.bind("pusher:subscription_error", (error) => {
    var { status } = error;
    if (status == 408 || status == 503) {
    // Retry?
    }
    });
    ∞ pusher:cache_missEvent

    When a client subscribes to a cache channel, you can bind to the pusher:cache_miss event to let the client know if there is no cached message.

    channel.bind("pusher:cache_miss", () => {});

    ∞ Additional presence events

    Presence comes with a number of presence specific events. For more information please see the presence events docs.

    ∞ Triggering client events

    Not all traffic needs to go via your conventional web server when using Channels. Some actions may not need validation or persistence and can go directly via the socket to all the other clients connected to the channel.

    It is important that you apply additional care when using client events, since these originate from other users, and could be subject to tampering by a malicious user of your site.

    Note that you cannot trigger client events from the debug console.

    Client events have a number of enforced restrictions to ensure that the user subscribing to the channel is an authorized user and so that client events can be clearly identified:

    • Client events must be enabled for the application. You can do this in the Settings tab for your app within the Channels dashboard
    • The user must be subscribed to the channel that the event is being triggered on
    • Client events can only be triggered on private and presence channels because they require authorization
    • Client events must be prefixed by client-. Events with any other prefix will be rejected by the Channels server, as will events sent to channels to which the client is not subscribed.
    • You can only trigger a client event once a subscription has been successfully registered with Channels. You can ensure this is the case using the pusher:subscription_succeeded event.
    • Client events are not delivered to the originator of the event. For more information see Message Routing.
    • Publish no more than 10 messages per second per client (connection). Any events triggered above this rate limit will be rejected by our API. See Rate limit your events.
    var triggered = channel.trigger(eventName, data);
    channel.trigger(eventName: eventName, data: data)
    channel.whisper(eventName, data);
    ∞ eventNameString Required

    The name of the event to be triggered. A client event must have a name prefixed with client- or it will be rejected by the server.

    ∞ dataObject Optional

    The object to be converted to JSON and distributed with the event.

    ∞ Returns (Boolean)

    true if the event was successfully triggered, otherwise false

    ∞ Example
    var pusher = new Pusher("YOUR_APP_KEY");
    var channel = pusher.subscribe("private-channel");
    channel.bind("pusher:subscription_succeeded", () => {
    var triggered = channel.trigger("client-someEventName", {
    your: "data",
    });
    });
    ∞ eventNameString Required

    The name of the event to be triggered. If the event name is not prefixed with client- the library will prepend it.

    ∞ dataObject Optional

    The object to be converted to JSON and distributed with the event.

    ∞ Example
    let myPrivateChannel = pusher.subscribe("private-chat")
    myPrivateChannel.trigger(eventName: "myevent", data: ["foo": "bar"])
    ∞ eventNameString Required

    The name of the event to be triggered. A client event must have a name prefixed with client- or it will be rejected by the server.

    ∞ dataObject Optional

    The object to be converted to JSON and distributed with the event.

    ∞ Example
    window.Echo = new Echo({
    broadcaster: "pusher",
    key: "YOUR_APP_KEY",
    cluster: "eu",
    forceTLS: true,
    });
    var channel = Echo.channel("private-channel");
    var callback = (data) => {};
    channel.listen("pusher:subscription_succeeded", () => {
    var triggered = channel.whisper("someeventname", {
    your: "data",
    });
    });

    ∞ Message routing

    When you trigger a client event, the event will not be fired in the client which calls trigger. This is similar to the case described in the page on excluding event recipients.

    ∞ Best practice when sending client events

    As well as the obvious security implications of sending messages from clients, and in particular web browsers, it’s also important to consider what events are sent and when. If the destination client is also a web browser there is only so much data that web browser can handle so there only the required information should be sent at the right time. With this in mind we’ve come up with a few best practice guidelines to follow when trigger client events.

    ∞ Rate limit your events

    ** Publish no more than 10 messages per second per client (connection). Any events triggered above this rate limit will be rejected by our API. **

    This is not a system issue, it is a client issue. 100 clients in a channel sending messages at this rate would each also have to be processing 1,000 messages per second! Whilst some modern browsers might be able to handle this it’s most probably not a good idea.

    ∞ When to trigger events

    The obvious things that result in events being triggered from a client application with a user interface are user actions such as mouse movement or key presses. In this scenario we still need to consider limiting how much information we send. Quite frequently a UI event should not lead directly to a client event being published into Channels.

    For example, if you have bound the the mousemove event and a user is wildly waving their pointer around the screen it’s not a good idea to translate each mouse move event into a client event. Instead you should define an interval at which the mouse position should be sent and if the mouse position has moved when the next interval fires send a single client event. The time interval may need to be tuned to suit your requirements.

    ∞ Example
    var outputEl = document.getElementById("client_event_example_log");
    var state = { currentX: 0, currentY: 0, lastX: undefined, lastY: undefined };
    var pusher = new Pusher("YOUR_APP_KEY");
    var channel = pusher.subscribe("private-mousemoves");
    // this method should be bound as a 'mousemove' event listener document.body.
    addEventListener("mousemove", onMouseMove, false);
    var onMouseMove = (ev) => {
    ev = ev || window.event;
    state.currentX = ev.pageX || ev.clientX;
    state.currentY = ev.pageY || ev.clientY;
    };
    setInterval(() => {
    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

    ∞ user_id in client events

    When you bind to client events on presence channels, your bound callback will be called with a metadata object as the second argument. This metadata object contains a user_id key, the value of which is the user_id of the client that triggered the event, as taken from the authorization token generated by your server for that client.

    const channel = pusher.subscribe("presence-chat");
    channel.bind("client-msg", (data, metadata) => {
    console.log(
    "I received",
    data,
    "from user",
    metadata.user_id,
    "with user info",
    channel.members.get(metadata.user_id).info
    );
    });

    The user_id field is useful for displaying the author of an event. You should trust the user_id from the metadata object, rather than embedding a user ID in the data object, which would allow any client to impersonate any user!

    When you bind to client events on presence channels, your bound callback will be called with a PusherEvent object as the only argument. This object has a userId key, accessible by calling getUserId() on the event. The value of this is the user_id of the client that triggered the event, as taken from the authorization token generated by your server for that client.

    channel.bind("client-my-event", new SubscriptionEventListener() {
    @Override
    public void onEvent(PusherEvent event) {
    System.out.println("Received event with userId: " + event.getUserId());
    }
    });

    The getUserId() method is useful for displaying the author of an event. You should trust the user ID returned by getUserId(), rather than embedding a user ID in the data object, which would allow any client to impersonate any user!

    When you bind to client events on presence channels, your bound callback will be called with a PusherEvent object as the only argument. This object has a userId property. The value of this is the user_id of the client that triggered the event, as taken from the authorization token generated by your server for that client.

    channel.bind(eventName: "client-my-event", eventCallback: {(event: PusherEvent) in
    if let userId = event.userId {
    print("Received event with userId: \(userId)")
    }
    })

    The userId property is useful for displaying the author of an event. You should trust the userId from the PusherEvent object, rather than embedding a user ID in the data object, which would allow any client to impersonate any user!

    ∞ See also

    • Connection status events
    • Presence events

    Contents

    • Binding to events
      1. Binding on the channel
      2. Binding on the user object
      3. Binding on the client
      4. Binding to all events from the connection
    • Unbinding from events
    • Channel events
      1. Additional presence events
    • Triggering client events
    • Message routing
    • Best practice when sending client events
      1. Rate limit your events
      2. When to trigger events
    • user_id in client events
    • See also

    Spotted something that isn’t quite right? Create an issue on GitHub.

    Copyright © 2020 Pusher Ltd. All rights reserved.

    • Support,
    • Status
    • Twitter
    • GitHub