If you are a Force.com developer, are you familiar with streaming API?
Have you ever had a chance to implement it for applications?
In this post, I will discuss using streaming API, which enables push notifications in Salesforce, by referring to the background techniques and operation overview, as well as by sharing some simple sample code.
I will also cover restriction matters too, so I hope this helps your understanding for your own projects.
What is “Streaming API?”
To put it simply, streaming API is a mechanism that monitors data changes in Salesforce based on the SOQL query you define, and if the condition matches, sends push notifications to all the subscribed clients.
Since Summer ’12, streaming API is available in any API-valid organizations. You can test it to see how it works in the Developer Edition.
Also, push notifications can be received from a page in a Salesforce application, a server and a page outside of Salesforce, and Java client.
For this example, we will use a Visualforce page to receive push notifications.
What is a “Push Notification?”
Push notification is the technology that allows you to send information without the clients’ request when an event occurs in the server.
In “pull technology” where information is sent in response to the clients’ request, the page will not be updated unless the user intentionally refreshes or changes the page. Therefore, in order for the client to know an event has occurred in the server, you need to send a page request periodically and receive the result (called polling).
On the server-side, a series of processes to generate an HTTP connection, send information and close the connection by each and every polling is necessary. iI polling is performed by many clients, then it would consume a huge amount of server resources and network bandwidth.
If you use Ajax that sends a request asynchronously by restricting one part of the page, you can reduce some network bandwidth consumption. However, this is not effective as you still need to respond to the requests that are sent regularly regardless of the server event.
I would not recommend you to use polling frequently, especially if you are using Salesforce, because polling from outside of Salesforce, such as SOAP/REST API consumes API request counts.
This is when streaming API becomes useful.
What kind of technology is used for streaming API?
Streaming API is implemented in the CometD framework which holds the Bayeux protocol created for providing an asynchronous message by HTTP. This is a method for a server to artificially push information to a client by long polling.
More specifically, the major operations of long polling are as follows:
1. The client issues a request to the server like polling
2. The server does not respond immediately but holds the request for a while
3. When the server recognizes an event is happening, it return replies for several pending requests.
4. Once the browser receives a response, it immediately re-issues the next request and gets back to the pending status.
⇒ In the end, the process is almost the same as if the push technology was performed by the server.
Setting Up Streaming API/Operation Overview
Let’s take a look at the settings of streaming API and its operations.
[Setting on the Server]
Define PushTopic:
Create a record for the “PushTopic object”, which is a standard object. Set monitoring conditions (PushTopic Query) in SOQL for a PushTopic record and define a name (PushTopic channel).
[Receiving Process from the Client]
Connect to the PushTopic channel (Subscribe):
Connect to the PushTopic channel by utilizing JavaScript or Java library which can be downloaded from https://cometd.org/. You can subscribe to several PushTopic channels from one client at the same time.
[Sending Notification from the Server]
Send a notification to all subscribing clients simultaneously if it matches the condition evaluation of the PushTopic query.
Condition evaluation will take place every time the record of the object PushTopic query is referring to is created or updated.
Streaming API restricts the number of event notification to up to 20,000 in 24 hours for Unlimited Edition as well as Enterprise Edition. Thus the restriction is managed differently from the conventional request API (available from the org information).
Sample Settings and Source Code
Let’s follow the sample scenario and check the operation.
Scenario: Imagine there is a company using a certain ERP system. Sales reps are in charge of inputting order data. When an ordered product is out of stock, they need to inform the order management team in real-time to avoid any chance of loss.
There is a possibility that someone might overlook the information if the message is sent by email, so the customer asked you to directly display a notification on the “check inventory” page.
1. Create a PushTopic Record
First, you need to create a PushTopic record. Any method can be applied.

