Reputation: 895
I'm trying to figure out how to implement unix sockets in crystal. I'd like to be able to send a name to a server app and have it return "Hello #{name}."
#server.cr
require "socket"
loop do
spawn do
server = UNIXServer.new("/tmp/myapp.sock")
name = server.gets
server.puts "Hello #{name}."
end
end
On the client I assume I could just have a loop that waits for standard in and sends it over the socket.
#client.cr
require "socket"
loop do
sock = UNIXSocket.new("/tmp/myapp.sock")
puts "What is your name?\n: "
name = gets
sock.puts name
puts sock.gets
sock.close
end
Obviously I'm missing something vital here, but I can't seem to find the right things in the documentation to fill in the blanks. What is the connections between UNIXServer and UNIXSocket? If someone could show me a working example of what I'm trying to do I would be forever grateful.
It turns out that using UNIXServer and calling accept on it to create a socket solved my initial issue. After than I ran into the issue that all of the Fibers were using the same socket so closing one closed all of them. There's probably another solution but this works for me. Thanks to @RX14 for all the help.
#server.cr
require "socket"
server = UNIXServer.new("/tmp/cr.sock")
while sock = server.accept
proc = ->(sock : UNIXSocket) do
spawn do
name = sock.gets
unless name == "q"
puts name
sock.puts "Hello #{name}."
sock.close
else
server.close
exit
end
end
end
proc.call(sock)
end
#client.cr
require "socket"
UNIXSocket.open("/tmp/cr.sock") do |sock|
puts "What is your name?"
name = gets
sock.puts name
puts sock.gets
sock.close
end
Upvotes: 3
Views: 282
Reputation: 3175
You need to use either UNIXServer#accept
or UNIXServer#accept?
methods to accept a incoming connection.
# server.cr
require "socket"
def handle_connection(socket)
name = socket.gets
socket.puts "Hello #{name}."
end
server = UNIXServer.new("/tmp/myapp.sock")
while socket = server.accept
spawn handle_connection(socket)
end
# client.cr
require "socket"
UNIXSocket.open("/tmp/myapp.sock") do |sock|
puts "What is your name?\n: "
name = STDIN.gets
sock.puts name
puts sock.gets
end
Upvotes: 3