Websocket 如何将数据推送到基于SQL语句的浏览器?
我知道在这个话题上有很多线索,但似乎确实回答了我想要的答案。我以前从来没有做过任何推送技术,所以这里的一些指导非常感谢。我知道当某些事情发生变化时,会触发推送到任何正在侦听的浏览器,但我认为这并不完全符合我正在尝试的场景 我们正在重建用户的web应用程序,以便他们跟踪发货。我们将允许用户建立自己的搜索,以匹配他们的工作方式。例如,有些人会查找计划今天交付的任何装运,而有些人会查找今天要提货的装运,还有一些人会查找需要计划提货的装运。因此,当他们打开应用程序时,我可以为他们计算他们今天需要完成的每个工作任务。现在我想要的是,计数将根据重新运行的SQL而改变。但是我不希望用户必须刷新页面才能看到新的计数 如何运行此SQL并将当前计数推送到使用此SQL的任何浏览器。自动重新运行此SQL的机制是什么?请记住,我将有50个或更多这些独特的SQL需要执行和计数Websocket 如何将数据推送到基于SQL语句的浏览器?,websocket,push-notification,long-polling,polling,Websocket,Push Notification,Long Polling,Polling,我知道在这个话题上有很多线索,但似乎确实回答了我想要的答案。我以前从来没有做过任何推送技术,所以这里的一些指导非常感谢。我知道当某些事情发生变化时,会触发推送到任何正在侦听的浏览器,但我认为这并不完全符合我正在尝试的场景 我们正在重建用户的web应用程序,以便他们跟踪发货。我们将允许用户建立自己的搜索,以匹配他们的工作方式。例如,有些人会查找计划今天交付的任何装运,而有些人会查找今天要提货的装运,还有一些人会查找需要计划提货的装运。因此,当他们打开应用程序时,我可以为他们计算他们今天需要完成的每
谢谢你的指导 我认为这完全属于AJAX的角色。AJAX将允许您向服务器发出GET和POST请求,服务器将处理查询并将结果返回给JS函数。冒着jQuery传播的风险,API使这类事情变得非常简单和标准,您几乎可以拥有任何想要激活它的事件 这有几个问题,即客户端输入和SQL注入。如果您通过POST请求发送任何输入,您必须非常小心地清理所有内容。使用预先准备好的语句,不要执行查询字符串concatation+执行,并且通常假定用户将尝试发送您不希望发送的文本。为将成功确认的输入提供一些服务器端边界(例如,如果选项为“左”或“右”,并且它们给出了“底部”,则默认为“底部”或将其删除)
AJAX拉取是一种解决方案,尽管其他解决方案可能更适合并为您节省资源* 例如,拥有一个持久的Websocket连接将有助于最大限度地降低建立新连接和重复请求(大部分是冗余的)的成本 因此,您的服务器应该具有较低的工作负载,并且您的应用程序将需要较少的带宽(如果这些对您很重要的话) 即使使用Websocket连接只是告诉客户机何时发送AJAX请求,有时也可以节省资源 这里有一个快速的Websocket推送演示 您可以使用许多不同的Websocket解决方案。我用编写了一个快速演示,因为它非常容易实现,但还有其他方法可以实现 Plezi框架是一个Ruby框架,它运行自己的HTTP和Websocket服务器,独立于Rack 示例代码包括用于模型的控制器(DemoController)、用于根索引页的控制器(DemoIndex)和用于Websocket连接的控制器(MyWSController) 示例代码看起来更长,因为它都在一个脚本中-甚至用作客户端的HTML页面。。。但它确实很容易阅读 搜索要求从客户端发送到web服务器(搜索要求模型的对象ID介于0和50之间) 每次创建(或更新)对象时,都会向所有连接的客户端发送警报,首先运行每个客户端的搜索,然后发送任何更新 服务器休息的其余时间(除了每隔45秒左右ping一次,以保持websocket连接的活动状态) 要查看演示,只需在IRB终端**内复制并粘贴以下代码,然后访问演示页面:
require 'plezi'
class MyWSController
def on_open
# save the user data / register them / whatever
@searches = []
end
def on_message data
# get data from the user
data = JSON.parse data
# sanitize data, create search parameters...
raise "injection attempt: #{data}}" unless data['id'].match(/^\([\d]+\.\.[\d]+\)\z/)
# save the search
@searches << data
end
def _alert options
# should check @searches here
@searches.each do |search|
if eval(search['id']).include? options[:info][:id]
# update
response << {event: 'alert'}.merge(options).to_json
else
response << "A message wouldn't be sent for id = #{options[:info][:id]}.\nSaved resources."
end
end
end
end
class DemoController
def index
"use POST to post data here"
end
# called when a new object is created using POST
def save
# ... save data posted in params ... then:
_send_alert
end
# called when an existing object is posted using POST or UPDATE
def update
# ... update data posted in params ... then:
_send_alert
end
def demo_update
_send_alert message: 'info has been entered', info: params.update(id: rand(100), test: 'true')
" This is a demo for what happens when a model is updated.\n
Please Have a look at the Websocket log for the message sent."
end
# sends an alert to
def _send_alert alert_data
MyWSController.broadcast :_alert, alert_data
end
end
class DemoIndex
def index search = '(0..50)'
response['content-type'] = 'text/html'
<<-FINISH
<html>
<head>
<style>
html, body {height: 100%; width:100%;}
#output {margin:0 5%; padding: 1em 2em; background-color:#ddd;}
#output li {margin: 0.5em 0; color: #33f;}
</style>
</head><body>
<h1> Welcome to your Websocket Push Client </h1>
<p>Please open the following link in a <b>new</b> tab or browser, to simulate a model being updated: <a href='#{DemoController.url_for id: :demo_update, name: 'John Smith', email: 'john@gmail.com'}', target='_blank'>update simulation</a></p>
<p>Remember to keep this window open to view how a simulated update effects this page.</p>
<p>You can also open a new client (preferably in a new tab, window or browser) that will search only for id's between 50 and 100: <a href='#{DemoIndex.url_for :alt_search}'>alternative search</a></p>
<p>Websocket messages recieved from the server should appeare below:</p>
<ul id='output'>
</ul>
<script>
var search_1 = JSON.stringify({id: '#{search}'})
output = document.getElementById("output");
websocket = new WebSocket("#{request.base_url 'ws'}/ws");
websocket.onmessage = function(e) { output.innerHTML += "<li>" + e.data + "</li>" }
websocket.onopen = function(e) { websocket.send(search_1) }
</script>
</body></html>
FINISH
end
def alt_search
index '(50..100)'
end
end
listen
route '/model', DemoController
route '/ws', MyWSController
route '/', DemoIndex
exit
需要“plezi”
类MyWSController
def on_打开
#保存用户数据/注册用户/无论什么
@搜索=[]
结束
def on_消息数据
#从用户获取数据
data=JSON.parse数据
#清理数据,创建搜索参数。。。
除非数据['id'].match(/^\([\d]+\.\.[\d]+\)\z/),否则引发“注入尝试:{data}}}”
#保存搜索
@那么,是否有一个运行ajax调用的计时器?如果它是一个计时器,那么在用户机器上使用内存不会有副作用吗?有多种方法可以让JS等待去做事情。对于在计时器上重复执行某项操作,我会使用,它需要执行一个函数,并在重复该函数之前等待一个以毫秒为单位的间隔。执行的函数是任意的,但在您的情况下,它将是一个进行AJAX调用的函数。它使用了一些内存,但不是很大的内存量,因为它的大部分操作只是检查间隔是否已过,这不是一个很大的操作,并且您提供给它的函数在此之前不会被调用。谢谢-我将围绕这一点来玩,看看会发生什么。谢谢你的指导,没问题。如果这回答了您的问题,您应该将其标记为答案,以便其他人知道它已完成。另外,我做了一些小的研究来确认setInterval实际上并没有占用太多内存。Chrome的时间轴模式显然有一个小怪癖,它报告占用的内存比实际占用的内存多,但事实上,如果你没有运行大量的实例,这是一件非常小的事情。