41
EWD 3 トトトトトト トトト #7 ewd-xpress トトトトトト トトトトトトトトト M/Gateway Developments Ltd. Rob Tweed ト : トトトトトトトトトトトトト ト トト

EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

Embed Size (px)

Citation preview

Page 1: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

EWD 3トレーニング・コース  #7

ewd-xpress のメッセージ・パターンを

適用するM/Gateway Developments Ltd.

Rob Tweed訳 : 日本ダイナシステム株式会社 嶋 芳成

Page 2: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

2

ewd-xpress アプリケーションのパターン

• ブラウザ内でイベントを発生する• ewd-xpress のバックエンドにメッセージを

送る• バックエンドで、そのタイプのメッセージに

対するハンドラ関数が、そのメッセージを処理し、通常は応答メッセージを生成する• 応答メッセージをブラウザに返し、それを受

けたブラウザではハンドラ関数がそれを処理し、通常はユーザー・インターフェースを変更する

2016/9/5 EWD 3 トレーニング・コース #6

Page 3: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

3

これらをひとつづつ適用してください

2016/9/5 EWD 3 トレーニング・コース #6

Page 4: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

4

ewd-xpress アプリケーションのパターン

• ブラウザでイベントを生成します• ボタンをクリックする• 書式の入力フィールドの値を変更する• マウス・ポインタを特定の領域内に入れる• その他 ...

• 求められたイベントが起こったとき、ハンドラ関数が起動できなくてはなりません

2016/9/5 EWD 3 トレーニング・コース #6

Page 5: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

5

イベントを生成する

• index.html にボタンを加える• App.js に、そのボタンに対するクリック・イ

ベントのハンドラを加える

2016/9/5 EWD 3 トレーニング・コース #6

Page 6: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

6

index.html にボタンを追加する<html> <head> <title>Demo ewd-xpress application</title> </head> <body> <script src=“//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js”></script> <script src=“/socket.io/socket.io.js”></script> <script src=“/ewd-client.js”></script> <script src=“app.js”></script>

<button id=“testBtn”>Click Me</button>

<div id=“content”> Content goes here </div> </body></html>

2016/9/5 EWD 3 トレーニング・コース #5

Page 7: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

7

app.js にハンドラを追加する

jQuery のイベント・ハンドラ

最初に、クリック・イベントが処理されることを確認するだけです

document.ready() 関数内で、 EWD を開始する前に、ハンドラを定義することに注意してください

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.on(‘ewd-registered’, function() {

$(‘#testBtn’).on(‘click’, function(e) { console.log(‘button was clicked!’); });

});

EWD.start(‘demo1’, $, io);});

Page 8: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

8

実行してみましょう

2016/9/5 EWD 3 トレーニング・コース #6

Page 9: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

9

ewd-xpress アプリケーションのパターン

• メッセージを、 ewd-xpress のバックエンドに送ります• EWD.send() 関数を用います• メッセージには必ず type プロパティがなくては

なりません• type プロパティの値は、自由に決められます

• 任意の文字列値• EWD.send() 関数は、登録完了まで利用できませ

ん• EWD.send() 関数は、セッション・トークンを

メッセージに自動的に追加します• この振る舞いは closure 内に保護され、変更できませ

ん• 手動での socket.io メッセージ通信はユーザには利用

できません2016/9/5 EWD 3 トレーニング・コース #6

Page 10: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

10

app.js を編集する

type プロパティひとつのみの現時点で最も簡単なメッセージ

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.on(‘ewd-registered’, function() {

$(‘#testBtn’).on(‘click’, function(e) { var message = {type: ‘testButton’}; EWD.send(message); });

});

EWD.start(‘demo1’, $, io);});

Page 11: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

11

実行してみましょう

• ボタンをクリックしても、ブラウザには何も現れません

• しかし、 ewd-xpress が稼働しているコマンド・プロンプト・ウィンドウをチェックしてください

2016/9/5 EWD 3 トレーニング・コース #6

Page 12: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

12

バックエンド・ログ

• メッセージはマスター・プロセスで受信され、ワーカーに渡されますworker 2052 received message: {“type”:”testButton”, “token”:”4fb0efcd-458c-4afd-a053-8a19600867c4”}

• セッション・トークンが、 EWD.send() 関数によってメッセージに追加されていることに注意してください。

