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
        • React Native quick start
      • Use case quick starts
        • Javascript realtime chart
        • Javascript realtime user list
      • Debugging
    • Using channels
      • Client API overview
      • Connection
      • User authentication
      • Watchlist events
      • Functions
      • 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 to which the client is subscribed to (refer to Binding on the channel section). 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. This means you will only receive 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

    Here’s 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

    You can bind to events on the pusher.user object. That means you will receive events sent to the user that has authenticated on that connection. Refer to User authentication for more information on authenticating users. Refer to Sending events to users for more information on how to send events to specific users based on user ID.

    pusher.user.bind(eventName, callback);
    pusher.user().bind(eventName, new SubscriptionEventListener() {
    public void onEvent(final PusherEvent event) {
    // ...
    }
    });

    ∞ Binding on the user’s Watchlist

    You can bind to events on the pusher.user.watchlist object. That means you will receive events about the Watchlist of the user authenticated on that connection. Refer to User authentication for more information on authenticating users. Refer to Watchlist events for more information on how to provide the user’s Watchlist and how to enable Watchlist events.

    pusher.user.watchlist.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.

    Here’s 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

    This function is 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

    This function is 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 is 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 from which your want to remove the binding.

    ∞ 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 from which your want to remove the binding.

    ∞ 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. 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. That way 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 you have a successful subscription.

    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 more information, refer to Events in Presence Channels.

    ∞ pusher:subscription_errorEvent

    Sometimes things go wrong so we have exposed a pusher:subscription_error event. It 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. To catch events at the connection level, you must bind to error events on the connection as described in Binding to connection events

    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", () => {});
    ∞ pusher:subscription_countEvent

    Provides the number of connections that are currently subscribed to a channel.

    To enable the Subscription Count feature, navigate to the Channels dashboard for your app > App Settings and switch the toggle on. Once activated, the event will be broadcast on all channel types except Presence channels.

    Pusher broadcasts the event to all clients connected to a channel whenever a new client subscribes or unsubscribes. On channels with more than 100 connected clients, the event is sent every 5 seconds as long as there is activity (subscribe or unsubscribe) on the channel.

    channel.bind("pusher:subscription_count", (data) => {
    console.log(data.subscription_count);
    console.log(channel.subscription_count);
    });

    NOTE:
    This Subscription Count event is available for all channel types except Presence channels.

    ∞ Additional presence events

    Presence comes with a number of presence-specific events. For more information, refer to Events in Presence Channels.

    ∞ 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. They can go directly via the socket to all the other clients connected to the channel.

    IMPORTANT:
    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:
    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 which will be triggered. A client event must have a name prefixed with client-. Otherwise, it will be rejected by the server.

    ∞ dataObject Required

    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 which will 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 which will be triggered. A client event must have a name prefixed with client-. Otherwise, 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 Excluding event recipients.

    ∞ Functions

    Through Pusher CLI, you can programmatically respond to any realtime event on Pusher Channels using serverless functions. Use Pusher functions to modify, filter, change, and re-route live events without the need to build or maintain your own server infrastructure.

    ∞ Best practice when sending client events

    Apart from 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. Only the required information should be sent at the right time. With this in mind, we’ve come up with a few best practice for you to follow when triggering 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. For example, 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
      • Binding on the channel
      • Binding on the user object
      • Binding on the user’s Watchlist
      • Binding on the client
      • Binding to all events from the connection
    • Unbinding from events
    • Channel events
      • Additional presence events
    • Triggering client events
    • Message routing
    • Functions
    • Best practice when sending client events
      • Rate limit your events
      • When to trigger events
    • user_id in client events
    • See also

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

    Copyright © 2024 Pusher Ltd. All rights reserved.

    • Support,
    • Status
    • Follow Pusher on Twitter Twitter
    • Subscribe to Pusher’s channel on YouTube
    • Follow Pusher on LinkedIn
    • Follow Pusher on Github GitHub
    • Follow Pusher on Twitch Twitch
    • Follow Pusher on Discord Discord