【问题标题】:"Existing subscription to channel" while only subscribing once“现有订阅频道”,仅订阅一次
【发布时间】:2013-07-24 12:04:05
【问题描述】:

我有一个小的 sn-p,即使我只调用一次 subscribe 方法,它也会引发“现有订阅频道”异常。

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

【问题讨论】:

    标签: javascript pusher


    【解决方案1】:

    虽然它看起来确实像库中的错误(请报告!),但您无需绑定到 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 客户端只会将该频道添加到列表中。一旦客户端建立了连接,它将通过subscribeAll方法为它列表中的每个频道再次调用subscribe方法:

    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>
    

    【讨论】:

    • “您不需要绑定到 state_change 事件来订阅频道” - 这是正确的,但实际上只是偶然遇到了这种行为 :) 在 Pusher 的问题跟踪器 @987654321 中转发了这个@
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-06-05
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      • 2018-07-30
      • 1970-01-01
      • 2015-10-14
      相关资源
      最近更新 更多