17

私のニーズに合わせてクロスタブミューテックスを実装しようとしています。ここで実装を見つけました。これは非常に有望に思えます。基本的に、ミューテックスを作成するためのアトミックな読み取り/書き込みが必要なレスリー・ランポートのアルゴリズムを実装しています。

ただし、アトミックな読み取り/書き込みを提供する localStorage に依存しています。これは、Chrome を除くほとんどのブラウザでうまく機能します。

私の質問は、代わりにクッキーの読み取り/書き込みを使用できますか? Cookie の読み取り/書き込みは、すべての主流のブラウザー (IE、Chrome、Safari、Firefox) でアトミックですか?

4

3 に答える 3

7

localStorageCookie も、アトミック トランザクションも提供しません。

そのブログ投稿を誤解されているかもしれませんが、彼の実装が Chrome で機能しないとは言っていませlocalStorage通常の localStorageアクセスは、Chrome ではより不安定になると彼は言います。これは、Chrome が各タブに個別のプロセスを使用するのに対し、他のほとんどのブラウザーはすべてのタブに単一のプロセスを使用する傾向があるという事実に関連していると思います。彼のコードは、localStorage上書きされないように保護するロック システムを実装しています。

別の解決策は、IndexedDBを使用することです。IndexedDBアトミック トランザクションを提供します。新しい標準であるため、 ほど多くのブラウザーではサポートされてlocalStorageいませんが、最近のバージョンの Firefox、Chrome、および IE10 では適切にサポートされています。

于 2013-02-13T09:14:23.847 に答える
0

いいえ。ブラウザーが Cookie の読み取りと書き込みのロックを実装している可能性があるとしても、読み取りとその後の書き込みの間に発生する変更からユーザーを保護することはできません。これは、 JavaScript API for cookiesを見ると簡単にわかります。そこにはミューテックス機能はありません...

于 2013-02-13T07:19:46.347 に答える
0

今日、localStorage を使用して、この同時実行の問題に遭遇しました (2 年後に..)

シナリオ: ブラウザー (Chrome など) の複数のタブには、基本的に同時に実行される同一のスクリプト コードがあります (SignalR などによって呼び出されます)。このコードは、localStorage の読み取りと書き込みを行います。タブは異なるプロセスで実行されますが、共有ローカル ストレージにまとめてアクセスするため、ここにはロック メカニズムがないため、読み取りと書き込みは未定義の結果につながります。私の場合、すべてのタブではなく、1 つのタブのみが実際にローカル ストレージで動作することを確認したかったのです。

上記の質問で述べた Benjamin Dumke-von der Ehe のロック機構を試しましたが、望ましくない結果が得られました。だから私は自分の実験的なコードをロールバックすることにしました:

localStorage ロック:

Object.getPrototypeOf(localStorage).lockRndId = new Date().getTime() + '.' + Math.random();
Object.getPrototypeOf(localStorage).lock = function (lockName, maxHold, callback) {
    var that = this;
    var value = this.getItem(lockName);
    var start = new Date().getTime();    
    var wait = setInterval(function() {
        if ((value == null) || (parseInt(value.split('_')[1]) + maxHold < start)) {
            that.setItem(lockName, that.lockRndId + '_' + start);
            setTimeout(function () {
                if (that.getItem(lockName) == (that.lockRndId + '_' + start)) {
                    clearInterval(wait);
                    try { callback(); }
                    catch (e) { throw 'exeption in user callback'; }
                    finally { localStorage.removeItem(lockName); }
                }
            }, 100);
        }        
    }, 200);        
};

利用方法:

localStorage.lock(ロック, maxHold ,コールバック);

  • lockName - ロックのグローバル スコープの一意の名前 - 文字列
  • maxHold - スクリプトを保護する最大時間 (ミリ秒) - 整数
  • callback - 保護されるスクリプトを含む関数

例:「1 つのタブでのみサウンドを再生する」

//var msgSound = new Audio('/sounds/message.mp3');

localStorage.lock('lock1', 5000, function(){

    // only one of the tabs / browser processes gets here at a time
    console.log('lock aquired:' + new Date().getTime());

    // work here with local storage using getItem, setItem

    // e.g. only one of the tabs is supposed to play a sound and only if none played it within 3 seconds        
    var tm = new Date().getTime();
    if ((localStorage.lastMsgBeep == null)||(localStorage.lastMsgBeep <tm-3000)) {
       localStorage.lastMsgBeep = tm;
       //msgSound.play();                       
       console.log('beep');                        
    }  
});
于 2016-01-22T20:22:20.673 に答える