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