2016/9/5 EWD 3 トレーニング・コース #6

Page 13: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

13

バックエンド・ログ

• ワーカー・プロセスは、エラーを報告します

Unable to load handler module for: demo1: Error: Cannot find module ‘demo1’

• ewd-xpress は、このアプリケーション(“demo1”) に対するメッセージ・ハンドラを含むモジュールを見つけられず、読み込めませんでした

2016/9/5 EWD 3 トレーニング・コース #6

Page 14: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

14

バックエンド・ログ

• このエラー・メッセージは、ワーカーからマスター・プロセスに返されます

master process received response from worker 2052: {”type”:”testButton”, ”finished”:true, ”message”:{”error”:”Unable to load handler module for: demo1”,”reason”:{”code”:”MODULE_NOT_FOUND”}}}

• マスター・プロセスは、このメッセージをブラウザに転送します• しかし、ブラウザ内には何も表示されません !

2016/9/5 EWD 3 トレーニング・コース #6

Page 15: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

15

ブラウザ内にメッセージを表示する

• 通常、メッセージを処理し、それを UI 内に表示するのは、開発したアプリケーションによります• 開発中は、送受信した全メッセージ

を、 JavaScript コンソールでトレースして見ることはとても有用です• これをするには、 EWD.log=true; とします

2016/9/5 EWD 3 トレーニング・コース #6

Page 16: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

16

