Ruby: Sending string over TCP Socket

730 Views Asked by At

I'm pretty new to Ruby, having decided to try my hand with another programming language. I have been trying to get to grips with sockets, which is an area I'm not too familiar with in general. I have created a basic 'game' that allows a player to move his icon around the screen, however, I am trying to make this into something that could be multiplayer using TCP Sockets.

At the moment, when a player launches the game as a host, it creates a server. If the player starts a game as a client, it connects to the server. Currently, it only works on the same machine, but the connection has been established successfully, and when connecting as a client, the server creates a username, sends this back to the client, which then uses it to create a player.

The problem comes when i try to communicate between the server and the client, the messages appear to be sending from server to client, but only partially, and it appears they are largely truncated at either the beginning or end.

If anyone could advice on what is causing this, it would be greatly appreciated. I am using Ruby with Gosu and Celluloid-IO.

SERVER CLASS

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 

CLIENT CLASS

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

Side note; There is also a Host class, which mimics the client class, only it calls the server. I am aware this is a terrible way to do things, i intend to fix it once i overcome the current issue.

Many thanks in advance

0

There are 0 best solutions below