我正在尝试使用带有 ruby eventmachine 的 HTML5 websocket 编写一个 web telnet 客户端。但是当 EM.watch 尝试监视新创建的 Net::Telnet 实例时它失败了。以下是服务器端和客户端代码:
服务器端:
require 'em-websocket'
require "debugger"
require 'net/telnet'
class Foo < EM::Connection
def initialize(websocket)
@websocket = websocket
@alltext = ""
end
def notify_readable
header= @io.recvfrom(2000)[0].chomp
header2 = header.to_s.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => "s")
if header2.length ==1
@alltext = @alltext + header2
else
@alltext.each_line do |x|
$stdout.puts x
@websocket.send x
end
@alltext = ""
header2.to_s.each_line do |y|
$stdout.puts y
@websocket.send y
end
end
if header == "\r\n"
fd = detach
end
rescue EOFError
detach
end
def unbind
EM.next_tick do
end
puts "close the socket:" + @io.to_s
end
end
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8090) do |ws|
ws.onopen {
puts "Web socket is opened"
ws.send "terminal to the node"
nodeSocket = Net::Telnet::new("Host" => "10.4.0.50","Timeout" => 10,"Prompt" => /login/ )
puts nodeSocket
nodeSocket.cmd("username") { |c| print c}
nodeSocket.cmd("password") { |c| print c}
EM.run{
$conn = EM.watch nodeSocket,Foo,ws
$conn.notify_readable = true
}
}
ws.onmessage { |msg|
puts msg
ws.send msg
}
ws.onclose {
puts "WebSocket closed"
}
end
克林特方面:
require 'eventmachine'
require 'em-http-request'
EventMachine.run {
http = EventMachine::HttpRequest.new("ws://localhost:8090").get :timeout => 0
http.errback { puts "oops" }
http.callback {
puts "WebSocket connected!"
http.send("Hello client")
}
http.stream { |msg|
puts "Recieved: #{msg}"
}
}
服务器端日志
C:\Ruby193\bin>ruby websocketserver12.rb
Web socket is opened
#<Net::Telnet:0xf976e0>
------------------Welcome to syseng1--------------------
This machine is the Server
--------------------------------------------------------
Ubuntu 8.04.3 LTS
syseng1 login: username
Password:
Last login: Tue Jun 5 15:05:00 EDT 2012 from 358.ystems.com on pts/0
Linux syseng1 2.6.24-24-generic #1 SMP Fri Jul 24 22:46:06 UTC 2009 i686
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
You have mail.
←[01;32musername@syseng1 ←[01;34m~ $ ←[00mWebSocket closed
C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86- mingw32/lib/eventmachine.rb:735:in `attach_fd': can't convert Net::Telnet into Integer (TypeError)
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86-mingw32/lib/eventmachine.rb:735:in `attach_io'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86-mingw32/lib/eventmachine.rb:708:in `watch'
from websocketserver12.rb:57:in `block (3 levels) in <main>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86-mingw32/lib/eventmachine.rb:163:in `call'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86-mingw32/lib/eventmachine.rb:163:in `run'
from websocketserver12.rb:56:in `block (2 levels) in <main>'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/connection.rb:20:in `call'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/connection.rb:20:in `trigger_on_open'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/handler.rb:18:in `run'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/connection.rb:114:in `dispatch'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/connection.rb:71:in `receive_data'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86-mingw32/lib/eventmachine.rb:179:in `run_machine'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/eventmachine-1.0.0.beta.4.1-x86-mingw32/lib/eventmachine.rb:179:in `run'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/em-websocket-0.3.6/lib/em-websocket/websocket.rb:9:in `start'
from websocketserver12.rb:47:in `<main>'
看起来 EM.watch 无法观看 Net::Telnet::new 实例,因为它无法将文件句柄转换为 lib 中某处的 Integer。我用 EM.watch 尝试了同样的事情来观察 TCPSocket,这个事件机器工作得很好。以前有人有同样的问题吗?