JDeveloper 11.1.1.4.0を使用して、メッセージング・モジュールを含むADF Fusion Webアプリケーションを開発しています。サーバー側のプッシュを行うためのテクニックを検索しました (これについても質問しました)。「comet」、サーバー側のプッシュなどについて検索しました。Active Data Serviceとチャットまたはサーバー側のプッシュの例をいくつか見つけました。
- http://biemond.blogspot.com/2009/12/adf-data-push-with-active-data-service.html
- https://blogs.oracle.com/adffun/entry/building_a_real_time_twitter_client_with_adf
biemond のブログの指示に従い、ADS の構成を行います
ADF META-INF/services フォルダーの下の adf-config.xml に ads conf を追加しました。
<ads:adf-activedata-config xmlns="http://xmlns.oracle.com/adf/activedata/config">
<transport>long-polling</transport>
<latency-threshold>10000</latency-threshold>
<keep-alive-interval>10000</keep-alive-interval>
<polling-interval>3000</polling-interval>
<max-reconnect-attempt-time>1800000</max-reconnect-attempt-time>
<reconnect-wait-time>10000</reconnect-wait-time></ads:adf-activedata-config>
adf-config.properties ファイルを作成しました
http\://xmlns.oracle.com/adf/activedata/config=oracle.adfinternal.view.faces.activedata.ActiveDataConfiguration$ActiveDataConfigCallback
jsfページにテーブルを作成しました。
<af:table value="#{MessageModel}" var="row"
rows="#{bindings.MessageVO.rangeSize}"
emptyText="#{bindings.MessageVO.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.MessageVO.rangeSize}"
rowBandingInterval="0" id="t1">
<af:column sortProperty="id" sortable="false"
headerText="#{bindings.MessageVO.hints.id.label}"
id="c1">
<af:outputText value="#{row.id}" id="ot2">
<af:convertNumber groupingUsed="false"
pattern="#{bindings.MessageVO.hints.id.format}"/>
</af:outputText>
</af:column>
<af:column sortProperty="Title" sortable="false"
headerText="#{bindings.MessageVO.hints.Title.label}"
id="c2">
<af:outputText value="#{row.title}" id="ot3"/>
</af:column>
</af:table>
そして、jsff でテーブル値として使用される MessageModel クラスを作成しました。
public class MessageModel extends ActiveCollectionModelDecorator {
private MessageActiveDataModel activeDataModel = new MessageActiveDataModel();
private CollectionModel model = null;
public CollectionModel getCollectionModel() {
if (model == null) {
DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
FacesCtrlHierBinding treeData = (FacesCtrlHierBinding)dcBindings.getControlBinding("MessageVO");
model = treeData.getCollectionModel();
}
return model;
}
public MessageActiveDataModel getActiveDataModel() {
return activeDataModel;
}
public MessageActiveDataModel getMessageActiveDataModel() {
return activeDataModel;
}
}
および ActiveDataModel クラス
public class MessageActiveDataModel extends BaseActiveDataModel {
private final AtomicInteger listenerCount = new AtomicInteger(0);
private final AtomicInteger currEventId = new AtomicInteger();
protected void startActiveData(Collection<Object> rowKeys,
int startChangeCount) {
listenerCount.incrementAndGet();
if (listenerCount.get() == 1) {
System.out.println("start up");
Runnable dataChanger = new Runnable() {
public void run() {
System.out.println("MyThread starting.");
try {
Thread.sleep(2000);
System.out.println("thread running");
Change chg = new Change();
chg.triggerDataChange(MessageActiveDataModel.this);
} catch (Exception exc) {
System.out.println("MyThread exceptioned out.");
}
System.out.println("MyThread terminating.");
}
};
Thread newThrd = new Thread(dataChanger);
newThrd.start();
}
}
protected void stopActiveData(Collection<Object> rowKeys) {
listenerCount.decrementAndGet();
if (listenerCount.get() == 0) {
System.out.println("tear down");
}
}
public int getCurrentChangeCount() {
return currEventId.get();
}
public void bumpChangeCount() {
currEventId.incrementAndGet();
}
public void dataChanged(ActiveDataUpdateEvent event) {
fireActiveDataUpdate(event);
}
}
ActiveDataModel クラスのスレッドは、Change という名前のクラスをトリガーします
public class Change {
public Change() {
}
public void triggerDataChange(MessageActiveDataModel model) throws Exception {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(4000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
model.bumpChangeCount();
ActiveDataUpdateEvent event =
ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.UPDATE,
model.getCurrentChangeCount(),
JboActiveDataEventUtil.convertKeyPath(new Object[] { new Long(1),
new Integer(0) }),
null,
new String[] { "title" },
new Object[] { "Administration" });
model.dataChanged(event);
}
}
}
アプリケーションを実行すると、テーブルに MessageVO からの行が表示されます。モデル クラス、アクティブ データ モデル クラス、および変更クラスに入り、ActiveDataMode クラスの listenerCount および currentEventId 値を変更します。データベースの行を更新すると、変更イベントがトリガーされず、データベースの更新が検出されません。
データベースの変更をリッスンし、ADF のデータベースの変更に応じてサーバー側のプッシュを行う方法について、誰かが考えを持っていますか?
前もって感謝します。