非常教程

Ruby 2.4参考手册

DRb

Rinda::RingServer

父类:ObjectIncluded模块:DRb :: DRbUndumped

RingServer允许通过UDP广播定位Rinda :: TupleSpace。默认服务位置使用以下步骤:

  • RingServer开始监听网络广播UDP地址。
  • RingFinger发送一个包含DRb URI的UDP数据包,在那里它将监听回复。
  • RingServer接收UDP数据包并通过DRb服务连接回提供的DRb URI。

RingServer需要TupleSpace:

ts = Rinda::TupleSpace.new
rs = Rinda::RingServer.new

RingServer也可以监听多播地址中的公告。这允许多个RingServers在同一台主机上运行。要使用网络广播和多播:

ts = Rinda::TupleSpace.new
rs = Rinda::RingServer.new ts, %w[Socket::INADDR_ANY, 239.0.0.1 ff02::1]

公共类方法

new(ts, addresses=Socket::INADDR_ANY, port=Ring_PORT) 显示源

广告ts在给定addressesport

如果addresses省略,则只使用UDP广播地址。

addresses可以包含多个地址。如果给出多播地址,addresses则RingServer将侦听多播查询。

如果使用IPv4组播,则可能需要设置加入组播组的入站接口的地址。

ts = Rinda::TupleSpace.new
rs = Rinda::RingServer.new(ts, [['239.0.0.1', '9.5.1.1']])

您可以将地址设置为数组对象。Array的第一个元素是多播地址,第二个元素是入站接口地址。如果第二个被省略,则使用“0.0.0.0”。

如果使用IPv6多播,则可能需要同时设置本地接口地址和入站接口索引:

rs = Rinda::RingServer.new(ts, [['ff02::1', '::1', 1]])

第一个元素是多播地址,第二个元素是入站接口地址。第三个是入站接口索引。

目前没有简单的方法来按名称获取接口索引。

如果第二个被省略,则使用':: 1'。如果第三个被省略,则使用0(默认接口)。

# File lib/rinda/ring.rb, line 94
def initialize(ts, addresses=[Socket::INADDR_ANY], port=Ring_PORT)
  @port = port

  if Integer === addresses then
    addresses, @port = [Socket::INADDR_ANY], addresses
  end

  @renewer = Renewer.new

  @ts = ts
  @sockets = []
  addresses.each do |address|
    if Array === address
      make_socket(*address)
    else
      make_socket(address)
    end
  end

  @w_services = write_services
  @r_service  = reply_service
end

公共实例方法

do_reply() 显示源

将查找元组从TupleSpace中拉出,并将它们的DRb对象发送到本地TupleSpace的地址。

# File lib/rinda/ring.rb, line 214
def do_reply
  tuple = @ts.take([:lookup_ring, nil], @renewer)
  Thread.new { tuple[1].call(@ts) rescue nil}
rescue
end

do_write(msg) 显示源

从响应URI中提取响应URI msg并将其添加到TupleSpace中,reply_service以便通知它。

# File lib/rinda/ring.rb, line 189
def do_write(msg)
  Thread.new do
    begin
      tuple, sec = Marshal.load(msg)
      @ts.write(tuple, sec)
    rescue
    end
  end
end

make_socket(address, interface_address=nil, multicast_interface=0)显示源

创建一个套接字 address

如果address是多播地址,则interface_addressmulticast_interface可设置为可选。

创建的套接字绑定interface_address。如果您使用IPv4多播,则接口将interface_address用作入站接口。如果interface_address省略或零,则使用“0.0.0.0”或“:: 1”。

如果您使用IPv6多播,则将multicast_interface其用作入站接口。multicast_interface是网络接口索引。如果multicast_interface省略,则使用0(默认接口)。

# File lib/rinda/ring.rb, line 132
def make_socket(address, interface_address=nil, multicast_interface=0)
  addrinfo = Addrinfo.udp(address, @port)

  socket = Socket.new(addrinfo.pfamily, addrinfo.socktype,
                      addrinfo.protocol)
  @sockets << socket

  if addrinfo.ipv4_multicast? or addrinfo.ipv6_multicast? then
    if Socket.const_defined?(:SO_REUSEPORT) then
      socket.setsockopt(:SOCKET, :SO_REUSEPORT, true)
    else
      socket.setsockopt(:SOCKET, :SO_REUSEADDR, true)
    end

    if addrinfo.ipv4_multicast? then
      interface_address = '0.0.0.0' if interface_address.nil?
      socket.bind(Addrinfo.udp(interface_address, @port))

      mreq = IPAddr.new(addrinfo.ip_address).hton +
        IPAddr.new(interface_address).hton

      socket.setsockopt(:IPPROTO_IP, :IP_ADD_MEMBERSHIP, mreq)
    else
      interface_address = '::1' if interface_address.nil?
      socket.bind(Addrinfo.udp(interface_address, @port))

      mreq = IPAddr.new(addrinfo.ip_address).hton +
        [multicast_interface].pack('I')

      socket.setsockopt(:IPPROTO_IPV6, :IPV6_JOIN_GROUP, mreq)
    end
  else
    socket.bind(addrinfo)
  end

  socket
end

reply_service()显示源

创建一个从TupleSpace通知等待客户端的线程。

# File lib/rinda/ring.rb, line 202
def reply_service
  Thread.new do
    loop do
      do_reply
    end
  end
end

shutdown() 显示源

关闭RingServer

# File lib/rinda/ring.rb, line 223
def shutdown
  @renewer.renew = false

  @w_services.each do |thread|
    thread.kill
    thread.join
  end

  @sockets.each do |socket|
    socket.close
  end

  @r_service.kill
  @r_service.join
end

write_services() 显示源

创建拾取UDP数据包的线程并将它们传递给#do_write进行解码。

# File lib/rinda/ring.rb, line 174
def write_services
  @sockets.map do |s|
    Thread.new(s) do |socket|
      loop do
        msg = socket.recv(1024)
        do_write(msg)
      end
    end
  end
end
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct