Node.jsで、着信TCP接続を受け入れ、非標準プロトコルを使用してクライアントとの重要なダイアログを実行するサーバーを作成しますか? 私のプロジェクトで私が開発している例に興味があるかもしれません。 自明ではない対話とはどういう意味ですか?
比較してみましょう。
サーバーをノックし、接続を確立した後、識別子の数バイトをソケットに書き込み、次に現在の温度の数バイトを書き込むリモート温度センサー-これはプリミティブです。
サーバーからコマンドを受信して、測定頻度または測定値の平均化期間を変更できる同じセンサーは、すでにより複雑です。 これに加えて、たとえば、ファームウェアの更新をセンサーに送信する機能とコードは、その簡潔さを簡単に失う可能性があります。
そのような場合、オートマトンの理論の規範に準拠するふりをせずに、「ステートマシン」のスタイルでコードを整理します。
この記事の例は、
github.com /
kityan /
fsmConnectionから入手できます。 次に、いくつかの重要なポイントについて説明します。
メインアプリケーションのコード。サーバー側のみを考慮してください。 コードは非常に簡単です。
var net = require('net'); var ClientConnection = require('./ClientConnection.js'); var config = {"socketTimeout":3000, "port": 30000} net.createServer(function(socket) {var clientConnection = new ClientConnection(socket, config);}) .listen(config.port, function () {console.log('Listening on: ' + config.port);});
接続を確立するたびに、サーバーはClientConnectionのインスタンスを作成し、ソケットと構成オブジェクトを渡します。
ClientConnectionモジュールのコードスニペット。インスタンスフィールドを初期化します。
var ClientConnection = function (socket, config){...}
プロトタイプでは、マシンを切り替える
ClientConnection.toメソッドを定義します。
ClientConnection.prototype.to = function (newState) {
切り替えるときに、
onExitHandlerメソッドに以前の状態があるかどうかを確認し、ある場合はそれを呼び出します。
次に、マシンの
handleInputメソッド
に、新しい状態の
inputHandlerへのポインターを割り当てます。 最後に、新しい状態に
onEnterHandlerメソッドがあるかどうかを確認します。 ある場合、それを呼び出します。
ClientConnection.to(newState)を呼び出した後はどうなりますか?
onExitHandlerと
onEnterHandlerの呼び出しが別の状態に
切り替わらない場合、マシンはこの状態のままになります。 そして、すべてがソケットデータに依存します。 到着するすべてのパケットは
handleInputにルーティングされ
ます 。 なんで?
実際には、インスタンスを作成すると、すぐに初期化状態に切り替わり、ソケットイベントのハンドラーがハングアップします。
ClientConnection.prototype.states = { 'inital': { 'onEnterHandler': function(){
そして、次の状態に切り替えます。 私たちの場合、これは
'waitingForHelloFromClient'です。
すべての状態は、
ClientConnection.prototype.statesオブジェクトで説明されて
います。 有効な状態には
inputHandlerがありません。 そのような状態に切り替えるとき、
onEnterHandler内で何らかのアルゴリズムを
実行し 、すぐに別の状態に切り替えます。
inputHandlerで停止して、イベントループの次の反復でコードが呼び出され、ソケットデータが表示された場合に処理できるようにします。
onExitHandlerに切り替えないことを強くお勧めします。
実際にはすべて。 コードが便利だと思われる場合-健康に使用してください。 批判は大歓迎です。
一般的なケースではより便利であることが判明する解決策(たとえば、
Machina.JS )があることに注意してください。