I am trying to use websocket on Thin server. The following code is an attempt to run a clock that updates the time on the web page every 0.1 second.
PAGE
is the content of the initial page to be rendered.serve
and session
methods.websocket
method.tick_every
is a utility function that calls a block at the right timing for every time interval given.Code:
require "rack"
require "thin"
require "em-websocket"
PAGE = <<_
<html>
<body><div id="output"></div></body>
<script>
window.addEventListener("load", init, false);
function init(){
websocket = new WebSocket("ws://localhost:4000");
websocket.onmessage = function(evt){
document.getElementById("output").innerHTML = evt.data;
};
}
</script>
<div id="output"></div>
</html>
_
def serve
Rack::Handler::Thin.run(Rack::Builder.new do
map("/"){run(->env{session(env)})}
end, Port: 3000)
end
def session env
websocket(env["SERVER_NAME"])
[200, {}, [PAGE]]
end
def websocket host
EM.run do
EM::WebSocket.run(host: host, port: 4000) do |ws|
ws.onopen do
tick_every(0.1){|t| ws.send "The time now since epoch in sec is #{t}"}
end
end
end
end
def tick_every sec, &pr
Thread.new do loop do
t = Time.now.to_f # present time in micro seconds
frac = t.modulo(sec.to_f) # fractional (decimal) part of it w.r.t. `sec`
pr.call((t - frac).round(6)) # calls the block, passing the present time with precision of `sec`
sleep(sec - frac) # wait for the next flat `sec`
end end
end
serve
When I run this and open the webpage at localhost:3000
, websocket
returns an error message in the console:
!! Unexpected error while processing request: no acceptor (port is in use or requires root privileges)
and shows the initial time on the web page, but does not update it for thirty seconds (not sure, but this seems constant, which may have some meaning), and after that, it starts to update the clock every 0.1 second.
The problem turned out to be that, the browser was requesting a favicon, which I had not set up. Probably, it waited till timeout, which is perhaps thirty seconds, then started to work after that. The error came from favicon request.