Saturday 19 January 2019

Sockets - Ruby to Ruby - Starting Ruby Sockets programming with a simple calculator app

Like most great languages Ruby has the ability open and read/write from/to sockets, a TCP/IP programming protocol lower than HTTP. This month I have been demonstrating Excel VBA acting as one endpoint for a Sockets connection (specifically communicating to Redis). That Excel VBA can talk to sockets means we can get VBA to talk to Ruby. I will write an VBA to Ruby article shortly but first it is better to write a Ruby to Ruby sockets application to see what is involved.

The application will be a simple calculator app. The client will pass a string such as "2*7" to the server, the server will parse the string into operands and operator, calculate the result and return the answer.

Ruby Development Preparation

I've not done any serious Ruby development. So I give a section which highlights some prep work to get an Ruby development environment up and running. First, a tip to see if Ruby is already installed. After that I will give some screenshots of the Ruby extensions that I installed into Microsoft Visual Studio Code.

How do you know if Ruby is Installed?

So I thought I had installed Ruby some time ago. So just taking my Ruby installation for a spin from the command line...

N:\>ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x64-mingw32]

N:\>gem --version
2.7.6

N:\>mkdir ruby

N:\>cd ruby

N:\ruby>mkdir socketsServer

N:\ruby>cd socketsServer

N:\ruby\socketsServer>notepad "RubyHelloWorld.rb"

N:\ruby\socketsServer>type "RubyHelloWorld.rb"
puts "Hello World"

N:\ruby\socketsServer>ruby  "RubyHelloWorld.rb"
Hello World

This looks installed. Also above I have created some directories because I want to open a folder using Visual Studio Code.

Installing Visual Studio Code Ruby Extensions

I know Visual Studio Code is multi-language in that there is an ecosystem of language extensions. So I was confident in picking VS Code for my source code editor. I just needed some extensions. First up was to find from the list of extensions. To view extensions go to menu View->Extensions (that's intuitive!) and then select this one...

Once installed the extension's page should look like this ...

Then during development I wanted my code to be indented for me so I chose this Ruby Formatter extensions as well one as well.

Sockets Calculator

So I started with the code from this great article Socket Programming in Ruby – Code Like A Girl but the code only sends text messages to and fro. I wanted to up the functionality a little so I wrote a calculator app.

socketServer.rb

So here is the source code for the socketServer.rb

#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd

require "socket"

puts "Starting the Server..................."
server = TCPServer.open(3000) # Server would listen on port 3000
loop { # Servers run forever
  client_connection = server.accept # Establish client connect connection
  begin
    clientText = client_connection.gets.chomp
    puts "clientText:" + clientText
    resp = ""

    #With thanks to https://regex101.com/
    parsed = /(\d+)\s*(\+|\*|-|\/)\s*(\d+)/.match(clientText)
    if parsed
      arg0 = Float(parsed[1])
      op = parsed[2]
      arg1 = Float(parsed[3])
      if op == "+"
        resp = arg0 + arg1
      elsif op == "-"
        resp = arg0 - arg1
      elsif op == "*"
        resp = arg0 * arg1
      elsif op == "/"
        resp = arg0 / arg1
      end
    else
      resp = "does not look calculable"
    end

    client_connection.puts("#{clientText}" + " = " + "#{resp}") # Send the answer to the client
    client_connection.puts("Closing the connection with #{client_connection}")
  rescue Exception => getException
    puts "#{getException}"
  end
  client_connection.close      # Disconnect from the client
}

socketClient.rb

So here is the source code for the socketClient.rb

#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd
require "socket"

while sum = $stdin.gets.chomp # Read lines from the socket
  socket = TCPSocket.open("localhost", 3000)

  #puts "Starting the Client..................."

  socket.puts sum
  while message = socket.gets # Read lines from the socket
    puts message.chomp
  end
  socket.close                    # Close the socket
end

#puts "Closing the Client..................."

Running the program

So run each program in their own console and in the client and then start typing sums ...

Let regular Expressions do the heavy lifting

If you do decide to write a sockets application then you have a lot of string parsing ahead of you. I'd recommend regular expressions. I have found a superb online regular expressions tester, regex101.com. This site gives not just testing panel and quick reference but also it gives an explanation which is a feature that makes this website by far better than any other I have come across. Enjoy!

No comments:

Post a Comment