2009年7月 2日

[ruby-list:46139] Re: 足し算ゲームサーバー

永井@知能.九工大です.

From: 牛坂 博則 <ushizaka@xxxxx>
Subject: [ruby-list:46136] 足し算ゲームサーバー
Date: Thu, 2 Jul 2009 13:19:44 +0900
Message-ID: <4A4C3533.3050502@xxxxx>
> 牛坂ともうします。"ruby アプリケーションプログラム"を勉強中です。このな
> かの5.6.5章の1対1の非同期通信のところをいま取り組んでいます。


その部分の著者です.

> serverを立
> ち上げて接続しても、途中で止まってしまいます。ちなみにwindows XP上でコマ
> ンドプロンプトより実行しています。

原因は,なかむら(う)さんがおっしゃった通りだと思います.
執筆時点では Linux 環境でやってたので,
当時は Win 環境でのその問題に気付いていませんでした.
ごめんんさい.

それだけでは何なので,応急処置的な対策を少々.

同書を使っての勉強中であれば,
もしかすると Ruby/Tk も動く環境になさっているかもしれません.
そうであるなら,コマンドプロンプトの代わりに
Ruby/Tk で作ったダミーのコンソールを使うことで
ある程度までは回避できると思います.

# コマンドプロンプト上での入力を使いませんので,
# thread 切替えをブロックしないはずです.

以下にソースを示します.
この DummyCons は手抜きで作成したものなので,細かい問題が多々存在する上,
クライアントスクリプトで使っていた print と gets にしか対応していません.
$stdin, $stdout, $stderr に設定できる程度の汎用的なものにするには
もうちょっとまじめに頑張る必要があります.
-------------------------------------------
require 'tk'
class DummyCons
def initialize
@v = TkVariable.new
f = TkFrame.new.pack(:fill=>:x)
TkLabel.new(f, :text=>'>> ').pack(:side=>:left)
TkButton.new(f, :text=>'reset EOF',
:command=>proc{reset}).pack(:side=>:right)
@e = TkEntry.new(f).pack(:side=>:left, :fill=>:x, :expand=>true)
@t = TkText.new(:takefocus=>false).pack(:expand=>true, :fill=>:both)
@st = ""

@e.bind('Return'){
s = @e.value; @e.value = ""
@t.insert(:end, "#{s}\n")
@v.value = s
}

eof_ev = TkVirtualEvent.new('Control-z','Control-d','Destroy')
@e.bind(eof_ev){@st = false; @v.value = ""}

@e.focus

@th = Thread.new{Tk.mainloop}
end

def print(s)
begin
@t.insert(:end, s)
@t.see(:end)
rescue
# ignore error
end
end

def gets
@v.wait if @st
(@st)? @v.value: nil
end

def reset
if @th.status
@st = true
self
else
raise RuntimeError, "#{self.inspect} is already destroyed"
end
end
end
cons = DummyCons.new

# ↑ここまでがダミーコンソール
#
# ↓ここからがクライアントプログラムをちょっとだけいじったもの
# "print msg" を "cons.print msg" に,
# "STDIN.gets" を "cons.gets" に変更している

require 'socket'

#STDOUT.sync = true
host = if ARGV[0] then ARGV[0] else 'localhost' end
port = if ARGV[1] then ARGV[1] else 12345 end
socket = TCPSocket.open(host, port)

th_get = Thread.start {
while msg = socket.gets
# print msg
cons.print msg
end
}

th_ans = Thread.start {
# while msg = STDIN.gets
while msg = cons.gets
socket.write msg
end
#sock.shutdown(1)
}

th_get.join
th_ans.exit if th_ans.alive?
socket.close
-------------------------------------------
--
永井 秀利 (nagai@xxxxx)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


投稿者 xml-rpc : 2009年7月 2日 17:18
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/86329
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。