Websockets允许您完全避免轮询,只要您控制所有事件(或Sub/Pub到外部事件)。
至于您的示例,如果您控制写入文件的操作,则可以调用websocket“广播”或“发布”此事件。
通过这种方式,您完全避免了轮询。
由于我不喜欢使用PHP(无意冒犯,我只是已经厌倦了它),这里有一个快速的Ruby示例,使用Plezi实时框架。
在这个例子中,我们使用一个简单的touch
方法来执行一个动作。虽然我并没有真正触摸文件,但您可以体验到API的使用使我能够控制事件并向其他用户广播-没有涉及轮询。
如果我订阅外部事件,情况也是如此。
要运行此示例,请使用[sudo] gem install plezi
安装plezi
gem(取决于您是否需要sudo
和您的系统),并使用irb
命令从终端打开IRB终端。然后粘贴以下代码:
需要 'plezi'
class RootController
def index
%{<html><head>
<script>
var websocket = NaN;
function connect() { websocket = new WebSocket( (window.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) ) + "/" ); }
function init()
{
connect()
websocket.onopen = function(evt) { WriteMessage("(Connected and waiting for messages)", "connection") };
websocket.onclose = function(evt) { WriteMessage("(Disconnected. messages will be lost)", "connection");connect(); };
websocket.onmessage = function(evt) {
WriteMessage(evt.data, "");
};
websocket.onerror = function(evt) { WriteMessage(evt.data, 'error'); };
}
function WriteMessage( message, message_type )
{
if (!message_type) message_type = 'received'
var msg = document.createElement("p");
msg.className = message_type;
msg.innerHTML = message;
document.getElementById("output").appendChild(msg);
}
function Send(message)
{
WriteMessage(message, 'sent');
websocket.send(message);
}
window.addEventListener("load", init, false);
</script></head>
<body>
<p>Messages should show up here:</p>
<div id=output></div>
</body>
</html>
}
end
def touch
FileController.touch
"You Touched the file, a message should be sent to the web browser windows."
end
def on_open
subscribe :file_notifications
end
def on_message data
end
def self.push_update_event
publish :file_notifications, "The file was updated."
"Touched - Ok".freeze
end
end
class FileController
def self.touch
puts "INFO: A file should be touched.. you can do whatever you feel like here..."
RootController.push_update_event
end
end
class APIController
def touched
RootController.push_update_event
end
end
Plezi.route '/', RootController
Plezi.route '/api', APIController
exit # the server will start once you exit the irb terminal
现在在两个不同的浏览器窗口中访问:
或者,您甚至可以使用外部脚本“编辑文件”(虚拟),然后访问http://localhost:3000/api/touched以通知所有用户该操作(此处未显示身份验证,但应添加)。