การใช้ Private-pub กับช่องที่มีคีย์เซ็กเมนต์และรูปแบบ Coffeescript

ฉันกำลังพยายามจำลองระบบการแจ้งเตือนแบบพุชที่คล้ายกับของ Facebook โดยใช้ private_pub ตามหลักการแล้ว ฉันอยากจะเชื่อมโยงสิ่งนี้เพื่อแสดงการแจ้งเตือนโดยใช้อัญมณี เช่น gritter (ยินดีรับคำแนะนำอัญมณีอื่นๆ )

เมื่อใดก็ตามที่มีการเรียกการกระทำบางอย่างจากคอนโทรลเลอร์ ฉันต้องการส่งการแจ้งเตือนไปยังสมาชิกทุกคนที่เป็นส่วนหนึ่งของรหัสเฉพาะ ตราบใดที่คุณเข้าสู่ระบบ แสดงว่าคุณสมัครรับข้อมูลจากช่อง ซึ่งทำได้โดยการใส่ subscribe_to ลงในเลย์เอาต์

ในมุมมอง:

<%= subscribe_to "/messages/#{@group_id}" %>

ในตัวควบคุม

PrivatePub.publish_to("/messages/#{@group_id}", "alert('test')")

มันใช้งานได้ดี แต่ฉันอยากได้สิ่งที่ซับซ้อนกว่าการตอบกลับ alert (เช่น การแจ้งเตือนที่น่าเศร้า) ดังนั้น:

PrivatePub.publish_to("/messages/#{@group_id}", data: @some_data)

ตามบทแนะนำ พวกเขาใช้ coffeescript สำหรับสิ่งนี้ อย่างไรก็ตาม ฉันไม่สามารถรับการแจ้งเตือนแบบธรรมดาได้ (อาจเป็นเพราะรหัสในช่อง)

ใน สิ่งนี้ คำถาม OP สามารถแก้ไขปัญหานี้ได้โดยใช้มุมมอง js.erb แต่ฉันไม่สามารถทำงานได้

ข้อจำกัดความรับผิดชอบ: ความรู้ js และ coffeescript ของฉันเกือบจะเป็นศูนย์

ความช่วยเหลือใด ๆ ที่ชื่นชม :)


แก้ไข

ข้อมูลเพิ่มเติม: ฉันมีวิธีการในตัวควบคุมที่เป็นส่วนหนึ่งของ API สาธารณะ และคาดว่าจะมีคำขอ POST หากทุกอย่างเรียบร้อยดี ระบบจะส่งการตอบกลับความสำเร็จของ JSON นอกเหนือจากนี้ วิธีการเดียวกันนี้ยังส่งการแจ้งเตือนไปยังผู้ใช้ทั้งหมดในกลุ่มใดกลุ่มหนึ่งด้วย

ฉันจัดการเพื่อให้สิ่งนี้ใช้งานได้จริงโดยวางสิ่งนี้ไว้ในคอนโทรลเลอร์:

วิธีการโทรกลับ:

respond_to do |format|
    format.js #-> calls callback.js.erb
    #format.json { render json: {"success" => true}.to_json }
end

และใส่สิ่งที่น่ากลัวลงใน my_api_controller/callback.js.erb:

<% publish_to "/messages/#{@group_id}" do %>
    <%= add_gritter(
    "Nova " + link_to("reserva", reservation_path(@r)) + " de #{@channel} para " + 
    link_to(@hostel_name, hostel_path(@hostel_id)),
    :title => "Nova reserva!",
    :sticky => true,
    :image => :notice
) %>
<% end %>

หมายเหตุ: เนื่องจากการสมัครสมาชิกช่องเสร็จสิ้นในทุกการดู (ผ่านเลย์เอาต์) คุณสามารถรับการแจ้งเตือนบนหน้า/มุมมองใดก็ได้

ปัญหาของฉันในขณะนี้คืออย่างที่คุณเดาได้ การตอบสนองของ JSON เนื่องจากฉันไม่สามารถตอบกลับได้สองครั้ง จึงเรียกเฉพาะ js.erb เท่านั้น แต่การตอบกลับ JSON จะไม่ถูกส่งไป


person Cristiano Sousa    schedule 14.01.2014    source แหล่งที่มา
comment
กำลังจะแนะนำให้ใช้ JS สำหรับสิ่งนี้ทันที ให้ฉันเขียนคำตอบ   -  person Richard Peck    schedule 14.01.2014


