我有一个小片段,抛出“现有订阅频道”异常,即使我只调用一次订阅方法。
这可以通过将“订阅”请求移到“state_change”处理程序之外来避免,但我想知道是什么原因造成这种情况?也许是Pusher库中的一个错误?
<!doctype html>
<html>
<body>
<h1>Pusher subscribe testcase</h1>
<p>Tip: check your console</p>
<script src="https://d3dy5gmtp8yhk7.cloudfront.net/2.1/pusher.min.js"></script>
<script>
var pusher, channel;
pusher = new Pusher('xxxxxxxxxxxxxxxxx');
pusher.connection.bind('state_change', function(change){
if(change.current === 'connected'){
console.log('connected');
channel = pusher.subscribe('test-channel');
channel.bind('pusher:subscription_succeeded', function() {
console.log('subscribed');
});
}
})
</script>
</body>
</html>
这导致:
connected
subscribed
Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Existing subscription to channel test-channel"}}}
答案 0 :(得分:3)
虽然它看起来像是库中的错误(报告它!),但您无需绑定到state_change
事件以订阅频道。
如果您在pusher.js
中查看订阅事件的代码:
prototype.subscribe = function(channel_name) {
var self = this;
var channel = this.channels.add(channel_name, this);
if (this.connection.state === 'connected') {
channel.authorize(this.connection.socket_id, function(err, data) {
if (err) {
channel.handleEvent('pusher:subscription_error', data);
} else {
self.send_event('pusher:subscribe', {
channel: channel_name,
auth: data.auth,
channel_data: data.channel_data
});
}
});
}
return channel;
};
您会看到它会首先通过channels.add
方法将您的频道添加到内部频道列表中,如下所示:
prototype.add = function(name, pusher) {
if (!this.channels[name]) {
this.channels[name] = createChannel(name, pusher);
}
return this.channels[name];
};
只会在您之前未订阅的情况下添加频道。
因此,如果您在建立连接之前订阅了频道,则Pusher客户端将仅将频道添加到列表中。客户端建立连接后,将通过subscribe
方法为其列表中的每个频道再次调用subscribeAll
方法:
this.connection.bind('connected', function() {
self.subscribeAll();
});
此时this.connection.state
connected
,它会连接。
所以,重新绑定,不要费心绑定到state_change
事件进行订阅,只需订阅,就像这样:
<!doctype html>
<html>
<body>
<h1>Pusher subscribe testcase</h1>
<p>Tip: check your console</p>
<script src="https://d3dy5gmtp8yhk7.cloudfront.net/2.1/pusher.js"></script>
<script>
var pusher, channel;
pusher = new Pusher('XXXXXXXXXXXXXXXX');
channel = pusher.subscribe('test-channel');
channel.bind('pusher:subscription_succeeded', function() {
console.log('subscribed');
});
</script>
</body>
</html>
答案 1 :(得分:2)
它看起来像一个bug。如果在开发工具中打开“网络”选项卡并查看WebSocket连接“帧”信息,则可以看到发送两次的pusher:subscribe
协议事件。但是,代码肯定只调用pusher.subscribe
一次。
您应该通过Pusher支持或向github repo提交问题来提出此错误。