2017-10-09 165 views
3

根據Sitepoint's tutorial,我在RoR應用程序中使用ActionCable,該應用程序旨在充當角色扮演的聊天室。我已經設置好了,並且如預期的那樣,消息在創建時就播出。但是,每次加載聊天室頁面時,都會爲同一用戶創建新的訂閱,從而使消息多次出現。
ActionCable多次登錄用戶

應用程序/資產/ Java腳本/渠道/ roleplays.coffee:

jQuery(document).on 'turbolinks:load', -> 
    messages = $('#messages') 
    if $('#messages').length > 0 


    App.global_chat = App.cable.subscriptions.create { 
     channel: "RoleplaysChannel" 
     roleplay_id: messages.data('roleplay-id') 
    }, 
     connected: -> 
# Called when the subscription is ready for use on the server 

     disconnected: -> 
# Called when the subscription has been terminated by the server 

     received: (data) -> 
     messages.append(data) 
     console.log(data) 


     send_message: (message, roleplay_id) -> 
     @perform 'send_message', message: message, roleplay_id: roleplay_id 


    $('#new_message').submit (e) -> 
     $this = $(this) 
     textarea = $this.find('#message_body') 
     e.preventDefault() 

     if $.trim(textarea.val()).length > 1 
     App.global_chat.send_message textarea.val(), messages.data('roleplay-id') 
     textarea.val('') 

     return false 

回答

1

爲了避免重複訂閱,您需要確定用戶是否已經連接的某種方式。

一個簡單的方法可能是做一些類似如下:

(-> 
    connected = false 

    jQuery(document).on 'turbolinks:load', -> 
    messages = $('#messages') 

    if $('#messages').length > 0 && !connected 
     App.global_chat = App.cable.subscriptions.create { 
     channel: "RoleplaysChannel" 
     roleplay_id: messages.data('roleplay-id') 
     }, 
     connected: -> 
      connected = true 

     disconnected: -> 
      connected = false 

     # … 
)() 

這將僅適用於單個角色扮演(或聊天室)工作。如果用戶嘗試不同的角色扮演,他們以前訪問過,他們將不會訂閱新的。爲了解決這個問題,你需要一種管理訂閱的方式。

像下面的內容可能會奏效:

(-> 
    connections = [] 

    addConnection = (id) -> 
    connections.push(id) 

    removeConnection = (id) -> 
    index = connections.indexOf(id) 
    connections.splice(index, 1) if index > -1 

    connectedTo = (id) -> 
    connections.indexOf(id) > -1 

    jQuery(document).on 'turbolinks:load', -> 
    messages = $('#messages') 
    roleplayID = messages.data('roleplay-id') 

    if $('#messages').length > 0 && !connectedTo(roleplayID) 
     App.global_chat = App.cable.subscriptions.create { 
     channel: "RoleplaysChannel" 
     roleplay_id: roleplayID 
     }, 
     connected: -> 
      addConnection(roleplayID) 

     disconnected: -> 
      removeConnection(roleplayID) 

     # … 
)()