使用 websocket 反应通量更新循环
Posted
技术标签:
【中文标题】使用 websocket 反应通量更新循环【英文标题】:React Flux update loop with websocket 【发布时间】:2016-01-03 08:37:15 【问题描述】:我有一个使用 Flux 反应的应用程序和一个存储所有数据并在通过 websocket 发生更新时通知所有订阅者的网络服务器。
我的问题是,当我的组件触发一个操作时,新状态会通过套接字发送到网络服务器并发送到客户端浏览器的商店,但是我的服务器会向所有订阅者发送一条消息,表明这是新状态为此组件,以便所有客户端都得到更新,但这会导致客户端发送状态已更改的新更新。这进入了一个无限循环,客户端发送到服务器,服务器响应所有订阅者的更新,并且由于它是一个更新,客户端再次将新状态发送到服务器......
utils/WebAPI:
var socket = new SockJS("http://localhost:8080/stomp");
var client = Stomp.over(socket);
module.exports =
sendUpdate: function(update)
if(client.connected)
client.send("/app/hello", , JSON.stringify(update));
,
getUpdates: function()
client.connect(, function()
client.subscribe("/topic/hello", function(message)
var data = JSON.parse(message.body);
MyActions.updateState(data.id, data.update)
);
);
;
我的行动:
var AppDispatcher = require('../dispatcher/AppDispatcher');
var FunctionConstants = require('../constants/FunctionConstants');
// Define actions object
var MyActions =
updateState: function(id, update)
AppDispatcher.handleAction(
actionType: FunctionConstants.STATE_UPDATED,
id: id,
update: update
)
;
module.exports = MyActions;
我的商店中的更新功能:
var WebAPI = require('../utils/WebAPI');
var _ = require('underscore');
// Define initial data points
var _data = ;
function updateFunction(id, data)
_data[id] = data
var update = "\"actionType\": \"STATE_UPDATED\", \"id\": \""+id+"\", \"update\": "+JSON.stringify(data)+"";
WebAPI.sendUpdate(JSON.parse(update));
...
最后是我的组件:
let React = require('react');
var MyActions = require('../../../actions/MyActions');
var WebAPI = require('../../../utils/WebAPI');
//Subscribe for updates sent from server
WebAPI.getUpdates();
let FunctionComponent = React.createClass(
newState: function(data)
MyActions.updateState(this.props.id, data);
,
render()
var d = this.props.data;
d.count++;
return (
<div>
<h1>this.props.id</h1>
<div>this.props.data</div>
<button onClick=this.newState(d)
</div>
)
);
module.exports = FunctionComponent;
当我的组件调用任何操作并且服务器向所有订阅者发送更新时,我该如何解决导致无限循环的问题?
【问题讨论】:
【参考方案1】:WebAPI.getUpdates();应该在商店中,而不是在组件中。以下是使用回流的基本存储。其余的见这个; Flux: waitFor specific event.
import Reflux from 'reflux';
import Actions from './Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';
let BasicStoreObject =
init() this.listenTo(AddonStore, this.onAddonTrigger); ,
data1: ,
listenables: Actions,
mixins: [MixinStoreObject],
onGotData1(data) this.data1 = data; BasicStore.trigger('data1'); ,
onAddonTrigger() BasicStore.trigger('data2'); ,
getData1() return this.data1; ,
getData2() return AddonStore.data2; ,
getData3() return this.data3;
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;
【讨论】:
其实我把它放在哪里并不重要,因为它只会打开一个套接字并在数据来自服务器时进行监听,然后调用 MyAction。唯一重要的是这个套接字在我的应用程序的某个地方初始化 可能是这样,但它是唯一可以说明您的循环问题的代码。如果更新操作仅由按钮单击事件调用,则不会由道具更新触发。如果您的代码中只有一个地方与您的 webapi 交互,那么调试起来会更容易。 循环是在我的 webapi 中的 getUpdates 中引起的,因为当从服务器接收到更新时,调用将传送到我的商店,这将再次向服务器发送更新。如果更新来自服务器或视图,通量体系结构是否有一些可能的方法来检查我的商店 updateFunction(),因为如果更新来自服务器,那么我不需要调用 WebAPI 来通知服务器我的 updateFunction() 中的更新。 我看的不够仔细。对于来自服务器的更新和来自组件的更新,您需要单独的操作。来自服务器的更新应由存储处理,然后传递给组件。来自组件的更新也应该由 store 处理,然后传递给服务器。这里有一个部分示例; ***.com/questions/32537568/…。我将在上面添加basic.store。 谢谢,我相信我现在明白了。以上是关于使用 websocket 反应通量更新循环的主要内容,如果未能解决你的问题,请参考以下文章