Skip to content

Instantly share code, notes, and snippets.

@shouhei
Last active March 29, 2018 10:53
Show Gist options
  • Save shouhei/c4989ed81460be51813eea1bc7fbec30 to your computer and use it in GitHub Desktop.
Save shouhei/c4989ed81460be51813eea1bc7fbec30 to your computer and use it in GitHub Desktop.
Multi process echo server
require 'socket'
def main(host, port)
Process.setproctitle "ruby_init"
s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(port, host)
s.bind(sockaddr)
s.listen(5)
Process.fork do
Process.setproctitle "ruby_server"
loop do
conn, addr = s.accept
pid = Process.fork do
Process.setproctitle "ruby_child"
loop do
mesg, sockaddr = conn.recvfrom(64)
break if mesg.empty?
conn.send(mesg, 0, conn.getsockname)
end
conn.close && exit
end
Process.detach pid
end
end
end
main("0.0.0.0", 8080)
require 'socket'
# 名前空間の関係で全く動かないのでテストのサンプル
class ResponseGenerator
def initialize(mesg)
@mesg = mesg
end
def response(html)
"HTTP/1.0 200 OK
Content-Type: text/html
Server: my-rubvy
Content-Length: " + html.bytesize.to_s + "
" + html + "\n"
end
end
def main(host, port)
Process.setproctitle "ruby_init"
s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(port, host)
s.bind(sockaddr)
s.listen(5)
Process.fork do
Process.setproctitle "ruby_server"
loop do
conn, addr = s.accept
pid = Process.fork do
Process.setproctitle "ruby_child"
loop do
mesg, sockaddr = conn.recvfrom(64)
break if mesg.empty?
r = new ResponseGenerator(mesg)
conn.send(r.response(), 0, conn.getsockname)
conn.close
break
end
conn.close && exit
end
Process.detach pid
end
end
end
main("0.0.0.0", 8080)
require 'minitest/autorun'
require './http'
class ResponseGeneratorTest < Minitest::Test
def test_generate_response
expexted = "HTTP/1.0 200 OK
Content-Type: text/html
Server: my-rubvy
Content-Length: 23
<h1>hello world!!!</h1>
"
actual = ResponseGenerator.new("hogehoge").response("<h1>hello world!!!</h1>")
assert_equal expexted, actual
end
def test_generate_response2
expexted = "HTTP/1.0 200 OK
Content-Type: text/html
Server: my-rubvy
Content-Length: 17
<h2>piyo piyo</2>
"
actual = ResponseGenerator.new("hogehoge").response("<h2>piyo piyo</2>")
assert_equal expexted, actual
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment