Javascript &引用;现有频道订阅;而只订阅一次

Javascript &引用;现有频道订阅;而只订阅一次,javascript,pusher,Javascript,Pusher,我有一个小片段,它抛出了一个“existingsubscriptiontochannel”异常,尽管我只调用了subscribe方法一次 这可以通过将订阅请求移到“state_change”处理程序之外来避免,但我想知道是什么原因导致了这种情况?可能是Pusher库中的一个bug <!doctype html> <html> <body> <h1>Pusher subscribe testcase</h1> <p&

我有一个小片段,它抛出了一个“existingsubscriptiontochannel”异常,尽管我只调用了subscribe方法一次

这可以通过将订阅请求移到“state_change”处理程序之外来避免,但我想知道是什么原因导致了这种情况?可能是Pusher库中的一个bug

<!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>

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

您应该通过Pusher支持或通过将问题提交给


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

您应该通过Pusher支持或通过将问题提交给


虽然它看起来确实像库中的一个bug(一定要报告!),但您不需要绑定到
state\u 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;
};
您将看到,它将首先通过
频道将您的频道添加到频道的内部列表中。add
方法,如下所示:

prototype.add = function(name, pusher) {
  if (!this.channels[name]) {
    this.channels[name] = createChannel(name, pusher);
  }
  return this.channels[name];
};
它只会在您之前没有订阅的情况下添加频道

因此,如果您要在建立连接之前订阅一个频道,推送客户端只会将该频道添加到列表中。一旦客户端建立了连接,它将通过
subscribebeall
方法为其列表中的每个频道再次调用
subscribe
方法:

this.connection.bind('connected', function() {
  self.subscribeAll();
});
看到此时,
this.connection.state
已连接,它将连接

因此,简单地说,不要麻烦绑定到要订阅的
state\u 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>

推送订阅测试用例
提示:检查你的控制台

var推进器,通道; 推进器=新推进器('XXXXXXXXXXXXXX'); 通道=推送器。订阅(“测试通道”); channel.bind('pusher:subscription\u successed',function(){ console.log('subscribed'); });
虽然它看起来确实像库中的一个bug(请报告!),但您不需要绑定到
state\u 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;
};
您将看到,它将首先通过
频道将您的频道添加到频道的内部列表中。add
方法,如下所示:

prototype.add = function(name, pusher) {
  if (!this.channels[name]) {
    this.channels[name] = createChannel(name, pusher);
  }
  return this.channels[name];
};
它只会在您之前没有订阅的情况下添加频道

因此,如果您要在建立连接之前订阅一个频道,推送客户端只会将该频道添加到列表中。一旦客户端建立了连接,它将通过
subscribebeall
方法为其列表中的每个频道再次调用
subscribe
方法:

this.connection.bind('connected', function() {
  self.subscribeAll();
});
看到此时,
this.connection.state
已连接,它将连接

因此,简单地说,不要麻烦绑定到要订阅的
state\u 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>

推送订阅测试用例
提示:检查你的控制台

var推进器,通道; 推进器=新推进器('XXXXXXXXXXXXXX'); 通道=推送器。订阅(“测试通道”); channel.bind('pusher:subscription\u successed',function(){ console.log('subscribed'); });
“订阅频道不需要绑定到状态更改事件”-这是正确的,但实际上只是意外地遇到了这种行为:)在Pusher的问题跟踪器中重新发布了此消息“订阅频道不需要绑定到状态更改事件”-这是正确的,但实际上只是偶然发现了这种行为:)在Pusher的问题追踪器中重新发布了这一行为