2017-03-08 15 views
9

मेरे पास एक एक्शनकेबल विधि है जो उपयोगकर्ता की सदस्यता लेती है। यदि कोई नया कॉन्वो शुरू हो गया है, तो मैं उपयोगकर्ता को नए चैनल में भी सब्सक्राइब करना चाहता हूं। मैं नियंत्रक में एक चैनल विधि को कॉल करने के लिए उचित वाक्यविन्यास नहीं समझ सकता।मैं रेल नियंत्रक में एक चैनल विधि कैसे कॉल कर सकता हूं?

अद्यतन: समस्या यह है कि संदेश भेजे जाने पर संदेशों को चैटबॉक्स में जोड़ा जाता है, लेकिन जब पहला संदेश भेजा जाता है, तो वेबसाईट कनेक्शन अभी तक स्थापित नहीं होता है, और इसलिए यह उपयोगकर्ता को लगता है जैसे संदेश नहीं था भेजा (क्योंकि यह संलग्न नहीं किया जा रहा है)।

चैनल/msgs_channel.rb

class MsgsChannel < ApplicationCable::Channel 
    #This function subscribes the user to all existing convos 
    def subscribed 
    @convos = Convo.where("sender_id = ? OR recipient_id = ?", current_user, current_user) 
    @convos.each do |convo| 
     stream_from "msg_channel_#{convo.id}" 
    end 
    end 

    #This is a new function I wrote to subscribe the user to a new convo that is started during their session. 
    def subscribe(convo_id) 
     stream_from "msg_channel_#{convo_id}" 
    end 
end 

मेरी convos नियंत्रक में, विधि बनाने के लिए, मैं कोशिश की है कई चीजें:

convos_controller.rb

def create 
    @convo = Convo.create!({sender_id: @sender_id, recipient_id: @recipient_id}) 
    ActionCable.server.subscribe(@convo.id) 
end 

ActionCable.subscribe(@convo.id)