คำตอบ (3)


แม้ว่าฉันจะไม่ค่อยมีประสบการณ์กับอัญมณีนี้มากนัก แต่ก็มีบางอย่างที่อาจช่วยได้:


จส

ฝั่งไคลเอ็นต์ โดยพื้นฐานแล้ว JS ของคุณใช้งาน eventlistener บนออบเจ็กต์ private_pub (กำหนดเมื่อคุณรวม private_pub / gritter JS บนเพจของคุณ) ซึ่งคุณสามารถใช้เพื่อดำเนินการอื่นๆ (การแจ้งเตือนการโทร เพิ่มข้อมูลต่อท้ายเพจ ฯลฯ)

ดูเหมือนว่าแบ็คเอนด์ของคุณใช้งานได้ เพียงรับและประมวลผลข้อมูลจากเซิร์ฟเวอร์ที่คุณกำลังประสบปัญหาเท่านั้น เพื่อแก้ไขปัญหานี้ คุณสามารถทำ 2 สิ่ง: 1) เรียกใช้การเรียก JS มาตรฐานจาก application.js หรือเรียกใช้ไฟล์ js จากการทำงานของคอนโทรลเลอร์ของคุณ:


ตัวควบคุม

ตามเอกสาร private_pub คุณควรทำสิ่งนี้เพื่อสร้างไฟล์ JS:

#app/controllers/your_controller.rb
def create
    @message = "Hello"

    respond_to do |format| 
        format.html { PrivatePub.publish_to("/messages/#{@group_id}", "alert('test')") }
        format.js #-> calls create.js.erb
    end
end 

#app/views/your_controller/create.js.erb
<% publish_to "/messages/new" do %>
  $("#chat").append("<%= j render(@messages) %>");
<% end %>

เบราว์เซอร์

#app/assets/javascripts/application.js.coffee
PrivatePub.subscribe("/messages/new", (data, channel) ->
      alert data.message.content
person Richard Peck    schedule 14.01.2014
comment
ขอบคุณสำหรับคำตอบ ฉันได้แก้ไขคำถามของฉันเพื่อดูข้อมูลเพิ่มเติมแล้ว - person Cristiano Sousa; 15.01.2014

ฉันสามารถทำได้สำเร็จโดยการเพิ่มสคริปต์ gritter โดยตรงในเมธอด publish_to ของ Privat pub

ในตัวควบคุมของฉัน:

PrivatePub.publish_to 
  "/some/URI/#{entity.id}"
 ,"jQuery.gritter.add({
      image: '#{ActionController::Base.helpers.asset_path('notice.png')}'
    , sticky: true
    ,title:'#{t('some_title')}'
    , text: '#{t('some text'}' 
});"

render json: {"error"=>{"code"=>20,"msg"=>e.message},"success" => false}.to_json

โดยพื้นฐานแล้ว ฉันสามารถเผยแพร่ไปยัง PrivatePub ได้โดยไม่ต้องใช้การตอบสนอง html ซึ่งทำให้ฉันสามารถส่งคืนการตอบสนอง JSON ตามที่ตั้งใจไว้

person Cristiano Sousa    schedule 11.03.2015

ฉันเดาว่า คุณสามารถจัดการปัญหาของคุณด้วยความช่วยเหลือของ gon gem ดังด้านล่างนี้:

In view

<%= subscribe_to "/messages/#{@group_id}" %>

In controller

gon.group_id = @group_id
PrivatePub.publish_to("/messages/#{@group_id}", message: @message)

In messages.coffee

if gon.group_id
  PrivatePub.subscribe "/messages/#{gon.group_id}", (data, channel) ->
    jQuery.gritter.add
      image: '/assets/notice.png'
      title: 'Notification!'
      text: data.message.content

แต่ gon.group_id อาจสร้างปัญหาได้ในบางครั้ง ดังนั้นคุณต้องดูแลเรื่องนั้น

ผมเลยแนะนำให้ใช้ js.erb ซึ่งง่ายและเราสามารถเข้าถึงตัวแปร controller's ได้อย่างง่ายดายในไฟล์ js.erb

หวังว่าจะช่วยตอบปัญหาของคุณ

person przbadu    schedule 10.03.2015