gpt4 book ai didi

javascript - Rails javascript 轮询

转载 作者:行者123 更新时间:2023-11-29 18:13:58 25 4
gpt4 key购买 nike

我正在尝试在我的应用程序中实现 javascript 轮询,但我遇到了一些问题。我非常关注这个 railscasts .我的问题是尝试在发现的任何新数据之前添加。它会添加所有新旧数据,如果没有发现任何新数据,它只会添加所有旧数据。我的另一个问题是我的 setTimeout 只被调用一次,即使在我尝试像它们在 railscast 中显示的那样保持轮询之后也是如此。下面是我的代码。我在这里做错了什么?

轮询.js

var InboxPoller;

InboxPoller = {
poll: function() {
return setTimeout(this.request, 5000);
},
request: function() {
return $.getScript($('.inbox_wrap').data('url'), {
after: function() {
$('.conversation').last().data('id')
}
});
}
};

$(function() {
if ($('.inbox_wrap').length > 0) {
return InboxPoller.poll();
}
});

轮询.js.erb

$(".inbox_wrap").prepend("<%= escape_javascript(render @conversations, :locals => {:conversation => @conversation}) %>");
InboxPoller.poll();

conversations_controller.rb

class ConversationsController < ApplicationController
before_filter :authenticate_member!
helper_method :mailbox, :conversation

def index
@messages_count = current_member.mailbox.inbox({:read => false}).count
@conversations = current_member.mailbox.inbox.order('created_at desc').page(params[:page]).per_page(15)
end

def polling
@conversations = current_member.mailbox.inbox.where('conversation_id > ?', params[:after].to_i)
end

def show
@receipts = conversation.receipts_for(current_member).order('created_at desc').page(params[:page]).per_page(20)

render :action => :show
@receipts.mark_as_read
end

def create
recipient_emails = conversation_params(:recipients).split(',').take(14)
recipients = Member.where(user_name: recipient_emails).all

@conversation = current_member.send_message(recipients, *conversation_params(:body, :subject)).conversation

respond_to do |format|
format.html { redirect_to conversation_path(conversation) }
format.js
end
end

def reply
@receipts = conversation.receipts_for(current_member).order('created_at desc').page(params[:page]).per_page(20)
@receipt = current_member.reply_to_conversation(conversation, *message_params(:body, :subject))

respond_to do |format|
format.html { conversation_path(conversation) }
format.js
end
end

private

def mailbox
@mailbox ||= current_member.mailbox
end

def conversation
@conversation ||= mailbox.conversations.find(params[:id])
end

def conversation_params(*keys)
fetch_params(:conversation, *keys)
end

def message_params(*keys)
fetch_params(:message, *keys)
end

def fetch_params(key, *subkeys)
params[key].instance_eval do
case subkeys.size
when 0 then self
when 1 then self[subkeys.first]
else subkeys.map{|k| self[k] }
end
end
end

def check_current_subject_in_conversation
if !conversation.is_participant?(current_member)
redirect_to conversations_path
end
end

end

index.html.erb

<%= content_tag :div, class: "inbox_wrap", data: {url: polling_conversations_url} do %>
<%= render partial: "conversations/conversation", :collection => @conversations, :as => :conversation %>
<% end %>

_conversation.html.erb

<div id="conv_<%= conversation.id %>_<%= current_member.id %>" class="conversation" data-id="<%= conversation.id %>">

<div class="conv_body">
<%= conversation.last_message.body %>
</div>

<div class="conv_time">
<%= conversation.updated_at.localtime.strftime("%a, %m/%e %I:%M%P") %>
</div>

</div>

最佳答案

Javascript 轮询效率极低 - 基本上每隔几秒向您的服务器发送一次请求以监听“更新”。即便如此,在许多情况下,更新将是整个文件/数据批处理,没有简洁性

如果我们不得不做这样的事情,我们总是考虑使用一种更高效的技术,特别是 SSEWebsockets

--

上交所

您是否考虑过使用Server Sent Events

这些是 HTML5 technology它的工作方式与 Javascript 轮询非常相似——每隔几秒发送一次请求。不同之处在于这些工作的基本方式——收听自己的“ channel ”(mime 类型 text/event-stream——允许您真正具体地处理您发送的数据)

你可以这样调用它:

#app/assets/javascript/application.js
var source = new EventSource("your/controller/endpoint");
source.onmessage = function(event) {
console.log(event.data);
};

这将允许您创建一个 endpoint对于“事件监听器”:

#config/routes.rb
resources :controller do
collection do
get :event_updates #-> domain.com/controller/event_updates
end
end

您可以使用 ActionController::Live::SSE 发送更新类:

#app/controllers/your_controller.rb
Class YourController < ApplicationController
include ActionController::Live

def event_updates
response.headers['Content-Type'] = 'text/event-stream'
sse = SSE.new(response.stream, retry: 300, event: "event-name")
sse.write({ name: 'John'})
sse.write({ name: 'John'}, id: 10)
sse.write({ name: 'John'}, id: 10, event: "other-event")
sse.write({ name: 'John'}, id: 10, event: "other-event", retry: 500)
ensure
sse.close
end
end

--

网络套接字

执行此操作的首选方法是使用 websockets

Websockets 比 SSE 或标准 JS 轮询更有效,因为它们始终保持连接打开。这意味着您可以发送/接收您需要的任何更新,而无需向服务器发送持续更新

Websockets 的问题在于设置过程 - 在您自己的应用服务器上运行 WebSocket 连接非常困难,因此许多人不这样做。

如果您对 Websockets 感兴趣,您可能希望研究使用 Pusher - 拥有 Ruby integration 的第三方 websocket 提供商.我们经常使用它 - 这是在您的应用程序中提供“实时”更新的一种非常有效的方式,不,我不隶属于他们

关于javascript - Rails javascript 轮询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24942389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com