根据Sitepoint's tutorial,我在我的RoR应用程序中使用ActionCable,该应用程序旨在充当角色扮演的聊天室。我已经设置好了,正如预期的那样,无论何时创建消息都会广播消息。但是,每次加载聊天室页面时,都会为同一个用户进行新的订阅,使消息多次出现。
应用/资产/ Javascript角/信道/ 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
答案 0 :(得分: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)
# …
)()