我的情况大致如下:我需要创建一个“聊天流”,用户还可以在其中添加自封装的子模块,这些子模块具有自己独特的私有通道进行通信。换句话说,用户正在聊天聊天,用户#1点击“添加模块”按钮,生成uuid并在“newModule”消息中发布到PubNub聊天频道,该频道上的所有听众都使用uuid接收消息,并继续创建模块的本地副本,该副本本身订阅PubNub通道'uuid'。模块出现在聊天流程中,用户可以继续聊天,但也可以在他们自己的'uuid'PubNub频道上从链接的私有模块来回发送(让我们说)'点击'。
不幸的是,当新模块尝试订阅新频道时,PubNub会“重新启动”聊天频道上收到的最后一个事件,从而触发创建第二个重复模块。
我在这里创建了一个展示问题行为的精简测试案例: http://codepen.io/teolitto/pen/09f75b8b60f69a1c3aaab85af01b3cd3?editors=1000
DOM和标签定义:
<AppMain></AppMain>
<script type="riot/tag">
<AppMain>
<h3>AppMain</h3>
<button onclick={ publishNewColorBox }>
New ColorBox
</button>
//logic
var context = this;
context.eventBus = appCore.eventBus;
context.publishNewColorBox = function() {
console.log('1. "New ColorBox" button click handler')
PN.publish({
channel: appCore.channel,
message: {
type: "newColorBox",
boxId: PN.uuid()
}
})
}
context.addNewColorBox = function(boxId){
var cb = document.createElement('ColorBox');
context.root.appendChild(cb);
riot.mount(cb, {boxId: boxId});
}
context.init = function(){
context.eventBus.on('addNewColorBox', function(boxId){
console.log('3. riot "addNewColorBox" event received by application, mounting new ColorBox');
context.addNewColorBox(boxId);
})
}
context.on('mount', function(){
context.init();
})
</AppMain>
<ColorBox>
<div></div>
//logic
var context = this;
context.eventBus = riot.observable();
context.boxId = opts.boxId;
context.init=function(){
console.log('4. ColorBox successfully mounted, subscribing PN to channel ',context.boxId);
PN.subscribe({
//channel: 'someChannel',
channel: context.boxId,
message: function(m){
console.log('box channel received message:',m);
}
});
}
context.on('mount', function(){
context.init();
})
</ColorBox>
</script>
使用Javascript:
$(function(){
appCore = {
channel: "firstChannel",
eventBus: riot.observable()
}
PN = PUBNUB.init({
publish_key: 'pub-c-92c890df-0f01-4f9b-9084-ec118f452dc9',
subscribe_key: 'sub-c-e8889318-c702-11e5-837e-02ee2ddab7fe'
});
PN.subscribe({
channel: appCore.channel,
message: function(m){
switch(m.type) {
case "newColorBox":
console.log('2. PN channel', appCore.channel, ' received "newColorBox" message. Firing riot event "addNewColorBox"')
appCore.eventBus.trigger('addNewColorBox', m.boxId);
break;
}
}
});
riot.mount('AppMain');
});
我确实在PubNub控制台中打开了muxing('stream controller'),所以不是这样。
我发现有助于改善问题的黑客 - 在订阅新频道之前设置约33毫秒的超时似乎可以解决问题。如果订阅的频道是最近访问过的频道,则不会出现问题。但是,由于我每次都需要一个新的,独特的频道,而且我真的更愿意避免像超时一样的hacky解决方案(天知道如果我必须这样做我会遇到什么),我问这里。有任何想法吗?这可能是PubNub中的错误吗?或者是我的实施镜头?
任何输入都非常赞赏。