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

      

+3


source to share


1 answer


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

      

+3


source







All Articles