Knockout订阅 - 使用websockets

时间:2016-03-09 18:19:27

标签: javascript knockout.js websocket race-condition

我不是张贴实际复杂的代码,而是以简化的形式提出这个问题。我正在开发一个Web应用程序,它有多个客户端通过websockets连接,每个客户端都有可以通过编程前端进行编程的接口。

每个客户端都有一个名为gameState的变量,它是一个可观察的变量。为简单起见,我们可以说它是一个常规数字。

var gameState = ko.observable();

当客户端最初连接时,后端服务器通过一个名为loadState的函数将gameState的当前值赋予它们。

function loadState(newGameState) {
    gameState(newGameState);
}

然后,每个客户端都可以通过输入框更改gameState的值,该输入框需要向所有其他连接的客户端发送更新。

<input type="text" data-bind="value: gameState"/>

我目前正在通过订阅方式发送更改。

gameState.subscribe(function(newGameState) {
    // sends a websocket message to the server with newGameState
    // which is received by all other clients via loadState function
});

此设置的问题是,当其他客户端获取websocket信号以更新其自己的gameState本地值时,这将依次触发自己的gameState.subscribe函数,因为值已更新,因此发送自己的更新。显然,这会导致更新和消息的无限和指数级联。

我觉得解决这个问题的方法是更改​​loadState函数以某种方式暂停gameState订阅

function loadState(newGameState) {
    // pause gameState.subscribe
    gameState(newGameState);
    // re-enable gameState.subscribe
}

然而似乎没有办法在淘汰赛中实现这一目标。

此外,如果有人确实有一个类似于“暂停订阅”的解决方案,就像我上面提到的那样。我觉得有机会错过更新。比如说,loadState开始运行并且gameState.subscribe被暂停。然后,用户为gameState输入新值。如果他们在执行gameState(newGameState)之前执行了它,那么当gameState(newGameState)运行时,它们的新值会立即被替换。如果他们在从loadState设置gameState后执行此操作,那么他们的值会保留,但订阅不会处于活动状态,因此他们的新值不会发送给其他客户端。

0 个答案:

没有答案