ruby eventmachine:在Net :: telnet实例上执行EM.watch时出现的问题

时间:2012-06-05 19:34:42

标签: ruby websocket eventmachine

我正在尝试使用带有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,这个事件机器工作得非常好。以前有人有同样的问题吗?

1 个答案:

答案 0 :(得分:1)

错误in `attach_fd': can't convert Net::Telnet into Integer (TypeError)正在被引发,因为Eventmachine.watch()“registers a given file descriptor or IO object with the eventloop”和Net :: Telnet实例都不是这些。

根据Net :: Telnet documentation,Net :: Telnet实例的sock属性是指实例使用的套接字。所以你可以将它传递给EventMachine.watch()方法。