私は、erlangのMessage passing構造を使ってマルチプレイヤーゲーム(正確には4人のプレイヤー)を作りました。私は例として次のリンクのtictactoeゲームに従ってきましたが、本当に似ているのは、ゲームに表示されている通りのメッセージパッシング構造です:関数呼び出し間の競合状態に対処する方法
私はこのゲームをejabberdで実行することを選択しました。これのためのejabberdフック。 上記のリンクのtictactoe.erlファイルのNewGameStateを見ると、変数に を取り出す方法がないことがわかります。
だから、私はmnesiaを使い、この記憶媒体テーブルに生成された新しいgamestateを書きました。 私のejabberdフックの中で、私は自分のゲーム関数を呼び出します(つまり、各呼び出しで、 "gen_server、game_modules、mnesia_modules"が実行されます) そしてゲーム機能の呼び出しの直ぐ下のフックの中で私はmnesiaテーブル次のようにgamestateのために(ここでは、関数myMessageはejabberdフックの内部関数です):
myMessage({#message = Msg, C2SState})->
some_other_module:game_func(Args),
State=mnesia_module:read(key),
{Msg, C2SState};
myMessage(Acc) ->
Acc.
今私の問題は、実行の順序は
some_other_module:game_func(Args),
GameState=mnesia_module:read(key),
ときに読み出し動作が私に空のテーブルを与えているということです
と、この2つの行の間に遅延を挿入すると、timer:sleep/1
がb
some_other_module:game_func(Args),
timer:sleep(200)
GameState=mnesia_module:read(key),
私はラインでの読み取り動作が
GameState=mnesia_module:read(key),
が行われつつあることを私に示唆のでGameStateの正しい値を取得しています:ELOW(値200は、異なる値を持ついくつかの試行後にランダムに選択されます) /一連のモジュール - > "gen_server、game_modules、mnesia_modules")の行の前に実行されると、mnesiaモジュールを実行し、GameStateをmnesiaテーブルに書き込むことができます。
timer:sleep/1
は信頼できる解決法ではないため、この問題を解決するにはどうすればよいですか。
誰でも私の周りの仕事を提案することはできますか?誰かが私に競技状態を持たないように、何か他の手段でゲームステートを取り戻す方法を提案できますか?
また、ejabberdがここで使用できる機能をいくつか提供していますか?
ありがとうございます。
mnesia:dirty_ * functionsを使用していますか? – Pouriya
いいえ@Pouriya私はmnesiaを使用しています:some_other_module:game_func(Args)が実行され、mnesia:GameState = mnesia_module:read(key)が呼び出されたときにデータを読み込むread/3関数。 –
コードを表示できますか? – Pouriya