app.js を編集する

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() { $(‘#testBtn’).on(‘click’, function(e) { console.log(‘button was clicked!’); }); }); EWD.start(‘demo1’, $, io);});

Page 17: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

17

メッセージが表示されます

2016/9/5 EWD 3 トレーニング・コース #6

Page 18: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

18

このエラーを修正する

• EWD.send() はうまく作動しています• 期待通りにメッセージをバックエンドに送ってい

ます

• バックエンドでエラーを修正するにはどうしますか、そこで受信したメッセージを処理するにはどうしますか?

2016/9/5 EWD 3 トレーニング・コース #6

Page 19: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

19

ewd-xpress アプリケーションのパターン

• バックエンドでは、メッセージの type に対するハンドラ関数がそのメッセージを処理し、通常は応答メッセージを生成します• 各アプリケーションについて、開発者はバックエ

ンド・モジュールを定義します• モジュール名はアプリケーション名と同一

• 例えば、 demo.js• 開発アプリケーションは、各メッセージ type に対して、

ひとつづつハンドラ関数を定義します• データベースの読み書き• セッションの読み書き• 旧来のアプリケーション関数の呼び出し• すなわち、あらゆる形で Caché にアクセスができます

2016/9/5 EWD 3 トレーニング・コース #6

Page 20: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

20

バックエンド・モジュールのパターン

• C:\ewd3\node_modules\{applicationName}.js

module.exports = { handlers: { {messageType1}:function(messageObj, session, send, finished){ // 受信メッセージに対して何かをします

// 応答オブジェクトを生成します

// finished() 関数をもちいて処理を終了し、ワーカーを解放します

finished(responseObj); }, {messageType2}:function(messageObj,session,send,finished){ // 同じく ... finished(responseObj); } }}

2016/9/5 EWD 3 トレーニング・コース #6

Page 21: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

21

例題のバックエンド・モジュールを作る

• C:\ewd3\node_modules\demo1.js

module.exports = { handlers: { testButton: function(messageObj, session, send, finished){ console.log(‘*** handling the button click message!’); finished({ ok: ‘testButton message was processed successfully!’ }); } }};

2016/9/5 EWD 3 トレーニング・コース #6

Page 22: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

22

例題のバックエンド・モジュールを作る

• C:\ewd3\node_modules\demo1.js

module.exports = { handlers: { testButton: function(messageObj, session, send, finished){ console.log(‘*** handling the button click message!’); finished({ ok: ‘testButton message was processed successfully!’ }); } }};

2016/9/5 EWD 3 トレーニング・コース #6

これが、 EWD.send() 関数内の type プロパティの値でした

EWD.send({type: ‘testButton’});

Page 23: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

23

実行してみましょう

2016/9/5 EWD 3 トレーニング・コース #6

Page 24: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

24

バックエンド・ログを見てみましょう

Worker 2000 received message:

{”type”:”testButton”,”token”:”527bd51f-7d6a-4dd7-827d-c1ea8dfa1f43”}

*** handling the button click message!

Master precess received response from worker 2000:

{”type”:”testButton”:,”finished”:true,”message”:{”ok”:”testButton message was processed successfully!”,”ewd_application”:”demo1”}}

*** handleMessage response

{”type”:”testButton”,”finished”:true,”message”:{”ok”:

”testButton message was processed successfully!”,

”ewd_application”:”demo1”}}

sending to socket /#5NdGRfdMn17-vboPAAAC

Master process has finished processing response from worker process

2000 which is back in available pool

2016/9/5 EWD 3 トレーニング・コース #6

この例題のハンドラー関数では、Console.log(‘*** handling the button click message!’);

Page 25: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

25

エラーが出ますか ?• バックエンド・ログを確認してください• “Unable to load module” というメッセージで

すか?• これは、そのモジュールに構文上のエラーがあ

るという意味です• どこがエラーかを調べるには?

• Node.js の REPL を用いてください

2016/9/5 EWD 3 トレーニング・コース #6

Page 26: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

26

Node.js の REPL を用いるC:\users\Rob Tweed> cd \ewd3

C:\ewd3> node>   var x = require(’demo1’) C:\ewd3\node_modules\demo1.js:6 ok:’testButton message was processd successfully!’’ ^SyntaxError: Unexpected token ILLEGAL at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Module.require (module.js:353:17) at require (internal/module.js:12:17) at repl:1:9 at REPLServer.defaultEval (repl.js:262:27) at bound (domain.js:287:14)>

2016/9/5 EWD 3 トレーニング・コース #6

REPL から出るには Ctrl + C を 2 回押下します

Page 27: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

27

バックエンドのメッセージ・ハンドラ資源

• バックエンドのメッセージ・ハンドラ関数内では、必要なすべてのものにアクセスできます• testButton: function(messageObj,session,send,finished){...}

• 受信メッセージ : messageObj• EWD セッション : session.data (Read/Write ア

クセス )• Caché データベース (Read/Write/Xecute アクセ

ス )• this.db で cache.node の API にアクセスできます

• 例えば、 this.db.function() で関数やルーチンを実行• this.documentStore で、 EWD 3 による Caché の

抽象化である JavaScript / Document データベースにアクセスできます

2016/9/5 EWD 3 トレーニング・コース #6

Page 28: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

28

セッションを用いる• C:\ewd3\node_modules\demo1.js

module.exports = { handlers: { testButton: function(messageObj, session, send, finished){ console.log(‘*** handling the button click message!’); session.data.$(‘foo’).value = ‘bar’ finished({ ok: ‘testButton message was processed successfully!’ }); } }};

2016/9/5 EWD 3 トレーニング・コース #6

Page 29: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

29

ewd-xpress アプリケーションのパターン

• バックエンドでは、そのメッセージ・タイプに対するハンドラ関数がメッセージを処理し、通常は応答メッセージを生成します• 応答メッセージは JSON オブジェクト• WebSocket を用いるなら、複数のメッセージを送信可能

• send() 関数は中間メッセージで、ワーカーはそのまま• finished() 関数は最終メッセージで、ワーカーは利用可能プールへ戻る

• 応答メッセージには、 type プロパティがあります• デフォルトでは、その type は元々ブラウザから来たメッセージと同一• オプションで、中間メッセージを send() 関数で送ったときは、この type

をオーバーライドできます• finished() メッセージの type はオーバーライドできず、元々受信したメッ

セージと常に同一です

• 応答メッセージは、自動的に、もともとのクライアントまたはブラウザに送り返されます

2016/9/5 EWD 3 トレーニング・コース #6

Page 30: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

30

ewd-xpress アプリケーションのパターン

• 応答メッセージは、ブラウザに返されるとそこでハンドラ関数で処理され、通常はユーザー・インターフェースを変更します• 応答メッセージをブラウザ内で処理するには2つの方

法があります• EWD.send() 関数の2つ目の引数で指定するコールバック

関数• EWD.send(messageObj, function(responseObj){…});

• メッセージの type 毎に指定して Pub/Sub 機構を用いる• EWD.on(messageType,function(responseObj){…});

• UI の変更には JavaScript を用います• 必要なら、どのフレームワークを用いるかは開発者により

ます

2016/9/5 EWD 3 トレーニング・コース #6

Page 31: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

31

app.js を編集する

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() { $(‘#testBtn’).on(‘click’, function(e) {     var message = {type: ‘testButton’}; EWD.send(message, function(messageObj) { console.log(‘Response received: ‘ + JSON.stringify(messageObj.message.ok)); }); }); }); EWD.start(‘demo1’, $, io);});

応答メッセージを処理するために、 EWD.send() のコールバック関数を用いています

Page 32: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

32

実行してみましょう

2016/9/5 EWD 3 トレーニング・コース #6

Page 33: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

33

ewd-xpress アプリケーションのパターン

• 応答メッセージは、ブラウザに返されるとそこでハンドラ関数で処理され、通常はユーザー・インターフェースを変更します• 応答メッセージをブラウザ内で処理するには2つの方法

があります• EWD.send() 関数の2つ目の引数で指定するコールバック関数

• EWD.send(messageObj, function(responseObj){…});• メッセージの type 毎に指定して Pub/Sub 機構を用いる

• EWD.on(messageType,function(responseObj){…});• UI の変更には JavaScript を用います

• 必要なら、どのフレームワークを用いるかは開発者によります• jQuery はロード済みなので、これを使いましょう

2016/9/5 EWD 3 トレーニング・コース #6

Page 34: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

34

app.js を編集する

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() { $(‘#testBtn’).on(‘click’, function(e) {     var message = {type: ‘testButton’}; EWD.send(message, function(messageObj) { $(‘#content’).text(messageObj.messag.ok); }); }); }); EWD.start(‘demo1’, $, io);});

<div id=“content”> タグの内側のテキストを変更します

Page 35: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

35

実行してみましょう

2016/9/5 EWD 3 トレーニング・コース #6

Page 36: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

36

ewd-xpress アプリケーションのパターン

• 応答メッセージは、ブラウザに返されるとそこでハンドラ関数で処理され、通常はユーザー・インターフェースを変更します• 応答メッセージをブラウザ内で処理するには2つの方法

があります• EWD.send() 関数の2つ目の引数で指定するコールバック関数

• EWD.send(messageObj, function(responseObj){…});• メッセージの type 毎に指定して Pub/Sub 機構を用いる

• EWD.on(messageType,function(responseObj){…});• バックエンドからメッセージを頻繁に送る場合に用います• 特に、 send() 関数を用いて中間メッセージを送る場合

• UI の変更には JavaScript を用います• 必要なら、どのフレームワークを用いるかは開発者によります

2016/9/5 EWD 3 トレーニング・コース #6

Page 37: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

37

中間メッセージ

• C:\ewd3\node_modules\demo1.js

module.exports = { handlers: { testButton: function(messageObj, session, send, finished){ session.data.$(‘foo’).value = ‘bar’ send({ type: ‘intermediate’, foo: ‘bar’, date: new Date().toString() }); finished({ ok: ‘testButton message was processed successfully!’ }); } }};

2016/9/5 EWD 3 トレーニング・コース #6

受信メッセージの type をオーバーライドしている

Page 38: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

38

実行してみましょう

2016/9/5 EWD 3 トレーニング・コース #6

Page 39: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

39

app.js を編集する

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() { EWD.on(‘intermediate’, function(responseObj) { $(‘#content’).text(responseObj.message.date); });

$(‘#testBtn’).on(‘click’, function(e) {     var message = {type: ‘testButton’}; EWD.send(message, function(messageObj) { $(‘#content’).append(‘<br />’ + messageObj.messag.ok); }); }); }); EWD.start(‘demo1’, $, io);});

Pub/Sub ハンドラーを用いて、中間メッセージのインスタンスを処理しています

Page 40: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

40

app.js を編集する

2016/9/5 EWD 3 トレーニング・コース #5

$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() { EWD.on(‘intermediate’, function(responseObj) { $(‘#content’).text(responseObj.message.date); });

$(‘#testBtn’).on(‘click’, function(e) {     var message = {type: ‘testButton’}; EWD.send(message, function(messageObj) { $(‘#content’).append(‘<br />’ + messageObj.messag.ok); }); }); }); EWD.start(‘demo1’, $, io);});

<div id=“content”> タグの内側のテキストに応答メッセージを接続しています

Page 41: EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する

41

実行してみましょう

2016/9/5 EWD 3 トレーニング・コース #6