How would I set up a simple unix socket server in crystal that could communicate with multiple clients?
I am trying to figure out how to implement UNIX sockets in crystal. I would like to be able to send a name to the server application and return it "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 am assuming that I can only have a loop that waits for standard input 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 something vital is missing here, but I can't seem to find the right things in the documentation to fill in the blanks. What are the connections between UNIXServer and UNIXSocket? If someone can show me a working example of what I'm trying to do, I'll be forever grateful.
Update: here's my solution
It turns out that using a UNIXServer and calling accept to create a socket solves my original problem. After I ran into the problem, all fibers were using the same socket, so the closure was closed. There is probably another solution, but it works for me. Thanks @ RX14 for 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
source to share
To accept an incoming connection, you need to use the UNIXServer#accept
or methods UNIXServer#accept?
.
# 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
source to share