Platform Event の購読と公開を Visualforce で実装(Apexも)


Visualforce ページから Platform Event を購読

  • Visualforce ページで Platform Event を購読するために、Streaming API を利用します。
  • 対して Visualforce ページで Platform Event を公開するために、Rest API を利用します。
  • Streaming API 実装方法の情報少なすぎ\(^o^)/

CometD のライブラリを含む静的リソースを準備

js ファイル 取得元
cometd.js CometD の Download ページ からダウンロードした cometd-3.1.X-distribution.tar.gz を展開後、cometd-javascript/jquery/target にある .war ファイルを展開
jquery-3.2.1.min.js jQuery CDN – Latest Stable Versions
jquery.cometd.js CometD の Download ページ からダウンロードした cometd-3.1.X-distribution.tar.gz を展開後、cometd-javascript/jquery/target にある .war ファイルを展開
  • こんな感じ

Visualforce での実装例

  • 事前に作成しておいた、ExampleEvent__c という Platform Event を購読するサンプルプログラムです。
PlatformEventSubscribeExample.vfp
<apex:includeScript value="{!URLFOR($Resource.PlatformEventExample, 'asset/js/cometd.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.PlatformEventExample, 'asset/js/jquery-3.2.1.min.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.PlatformEventExample, 'asset/js/jquery.cometd.js')}"/>

<script>
    /*** Streaming API によるイベントの購読 ***/ 
    $(document).ready(function() {

        // Websocket はサポートされていないらしい
        $.cometd.websocketEnabled = false;

        $.cometd.configure({
            url: window.location.protocol + '//' + window.location.hostname + '/cometd/41.0/',
            requestHeaders: { Authorization: 'OAuth {!$Api.Session_ID}'}
        });

        // 握手が成功してから購読開始
        $.cometd.handshake(function(handshakeReply) { 
            if(handshakeReply.successful) { 
                $.cometd.subscribe('/event/ExampleEvent__e', function(message) {
                    console.log(message.data.payload);
                });
            } else {
                console.error(handshakeReply);
            }
        });
    });
    // Window が閉じられる前に、購読を停止する
    window.onbeforeunload = function () {
        $.cometd.disconnect();
    };
</script>

Visualforce ページから Platform Event を公開

  • 通常の Rest API による Plateform Event の公開例です。

Visualforce での実装例

PlatformEventPublishExample.vfp

<script>
    /*** Rest API によるイベントの公開 ***/ 
    function publishExampleEvent() {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', window.location.protocol + '//'+ window.location.hostname +'/services/data/v41.0/sobjects/ExampleEvent__c');
        xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
        xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');
        xhr.onreadystatechange = function () {
            if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 201) {
                response = JSON.parse(xhr.responseText);
                if (response.success) {
                    alert('SUCCESS');
                } else {
                    alert('ERROR');
                    console.error(response.warnings);
                    console.error(response.errors);
                }

            } 
        };
        xhr.send(JSON.stringify({CustomField1__c: 'Value1', CustomField2__c: 'Value2'}));
    }
</script>

Apex から Platform Event を公開

  • Apex から Platform Event を公開したい場合は以下の実装が可能です。
PlatformEventPublishExample.apxc
ExampleEvent__c event = new ExampleEvent__c(CustomField1__c='Value1', CustomField2__c='Value2');
Database.SaveResult sr = EventBus.publish(event);
if (sr.isSuccess()) {
    System.debug('Successfully published event.');
} else {
    for(Database.Error err : sr.getErrors()) {
        System.debug('Error returned: ' +
                     err.getStatusCode() +
                     ' - ' +
                     err.getMessage());
    }
}