0

私は Ruby にかなり慣れていないので、別のプログラミング言語を試してみることにしました。私はソケットを理解しようとしてきましたが、これは私が一般的にあまり慣れていない分野です。プレーヤーがアイコンを画面上で移動できるようにする基本的な「ゲーム」を作成しましたが、これを TCP ソケットを使用してマルチプレーヤーにできるものにしようとしています。

現時点では、プレーヤーがホストとしてゲームを起動すると、サーバーが作成されます。プレーヤーがクライアントとしてゲームを開始すると、サーバーに接続します。現在、同じマシンでのみ機能しますが、接続は正常に確立されており、クライアントとして接続すると、サーバーはユーザー名を作成し、これをクライアントに送り返し、クライアントはそれを使用してプレーヤーを作成します。

サーバーとクライアントの間で通信しようとすると問題が発生します。メッセージはサーバーからクライアントに送信されているように見えますが、部分的にしか送信されておらず、最初または最後で大きく切り捨てられているようです。

これの原因について誰かがアドバイスできるなら、それは大歓迎です。Gosu と Celluloid-IO で Ruby を使用しています。

サーバークラス

require 'src/Game.rb'
require 'celluloid/io'

class Server
  include Celluloid::IO
  finalizer:shutdown
  def initialize
    puts ("server init")
    #super
    @playersConnected = Array.new
    @actors = Array.new
    @server = TCPServer.new("0.0.0.0", 28888)
    #@server.open(8088)
    puts @server
    async.run

  end

  def run
    loop {
      async.handle_connection @server.accept

    }
  end

  def readMessage(socket, player)
    msg = socket.recv(30)
    data = msg.split"|"

    @playersConnected.each do |p|
      if p.getUser() == player
        p.setX(data[1])
        p.setY(data[2])
      end
      #puts "END"
    end
  end

  def handle_connection(socket)
    _, port, host = socket.peeraddr
    user = "#{host}:#{port}"
    puts "#{user} has joined the game"
    @playersConnected.push(Player.new(user))
    socket.send "#{user}", 0
    #socket.send "#{Player}|#{user}", 0
    #socket.send "#{port}", 0
    puts "PLAYER LIST"
    @playersConnected.each do |player|
      puts player
    end
    Thread.new{
      loop{
        readMessage(socket, user)
        #divide message
        #find array index
        #update character position in array
      }
    }
    Thread.new{
      loop{
        @playersConnected.each do |p|
          msg = p.getUser() + "|" + "#{p.getX}" + "|" + "#{p.getY}" 
          socket.send(msg, 0)
        end
      }
    }
  end

  Server.new

end 

クライアントクラス

require 'src/Game.rb'

class Client < Game
  #finalizer :shutdown
  def initialize
    super
    @socket = TCPSocket.new("localhost", 28888)
    #188.222.55.241

    while @player.nil?
      @player = Player.new(@socket.recv(1024))
      puts @player
      puts @player.getUser()
      @player.warp(0, 0)
      pulse
    end
  end

  def pulse
    Thread.new{
      loop{
        msg = @player.getUser() + "|" + "#{@player.getX()}" + "|" + "#{@player.getY()}"
        @socket.write(msg)
      }

    }
    Thread.new{
      loop{
        msg = @socket.recv(1024)
        data = msg.split"|"
        puts data[0]
        match = false
        @players.each do |player|
          if player.getUser() == data[0]
            puts "MATCHX"
            player.setX(data[1])
            player.setY(data[2])
            match = true
          end
          if match == false
            p = Player.new(data[0])
            #p.warp(data[1],data[2])
            @players.push(p)
          end
        end
        puts "end"
      }
    }
  end

  Client.new.show

end

サイドノート; また、クライアント クラスを模倣する Host クラスもありますが、それはサーバーを呼び出すだけです。私はこれが物事を行うためのひどい方法であることを認識しています.現在の問題を克服したら修正するつもりです.

よろしくお願いします

4

0 に答える 0