2017-12-28 31 views
2

上のクライアントを設定するには、リロードを送る(携帯電話/タブレット/などを経由して...)レール5:私は、人の社会的なゲームのためのシンプルなターンベースのゲームトラッカーを作るためにRailsの5を使用しているデータ更新

私はプレーヤーがアクションを取った後に自動的にブラウザをリロードするために、ゲーム内のすべてのプレイヤー(セッション/ユーザ/のリスト)を持っていたいと思います。

私は、AJAXやウェブソケットなどのライブアップデート機能があることは知っていますが、単純な問題のように思われるほど重すぎます。さらに、アクションを開始したクライアントだけでなく、他のクライアントページを更新したいと思います。

リロードを送信する簡単なソリューションはありますか?あるいは、より複雑なAPIの1つで何かをコード化する必要がありますか?

+1

この場合、AJAXを使用する方法が最も簡単です。しかし、Rails 5の 'ActionCable'(WebSocketの方法)も実装するのが非常に簡単です。可能であれば、試してみてください。 – yeuem1vannam

+0

これを実証する簡単な例はありますか?私が見てきたすべてのAJAXチュートリアルではAJAXを使用しているため、クライアントのアクションはページ全体をロードせずにクライアントの独自のページを更新できます。 *他の*クライアントにリロードを送ろうとしています。これをもっと明確にするために質問を更新します。 –

答えて

1

簡単な問題のために、AJAXを使用して、XX秒ごとに間隔要求を行うことによって、ユーザークライアントをリロードすることができます。サーバーは、クライアントがリロードするかどうかを判断するために使用できる最後のアクション時間を戻すことができます。クライアント

function getLocalLastAction() { 
    /* return timestamp of the last action on local */ 
} 

function setLocalLastAction (time) { 
    /* Store the `time` to somewhere, ex: localStorage */ 
} 

function checkLastAction() { 
    $.getJSON("/get_last_action_time", function (data) { 
    if (getLocalLastAction() < data.last_action_time) { 
     /* destroy the interval */ 
     setLocalLastAction(data.last_action_time) 
     /* do the reload page */ 
    } else { 
     /* do nothing */ 
    } 
    }) 
} 

// Check every 1 second, shouldn't be too short due to performance 
var checking = setInterval(checkLastAction, 1000) 

たとえば、コントローラ上の

# SomeController 
def get_last_action_time 
    # Return the timestamp of the last action 
    render json: {last_action_time: "2017-12-29 10:00:42 UTC"} 
end 

ユーザAがアクションを行うときに、サーバlast_action_timeは、他のユーザのクライアントに再ロードされるため、変化しますほとんど1秒後。

これは古いものですが、単純なケースでは非常に簡単です。また、キャッシングアクションとともに実装すると、アプリのパフォーマンスは依然として受け入れられます。より複雑なケースでは、私は、@のyeuem1vannamの答えのおかげで、ここでの最終的なコードがある

  • フルコントロール
  • 低レイテンシのアプリ
+0

ここでは、通常のリロードに比べて唯一の利点は、アプリケーションがページ全体をリロードする必要がないということですか?私は、それはまた、ユーザーのページがそれらの下にリロードを維持しないことを意味すると思います... –

+0

@DavidLjungMadisonいいえ、それはページ全体をリロードすることではありません。ユーザーAがLAに滞在してアクションを実行すると、CAのユーザーBが1秒未満でページを自動的にリロードするという問題を解決しました。 AJAXは、誰かが何かをしたかどうかを確認し、必要に応じてページをリロードするのに役立ちます。 – yeuem1vannam

+0

右 - ページをリロードしないようにすることができますが、クライアントはサーバーからのデータを頻繁にポーリング/ロードする必要があります。この場合は、ページ全体ではなくアクションタイムです。これは改善点です。各クライアントへの接続を保持し、サーバーからリロードを直接呼び出す簡単な方法を理解することは良いことです。 –

0

ため

  • パフォーマンスを向上させるためのWebSocketのソリューションを使用することをお勧めこれは、時間が更新されている間に古い情報を読み込んでいるページの競合状態を回避し、JavaScriptを使用して時間を更新して新しい時間を取得し、リロードを失うのに役立ちます。

    javascriptのコード:

    var actionChecker; 
    
    function doneChecking() { 
        clearInterval(actionChecker); 
    } 
    
    function checkLastAction() { 
        // Get the game ID from the html access span 
        var dataId = document.getElementById('javascript_data_access'); 
        if (!dataId) return doneChecking(); 
        var initActionTime = dataId.getAttribute('init_last_action_time'); 
        if (!initActionTime) return doneChecking(); 
    
        dataId = dataId.getAttribute('game_number'); 
        if (!dataId) return doneChecking(); 
    
        // Get the last action time 
        var ret = $.getJSON("/get_last_action_time/"+dataId, function (data) { 
        var lastActionTime = data.last_action_time; 
        if (!lastActionTime) return doneChecking(); 
        if (lastActionTime>initActionTime) { 
         location.reload(); 
        } 
        }) 
    } 
    
    window.onload = function() { 
        // Check every 1 second, shouldn't be too short due to performance 
        actionChecker = setInterval(checkLastAction, 1000); 
    } 
    

    コントローラのアクション:

    <span id='javascript_data_access' game_number=<%= params[:id] %> init_last_action_time=<%= @game.reloadTime %>></span> 
    

    はもちろん、あなたのモデルにreloadTimeを追加する必要があります。

    def get_last_action_time 
        last_time = nil 
        begin 
         @game = Game.find_by_id(params[:id]) 
         # Return the timestamp of the last action 
         last_time = (@game && [email protected]) ? @game.reloadTime.to_i : 0 
        rescue ActiveRecord::RecordNotFound 
         last_time = 0 
        end 
        # Stop bugging us after 30m, we should have moved on from this page 
        last_time==0 if (last_time!=0 && (milliseconds - last_time)>30*60*1000) 
        render json: {last_action_time: last_time} 
        end 
    

    そしてhtml.erbでまた、もはや再ロードをもうチェックしたくない時間がある場合はendTimeを指定します。

    これまでのところうまく動作しているようですが、reloadTimeの設定担当者を慎重に確認する必要があります。 2つのページがreloadTimeをリロードするたびに設定すると、2つのページのリロードループでスタックされます。

  • 関連する問題