1

我有一个小片段引发“现有订阅频道”异常,即使我只调用一次订阅方法。

这可以通过将订阅请求移到“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"}}}
4

2 回答 2

3

虽然它看起来确实像库中的错误(请报告它!),但您无需绑定到state_change事件即可订阅频道。

如果您查看 subscribe 事件的代码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>
于 2013-07-26T14:19:25.340 回答
2

它看起来像一个错误。如果您在开发工具中打开“网络”选项卡并查看 WebSocket 连接“帧”信息,您可以看到pusher:subscribe协议事件被发送了两次。但是,代码肯定只调用pusher.subscribe一次。

您应该通过 Pusher 支持或向github repo提交问题来提出此错误。

pusher:subscribe 协议事件发送两次

于 2013-07-24T18:48:41.103 回答