0

我正在尝试使用 EventManager 在 ruby​​ 中构建聊天服务器。不用说,我是 Ruby 的新手,对我遇到的当前错误感到有点不知所措,因为我不知道这意味着什么,并且搜索不会返回任何有价值的东西。这是一些物流-

(我只实现了登录和注册,所以我只包括那些..)用户可以输入 - 注册用户名密码 - 注册用户登录用户名密码 - 登录用户

我正在接收用户发送的数据字符串,将其拆分为一个名为 msg 的数组,然后根据 msg[0] 对数据进行操作(作为它的命令,如 REGISTER、LOGIN 等)

这是我的代码,所有代码都包含在一个文件 chatserver.rb 中(解释如下):

require 'rubygems'
require 'eventmachine'

class Server
  attr_accessor :clients, :channels, :userCreds, :userChannels

  def initialize
    @clients     = [] #list of clients connected e.g. [192.168.1.2, 192.168.1.3]
    @users       = {} #list of users 'logged in' e.g. [tom, sam, jerry]
    @channels    = [] #list of channels          e.g. [a, b, c]
    @userCreds   = {} #user credentials hash     e.g. { tom: password1, sam: password2, etc }
    @userChanels = {} #users and their channels  e.g. { tom: a, sam: a, jerry: b }
  end

  def start
    @signature = EventMachine.start_server("127.0.0.1", 3200, Client) do |con|
      con.server = self
    end
  end

  def stop
    EventMachine.stop_server(@signature)

    unless wait_for_connections_and_stop
      EventMachine.add_periodic.timer(1) { wait_for_connections_and_stop }
    end
  end

  # Does the username already exist?  
  def has_username?(name)
    @userCreds.has_key?(name)
  end

  # Is the user already logged in?
  def logged_in?(name)
    if @users[name] == 1
      true
    else
      false
    end
  end

  # Did the user enter the correct pwd?
  def correct_pass?(pass)
    if @userCreds[name] == pass
      true
    else
      false
    end
  end

  private

    def wait_for_connections_and_stop
      if @clients.empty?
        EventMachine.stop
        true
      else
        puts "Waiting for #{@clients.size} client(s) to stop"
        false
      end
    end
end

class Connection < EventMachine::Connection
  attr_accessor :server, :name, :msg

  def initialize
    @name = nil
    @msg = []
  end

  # First thing the user sees when they connect to the server.
  def post_init
    send_data("Welcome to the lobby.\nRegister or Login with REGISTER/LOGIN username password\nOr try HELP if you get stuck!")
  end

  # Start parsing incoming data
  def receive_data(data)
    data.strip!
    msg = data.split("") #split data by spaces and throw it in array msg[]
    if data.empty? #the user entered nothing?
      send_data("You didn't type anything! Try HELP.")
      return
    elsif msg[0] == "REGISTER"
      handle_register(msg) #send msg to handle_register method
    else
      hanlde_login(msg)    #send msg to handle_login method
    end
  end

  def unbind
    @server.clients.each { |client| client.send_data("#{@name} has just left") }
    puts("#{@name} has just left") 
    @server.clients.delete(self)
  end

  private

    def handle_register(msg)
      if @server.has_username? msg[1] #user trying to register with a name that already exists?
        send_data("That username is already taken! Choose another or login.")
        return
      else
        @name = msg[1] #set name to username
        @userCreds[name] = msg[2] #add username and password to user credentials hash
        send_data("OK")  #send user OK message
      end
    end

end

EventMachine::run do
  s = Server.new
  s.start  #start server
  puts "Server listening"
end

哇,好吧,这只是开始,所以没那么复杂。由于我是 Ruby 新手,我有一种感觉,我只是没有声明变量或正确使用范围。这是错误输出:

chatserver.rb:16:in start': uninitialized constant Server::Client (NameError) from chatserver.rb:110:inblock in '来自/Users/meth/.rvm/gems/ruby-1.9.3-p392@rails3tutorial2ndEd/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in call' from /Users/meth/.rvm/gems/ruby-1.9.3-p392@rails3tutorial2ndEd/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in run_machine'来自 /Users/meth/.rvm/gems/ruby-1.9.3-p392@rails3tutorial2ndEd/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in run' from chatserver.rb:108:in<\main>'

忽略最后一行 main 中的斜线。第 108 行是最后一个函数 - EventMachine::run do 等。

任何帮助将不胜感激,如果我没有提供足够的信息,请告诉我。

4

1 回答 1

0

我认为,当您打电话时,EventMachine::start_server您需要将您的Connection班级作为处理程序。Client没有在任何地方定义。

于 2013-05-10T04:29:50.227 回答