#!/usr/bin/env ruby # -*- coding: utf-8 -*- # EM Intro. - http://keijinsonyaban.blogspot.jp/2010/12/eventmachine.html require 'em-websocket' require 'json' require 'csv' PORT = 8804 clients = {} ans = {} readiness = {} <<<<<<< HEAD @musiclist = ["UFO.mp3"] ======= @musiclist = CSV.read("music.csv", :headers=>true) >>>>>>> cf891c544eeca563d1b75fdc33107a9a3a55512d @musicpos = 0 @rediness = {} @admin = nil @stoptime = nil print("No clients yet...") EM::WebSocket.start({:host => "0.0.0.0", :port => PORT}) do |ws_conn| ws_conn.onopen do # p "hello"+ws_conn.inspect clients[ws_conn] = a = {} # Start from NO NAME printf("%d guest(s)\n", clients.keys.length) a["ping"] = Time.now.to_f ws_conn.send("PING") end ws_conn.onmessage do |message| jv = JSON.parse(message) team, st = jv['team'], jv['state'] if team > '' clients[ws_conn]["name"] = team if "PUSH" == st # /PUSH: ([0-9.]+)/ =~ st ans[team] ||= [] ans[team] << (jv['curtime']||9999) if @stoptime @stoptime = [@stoptime, jv['curtime']].min else @stoptime = jv['curtime'] end STDERR.printf("Stopped at client %.3fs\n", @stoptime) if @stoptime p ans end end # clients.each{|conn| conn.send(resp) } if team=="admin" @admin = ws_conn case st when "prev", "next" @musicpos += (st=="prev" ? -1 : 1) @musicpos = [[0, @musicpos].max, @musiclist.length-1].min ans = {}; @rediness = {}; msg = sprintf("src=%s", @musiclist[@musicpos]["ファイル名"]) m = @musiclist[@musicpos] jsn = {url: m["ファイル名"], hint: m["ヒント"]} p JSON.generate(jsn) msg = sprintf("src=%s", JSON.generate(jsn)) @stoptime = nil when "RESET" ans = {}; msg="RESET" @stoptime = nil when "PLAY", "STOP" # /STOP: ([0-9.]+)/ if st=="STOP" @stoptime = jv['curtime'] STDERR.printf("stoptime saved = %f\n", @stoptime) end maxdelay = clients.keys.collect{|x|clients[x]["delay"]}.max clients.keys.each{|c| d = maxdelay-clients[c]["delay"] c.send("#{st}: #{d} #{@stoptime||0}") } msg="" when "SABI" clm = @musiclist[@musicpos]["サビ秒数"]||10 clients.keys.each{|c| c.send("PLAY: 0 #{clm}") # 仮に10秒とする 変えてね! } msg="" else msg = ans.keys.select{|x|x!="admin"}.join(", ") end #if false && /prev|next/ =~ st # STDERR.printf("Set pos @ %d -> %s\n", @musicpos, @musiclist[@musicpos]) # @rediness = {} # clients.keys.each{|conn| # conn.send(msg) # if conn!=ws_conn; # } if msg>"" clients.keys.each{|conn| conn.send(msg)} end end p ans resp = ans.keys.select{|x|x!="admin"}.sort_by{|k| ans[k].min}.join(", ") p ans.keys.select{|x|x!="admin"}.sort_by{|k| ans[k].min} case st when /PONG/i a = clients[ws_conn] a["pong"] = Time.now.to_f a["delay"] = a["pong"]-a["ping"] p clients.values.collect{|v| v['delay']}.join(", ") when /loading done/i @rediness[ws_conn] = true msg = "RESET" STDERR.printf("%d/%d\n", @rediness.keys.length, clients.keys.length) # clients.keys.each{|conn| conn.send("RESET")} @admin.send(sprintf("LOAD: %d/%d\n", @rediness.keys.length, clients.keys.length)) if @rediness.keys.length == clients.keys.length then clients.keys.each {|conn| if conn != @admin STDERR.puts("Sending RESET to #{conn}") conn.send("RESET") end } end end if /PLAY|STOP|RESET|loading/ !~ st clients.keys.each{|conn| conn.send(resp);} end end ws_conn.onclose do clients.delete(ws_conn) @rediness # p "bye"+ws_conn.inspect printf("%d GUEST(s)\n", clients.keys.length) end EM::defer do puts "..captured!" loop do print("Hit Return to Reset client messages...") line = gets puts("Resetting") clients.keys.each{|conn| conn.send("Ready..") } ans = {}; end end end