त्रुटि: NoMethodError (undefined method सदस्यता ले 'ActionCable के लिए: मॉड्यूल) `


ActionCable.msgs.subscribe(@convo.id)

त्रुटि: NoMethodError (undefined method msgs' ActionCable के लिए: मॉड्यूल):`


App.msgs.subscribe(@convo.id) 

त्रुटि : NameError (uninitialized constant ConvosController::App):


MsgsChannel.subscribe(@convo.id)

त्रुटि: NoMethodError (undefined method 'MsgsChannel के लिए: Class`


ActionCable.server.subscribe(@convo.id)

त्रुटि: NoMethodError (undefined method सदस्यता ले' सदस्यता लें # के लिए): `

+0

आईडी पर आधारित प्रत्येक बातचीत के लिए वेबसाईट करने का प्रयास कर रहे हैं? –

+0

@TallPaul यह सही है – gwalshington

उत्तर

1

तो आपको चाहिए उपयोगकर्ता को चैनल में चैनल की सदस्यता नहीं लेना चाहिए बनाने पर रोलर। यह पृष्ठ पर जाने पर आधारित होना चाहिए। जो कनेक्ट है, उसके आधार पर आपको यह बदलने के लिए जेएस/कॉफ़ी फ़ाइल में जोड़कर उपयोगकर्ता कनेक्ट कर सकते हैं। जब मैं सीख रहा था तब इसके लिए एक अच्छा उदाहरण/ट्यूटोरियल यह वीडियो here था।

वीडियो छोड़ देता है कि एक व्यक्तिगत बातचीत से कैसे जुड़ना है। इसलिए मैंने इसके साथ संघर्ष किया और यूआरएल से वार्तालाप आईडी को पकड़ने का एक तरीका खोजा, शायद सबसे अच्छा तरीका नहीं बल्कि यह काम करता है। आशा है कि इस मदद करता है

conversation_id = parseInt(document.URL.match(new RegExp("conversations/"+ "(.*)"))[1]) # gets the conversation id from the url of the page 

App.conversation = App.cable.subscriptions.create { channel: "ConversationChannel", conversation_id: conversation_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['message'] 

    speak: (message) -> 
    @perform 'speak', message: message 
+0

आपकी मदद के लिए हाय धन्यवाद। मैंने पहले ही convo_ids के लिए कनेक्शन स्थापित कर लिया है और सबकुछ बढ़िया काम करता है। सवाल यह है कि, उपयोगकर्ता के सत्र के मध्य में, उपयोगकर्ता एक अलग उपयोगकर्ता के साथ एक नया कॉन्वो खोलता है, और एक संदेश भेजता है। यह नया कोंवो अभी तक सब्सक्राइब नहीं हुआ है, इसलिए उपयोगकर्ता को सही क्रियाएं नहीं दिखाई देती हैं (पूर्व - चैटबॉक्स में संलग्न संदेश)। मैं बनाने विधि में, convos नियंत्रक से चैनल में सब्सक्राइब विधि कैसे कॉल कर सकता हूं? धन्यवाद! – gwalshington

3

एक नियंत्रक

Channel उदाहरणों के साथ जुड़े रहे से किसी विशिष्ट चैनल उदाहरण पुनः प्राप्त उपयोगकर्ता के Connection

conn = ActionCable.server.connections.first { |c| c.current_user == user_id } 

# subs is a hash where the keys are json identifiers and the values are Channels 
subs = conn.subscriptions.instance_variable_get("@subscriptions") 

(। यदि Connection#current_user तो मौजूद नहीं है इसे जोड़ने के लिए the rails ActionCable overview से खंड 3.1.1 के शीर्ष पर निर्देशों का पालन करें)

: निम्नलिखित एक Connection के लिए Channel रों के हैश प्राप्त करने के लिए काम करेंगे

फिर आप जो भी मानदंड चाहते हैं उसके आधार पर Channel प्राप्त कर सकते हैं। उदाहरण के लिए आप उस प्रकार से खोज सकते हैं जो आपके मामले में MsgsChannel होगा। subs में जेसन कुंजी का भी उपयोग किया जा सकता है लेकिन यह अधिक जटिल हो सकता है।

एक बार आपके पास यह उदाहरण हो जाने के बाद आप उस विधि को कॉल कर सकते हैं जिसे आप चाहते हैं (आपके मामले में MsgsChannel#subscribe)।

चिंताओं के बारे में इस दृष्टिकोण

एक Channel सिर्फ सर्वर साइड काम है कि एप्लिकेशन की क्लाइंट की ओर से संदेशों के जवाब में शुरू हुआ हो जाएगा समाहित। सर्वर को Channel विधि कॉल करने के लिए प्रभावी ढंग से सर्वर का दावा करने की मात्रा है कि उपभोक्ता ने एक संदेश भेजा है जो उसने नहीं भेजा था।

मैं इसे साझा करने के बजाय किसी भी तर्क को Controller और Channel से साझा स्थान में किसी विधि में उपयोग करने के बजाय अनुशंसा करता हूं। Controller और Channel तब आवश्यकतानुसार इस विधि को सीधे कॉल कर सकते हैं।

कहा जा रहा है कि इस पर एक दर्दनाक चेतावनी है कि आपको stream_from पर कॉल करने के लिए Channel की आवश्यकता है। दुर्भाग्यवश स्ट्रीमिंग स्ट्रीम Channel एस के लिए विशिष्ट है, भले ही मूल रूप से यह Server के लिए पबब जानकारी अपडेट कर रहा है।

मुझे लगता है कि स्ट्रीम प्रबंधन को वास्तव में उचित कनेक्शन और Server को अपने पब के साथ चाहिए। यदि ऐसा होता है तो आपको किसी एप्लिकेशन के सर्वर पक्ष से Channel विधियों को कॉल करने के बारे में चिंता करने की आवश्यकता नहीं होगी।

आप को प्रभावी ढंग से stream_for अधिक सीधे चलाने के लिए अगर आप एक Channel पाने में सक्षम होना चाहिए, किसी भी Channel (आप subs इस उत्तर के ऊपर से रूप में अच्छी तरह इस्तेमाल कर सकते हैं) और यह

conn = ActionCable.server.connections.first { |c| c.current_user == user_id } 
MsgsChannel.new(conn, "made up id").stream_from "your_stream_name" 

मैं हेवन पर stream_for फोन यह खुद की कोशिश नहीं की लेकिन ऐसा लगता है कि यह काम करना चाहिए।

+0

यह बहुत उपयोगी था! धन्यवाद Chiune! मैंने स्थानीय रूप से आपके पहले सुझाव का परीक्षण किया और यह बेकार ढंग से काम किया, लेकिन जब मैंने परीक्षण में अपने डमी हेरोकू ऐप पर इसका परीक्षण किया तो काम नहीं किया। कोई विचार क्यों? – Amloelxer

+0

@Amloelxer - काम नहीं करके क्या आपका मतलब है कि 'subs' में' चैनल 'उदाहरण नहीं है जिसे आप ढूंढ रहे हैं? –

संबंधित मुद्दे