The required field for creating a record is Name(PushTopic channel), Query(PushTopic query) and ApiVersion.
In this sample, the case where the evaluation is done when a record is created or updated (NotifyForOperations: All), or where there is an update in the field which is created or referred in a SELECT phrase or a WHERE phrase (NotifyForFields: Referenced), also the case where it matches to the WHERE phrase condition are subject.
※Note
Always contain Id in a SELECT phrase
There is only one entity that can be referred for one query. A relation query is not available.
Aggregation query, COUNT, LIMIT, ORDER BY, GROUP BY, NOT(NOT IN is acceptable), OFFSET and TYPEOF cannot be used. Also, a formula can be specified in a SELECT phrase but not in a WHERE phrase.
You cannot change the query when connecting CometD session exists. When you close subscribing pages after 110 seconds socket timeout is thrown and it becomes editable.
2. Enter a JavaScript file for CometD in the Static Resource
Download JavaScript Library in CometD, extract the below JavaScript files, and enter in the static resource with the appropriate name.
cometd-2.2.0/cometd-javascript/common/target/org/cometd.js
cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/jquery-1.5.1.js
cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/json2.js
cometd-2.2.0/cometd-javascript/jquery/src/main/webapp/jquery/jquery.cometd.js
3. Create a Visualforce Page
Use the code below to create a Visualforce page manually or use SkyVisualEditor to create your page.
<span style="color: #000080;"><apex:page ></span>
<span style="color: #000080;"> <apex:includeScript value="{!$Resource.cometd}"/></span>
<span style="color: #000080;"> <apex:includeScript value="{!$Resource.jquery}"/></span>
<span style="color: #000080;"> <apex:includeScript value="{!$Resource.json2}"/></span>
<span style="color: #000080;"> <apex:includeScript value="{!$Resource.jquery_cometd}"/></span>
<span style="color: #000080;"> <apex:stylesheet value="//ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/themes/hot-sneaks/jquery-ui.css" /></span>
<span style="color: #000080;"> <apex:includeScript value="//ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/jquery-ui.min.js" /></span>
<span style="color: #000080;"> <script type="text/javascript"></span>
<span style="color: #000080;"> (function($){</span>
<span style="color: #000080;"> $(document).ready(function() {</span>
<span style="color: #000080;"> // CometD Connect to the end point</span>
<span style="color: #000080;"> $.cometd.init({</span>
<span style="color: #000080;"> url: window.location.protocol + '//' + window.location.hostname + '/cometd/24.0/',</span>
<span style="color: #000080;"> requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'}</span>
<span style="color: #000080;"> });</span>
<span style="color: #000080;">// Subscribe InventoryReserve Topic</span>
<span style="color: #000080;"> // Update the screen by calling back delivery notification</span>
<span style="color: #000080;"> $.cometd.subscribe('/topic/InventoryReserve', function(message) {</span>
<span style="color: #000080;"> var noticePanel = $("#notice").accordion();</span>
<span style="color: #000080;"> noticePanel.append('<h3>Backlog!' + JSON.stringify(message.data.event.createdDate) </span>
<span style="color: #000080;"> + '</h3>' +</span>
<span style="color: #000080;"> '<div><p>Date Occured : ' + JSON.stringify(message.data.event.createdDate) +</span>
<span style="color: #000080;"> '<br/>Status : ' + JSON.stringify(message.data.sobject.gii__ReserveStatus__c) + </span>
<span style="color: #000080;"> '<br/>Event : ' + JSON.stringify(message.data.event.type) +</span>
<span style="color: #000080;"> '<br/>Inventory Reservation : ID - ' + JSON.stringify(message.data.sobject.Id) + </span>
<span style="color: #000080;"> ' Name - ' + JSON.stringify(message.data.sobject.Name) + '</p></div>'</span>
<span style="color: #000080;"> );</span>
<span style="color: #000080;"> noticePanel.accordion('destroy');</span>
<span style="color: #000080;"> noticePanel.accordion();</span>
<span style="color: #000080;"> });</span>
<span style="color: #000080;"> });</span>
<span style="color: #000080;"> })(jQuery)</span>
<span style="color: #000080;"> </script></span>
<span style="color: #000080;"><div id="notice"/></span>
<span style="color: #000080;"> <apex:ListViews type="gii__ProductInventory__c"/></span>
<span style="color: #000080;"></apex:page></span>
This Visualforce page above is to display the result to a simple page to show a list view of the product inventory object (gii__ProductInventory__c).
Row 2 to 5: JavaScript library of CometD is included.
※This time, JavaScript library includes independently in order to make it simple.
However, usually, it is recommended to put them together in a zip file and register in the static resource.
Row 12 to 15: Connect to the endpoint Row 19: Subscribe to the PushTopic channel and create a callback Row 20 to 30: the processing when a notification is received
4. Operation Check
When the status was a backlog, a notification will appear on the screen! If you implement not only a Visualforce page but to a Visualforce Component and use on the same Visualforce page in the application, you can apply this mechanism to the whole application.
Precautions
Not completely a real-time notification (3 seconds interval to check the server event)
Persistence of notification and reliability is not guaranteed. There might be a case where a message cannot be received due to the heavy load and timing of processing by the client.
PushTopic standard objects, as well as the access permission to the objects and fields the PushTopic query is referring to, are required.
No notification to the event created by Bulk API (because the notification amount may exceed the capacity)
Supported Internet Explorer 8 or above, or Firefox 4 or above ※The operation check for this sample is done with Chrome 26.0.1410.64.
Summary
It is true that streaming API has some strict restrictions and you need to carefully consider the purpose of the use. But even so, I assume you understand the simple usage of streaming API. If you are using polling or would like to change data all at once, please take streaming API into your consideration.
Comments