Насколько я могу судить, ни один из них не работает.
Это неверно; с твоим клиентом все в порядке. Ваш сервер, однако, не является.
Ваш код клиента пытается связаться по HTTP. Ничто в коде вашего сервера не реализует семантику HTTP.
Я верю, что с вами происходит следующее: клиент подключается. Сервер говорит «Привет, мир» и закрывает соединение, как только Клиент начинает отправлять заголовок. Клиент обнаруживает, что он говорит со стеной, и поскольку передача заголовка является обязательной, он сдается с ошибкой.
Это означает, что вы должны по крайней мере позволить клиенту произнести заголовок HTTP, прежде чем закрыть соединение , Вы также должны отправить заголовок ответа HTTP, иначе клиент HTTP окажется в замешательстве.
Вот минимальный код сервера, который мне подходит:
#!/usr/bin/ruby -w
require 'socket'
begin
server = UNIXServer.new('/tmp/socket-simple')
socket = server.accept
# read the headers, at least
while socket.gets.chomp != ""
end
# send the HTTP response header
socket.puts "HTTP/1.1 200 OK"
socket.puts "Content-Type: text/plain"
socket.puts
# only now can you send a response body
socket.puts 'Hello world'
socket.close
server.close
ensure
File.unlink('/tmp/socket-simple')
end
Это очень упрощенно c хотя и не очень корректно (например, при POST произойдет сбой и многие другие детали). Возможно, вам лучше использовать Rack, который уже знает, как правильно говорить по HTTP. Rack может использовать сокет UNIX, если вы указали путь в аргументе Host
. Например:
require 'rack'
require 'thin'
class TestApp
def call(env)
[200, {"Content-Type" => "text/plain"}, ["Hello World!"]]
end
end
app = TestApp.new
Rack::Handler.get('thin').run(app, Host: '/tmp/socket-simple')
РЕДАКТИРОВАТЬ: Вот версия без зависимости с использованием WEBrick. WEBrick не поддерживает UNIX сокетов напрямую, поэтому мы должны предотвратить попытки его прослушивания и вставить наш собственный слушатель:
require 'webrick'
require 'socket'
begin
UNIXServer.open('/tmp/socket-simple') do |ssocket|
server = WEBrick::HTTPServer.new(DoNotListen: true)
server.listeners << ssocket
server.mount_proc '/' do |req, res|
res.set_content_type('text/plain')
res.body = "Hello, world!"
end
server.start
end
ensure
File.unlink('/tmp/socket-simple')
end