I'm a complete beginner to rails and web development in general. I'm looking to implement a ruby TCPSocket server in a rails application which will recieve data from the client over a raw tcp connection without the http protocol. The app will have other functionality which will be handled by rails. Is this possible? For example this is a simple server that i can run on my computer:
require 'socket'
server = TCPServer.new 3490
puts "waiting for connection"
client = server.accept
puts "client found"
while str=client.recv(100);
val=str.unpack("H*")
temp=val.join('').gsub('0','').to_i
#application specific code below
if temp<100
temp=temp*10
end
print "Temperature: "
puts temp*0.125
end
How can I implement this in a rails app? Any kind of suggestions would be appreciated.
TCP sockets are used for communication between a server and a client process. The server's code runs first, which opens a port and listens for incoming connection requests from clients. Once a client connects to the same (server) port, the client or server may send a message.
A socket programming interface provides the routines required for interprocess communication between applications, either on the local system or spread in a distributed, TCP/IP based network environment. Once a peer-to-peer connection is established, a socket descriptor is used to uniquely identify the connection.
Rails is basically Rack application, as per Rails documentation,
Rails.application is the primary Rack application object of a Rails application. Any Rack compliant web server should be using Rails.application object to serve a Rails application.
Since Rack primarily wraps HTTP requests and responses, one may not be able to build pure TCP IP socket based interaction with Rails Server.
However, you may want to have look at Action Cable, a new addition to Rails 5 - which integrates websockets
with Rails application. As per Wikipedia,
The WebSocket Protocol is an independent TCP-based protocol. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade request.
How to extract Action Cable to work with non browser clients may be tricky given that Rails is primarily a web application framework.
You can make the TCP Sockets in the rails application and to handle multiple request at the same time implement threading. For communication use either the text format or JSON.
link: https://ruby-doc.org/stdlib-2.4.0/libdoc/socket/rdoc/TCPServer.html
First create a task inside the lib directory by following command:
rails g task socketing start
This will create a file inside the app/lib/tasks/ with name socketing.rake and inside it a task "start" would be created. Now Edit the file as:
task start: :environment do
require 'socket'
puts "Started TCP Server"
server = TCPServer.new 53492 # Server bound to port 53492
loop do
Thread.start(server.accept) do |client|
p "Inside Task"
string = client.recv(1000).chomp ## Request Data received at the socket port
result = JSON.parse(string)
p 'Bye'
client.puts result.to_s
client.close
end
end
end
From Terminal run socket from project folder as:
rails socketing:start
or run as demon with nohup
Now the application will start listening at port 53492 in TCP and start sending responses to requests.
Sample Request in JSON format:
echo '{"password" : "12345678" , "name" : "[email protected]"}' | nc localhost 53492
or create the socket using a module and require it inside the controller action in that case create a new module inside the app/lib/socketing.rb
with the following code:
require 'socket'
puts "Started TCP Server"
server = TCPServer.new 53492 # Server bound to port 53492
loop do
Thread.start(server.accept) do |client|
p "Inside Task"
string = client.recv(1000).chomp ## Request Data received at the socket port
result = JSON.parse(string)
p 'Bye'
client.puts result.to_s
client.close
end
end
and define the routing to that controller:
get '/socket', to: 'webhook#socket', as: 'socket'
Give a call to that route from browser and the TCP server would be started and start sending the responses to the requests and you can check the logs also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With