#!/usr/bin/env ruby # -*- coding: utf-8 -*- # EM Intro. - http://keijinsonyaban.blogspot.jp/2010/12/eventmachine.html # irb to EM - https://keyesberry.hatenadiary.org/entry/20110929/p1 # # Browser Settings: # Chrome: https://blog.hello-world.jp.net/node-js/1821/ require 'em-websocket' require 'json' require 'csv' PORT = 9124 # クイズよ # TOKEN = "jugemujugemugokonosurikire" TOKEN = "jugemu" QUIZ = "quiz.csv" QJSON = CSV.read(QUIZ, headers:true).collect{|row| p row.to_h} class QZ def jsonval(hash) JSON.generate(hash) end def sendinfo(client, msg) client.send(jsonval({info: msg})) end def initialize @client = Hash.new @currentQ = 0 end def handleMessage(client, msg) begin json = JSON.parse(msg) rescue p "GYAA" return # Simply ignore it end p json json.each do |key, val| STDERR.printf("JSON:IN Handling key=[[%s]]\n", key) if key=="mode" if val == TOKEN @client[client][:master] = true STDERR.printf("Client %s set to master\n", client) client.send(jsonval({q: QJSON})) end next else @client[client][key] = val STDERR.printf("Set %s of %s to %s\n", key, @client[client]["name"], val) end @client.each do |c, prop| isMaster = @client[c][:master] STDERR.printf("isMaster=%s\n", isMaster) if c == client # to packet sender if key == "getquiz" STDERR.printf("sent %s to %s\n", QJSON[@currentQ], @client[c][:name]) c.send(jsonval({setquiz: QJSON[@currentQ]})) else sendinfo(c, "送信完了") end else STDERR.printf("notClient key=%s val=%s\n", key, val) case key when "name" sendinfo(c, "#{val}さんが入室しました") when "setquiz" @currentQ = val.to_i c.send(jsonval({setquiz: QJSON[@currentQ]})) when "select" if isMaster v = { # クイズサーバのみに誰が何を選択したか送る "name" => @client[client]["name"], "choice" => val } c.send(jsonval({select: v})) end when "check", "result" if !isMaster c.send(jsonval({key => val})) end end end end end end def start print("No @client yet...") EM::WebSocket.start({:host => "0.0.0.0", :port => PORT}) do |ws_conn| # クライアント接続がある度にその情報が ws_conn に入って来る ws_conn.onopen do # そのクライアントが接続開始してきたとき @client[ws_conn] = {openat: Time.now} sendinfo(ws_conn, "うっす!") printf("%d guest(s)\n", @client.length) end ws_conn.onmessage do |message| # クライアントから文字列が来たとき handleMessage(ws_conn, message) end ws_conn.onclose do # クライアントが切断したとき @client.delete(ws_conn) # そのクライアントを集合から削除 # p "bye"+ws_conn.inspect printf("%d GUEST(s)\n", @client.length) end EM::defer do # 共通で実行するスレッド # Thread.new do のほうがいいかも puts "..captured!" loop do print("Enter message for all @client: ") line = gets puts("Sending") @client.each{|conn| conn.send(line.chomp) } end end end end end QZ.new.start