Ruby TCP/IP通信如何處理并發(fā)

小樊
82
2024-11-03 03:49:44
欄目: 編程語言

在Ruby中處理TCP/IP通信并發(fā)可以通過多種方式實(shí)現(xiàn),包括使用線程、異步IO和事件驅(qū)動(dòng)庫等。下面是一些常見的方法:

1. 使用線程(Threads)

線程是Ruby中最基本的并發(fā)機(jī)制。你可以創(chuàng)建多個(gè)線程來同時(shí)處理多個(gè)TCP連接。

require 'socket'

server = TCPServer.new('localhost', 8080)

threads = []

server.each_connection do |client|
  threads << Thread.new do
    client.puts "Hello from thread #{Thread.current.object_id}"
    client.close
  end
end

threads.each(&:join)

2. 使用異步IO(Async IO)

Ruby的IO模塊提供了異步IO支持,可以使用IO.selectIO.wait來處理多個(gè)連接。

require 'socket'
require 'io/select'

server = TCPServer.new('localhost', 8080)

inputs = [server]
outputs = []

while inputs.any?
  readable, writable, exceptional = IO.select(inputs, outputs, inputs)

  readable.each do |sock|
    if sock == server
      client = server.accept
      inputs << client
      puts "New connection from #{client.peerhost}:#{client.peerport}"
    else
      data = sock.gets
      puts "Received: #{data}"
      outputs << sock
    end
  end

  writable.each do |sock|
    sock.puts "Message received"
  end

  exceptional.each do |sock|
    puts "Exception on #{sock.path}: #{sock.error}"
    inputs.delete(sock)
    sock.close
  end
end

3. 使用事件驅(qū)動(dòng)庫(Event-driven libraries)

Ruby中有許多事件驅(qū)動(dòng)庫,如EventMachineCelluloid,它們可以幫助你更高效地處理并發(fā)連接。

使用EventMachine

require 'eventmachine'

class MyServer < EventMachine::Connection
  def post_init
    @data = ''
    @send_data = false
  end

  def receive_data(data)
    @data += data
    if @data == 'hello'
      @send_data = true
    end
  end

  def send_data
    if @send_data
      send_data("Hello from EventMachine\n")
      @send_data = false
    end
  end

  def connection_closed
    @data = nil
    @send_data = false
  end
end

EventMachine.run do
  EventMachine.start_server('localhost', 8080, MyServer)
end

使用Celluloid

require 'celluloid'
require 'socket'

class MyServer
  include Celluloid::IO

  def initialize(host, port)
    @server = TCPServer.new(host, port)
  end

  def start
    @server.each_connection do |client|
      handle_connection(client)
    end
  end

  def handle_connection(client)
    client.puts "Hello from Celluloid"
    client.close
  end
end

MyServer.run('localhost', 8080)

總結(jié)

選擇哪種方法取決于你的具體需求和應(yīng)用場(chǎng)景。線程適用于簡(jiǎn)單的并發(fā)場(chǎng)景,異步IO適用于需要高性能的場(chǎng)景,而事件驅(qū)動(dòng)庫則適用于需要處理大量并發(fā)連接的場(chǎng)景。

0