Ruby 中两个客户端之间的通信
communication between two clients in Ruby
我正在尝试创建一个 Ruby 程序,该程序将在中间有服务器的两个客户端之间发送消息。例如,客户端 A 连接到服务器,客户端 B 连接到相同的服务器和端口。客户端 A 说 "How are you?",客户端 B 说 "Doing good." 有点像聊天服务器。我正在考虑让服务器从客户端 A 获取消息并发送给客户端 B。到目前为止,我有这个工作的客户端和服务器程序使用证书进行连接。我遇到的问题是我的服务器发送回客户端 A,我不知道如何发送到第二个连接(客户端 B)。
客户端
#!/usr/bin/ruby
require "socket"
require "openssl"
require "thread"
host = ARGV[0]
port = Integer(ARGV[1])
socket = TCPSocket.new(host, port)
certificate = OpenSSL::X509::Certificate.new(File.open("server.crt"))
ssl = OpenSSL::SSL::SSLSocket.new(socket)
ssl.sync_close = true
ssl.connect
if ssl.peer_cert.to_s != certificate.to_s
stderrr.puts "Unexpected certificate"
exit(1)
end
# Get input through the server
Thread.new {
begin
while server_res = ssl.gets.chomp
puts server_res
end
rescue
$stderr.puts "Error in server response loop: " + $!
end
}
# send out the STDIN to the server
while (client_sent = STDIN.gets.chomp)
ssl.puts client_sent
end
服务器
#!/usr/bin/ruby
require "socket"
require "openssl"
require "thread"
port = Integer(ARGV[0])
server = TCPServer.new(port)
sslCont = OpenSSL::SSL::SSLContext.new
sslCont.cert = OpenSSL::X509::Certificate.new(File.open("server.crt"))
sslCont.key = OpenSSL::PKey::RSA.new(File.open("server.key"))
sslServ = OpenSSL::SSL::SSLServer.new(server, sslCont)
loop {
connection = sslServ.accept
Thread.new {
begin
while (client_sent = connection.gets) do
client_sent = client_sent.chomp
puts "Client Sent: " + client_sent
server_res = "Server Response: " + client_sent
puts server_res
connection.puts server_res
end
rescue
$stderr.puts $!
end
}
}
保留已接受连接的数组
connections = []
当有人连接或断开连接时保持最新状态
connections << connection
...
connections.delete(connection)
发送时,您可以发送给所有的人:
connections.each do |conn|
conn.puts server_res
end
或者除了当前的所有:
connections.each do |conn|
next if conn == connection
conn.puts server_res
end
编辑:从注释中移出,因为它很重要:将 connections.delete
放入 begin...rescue...finally...end
块的 finally
子句中。这样,当连接因任何原因中断时(无论是自然地打破 while
条件,还是异常异常),它都会被执行。你不能做的是把它放在线程块之外,因为这样每个 connection
都会在放入后立即从 connections
中取出。
我正在尝试创建一个 Ruby 程序,该程序将在中间有服务器的两个客户端之间发送消息。例如,客户端 A 连接到服务器,客户端 B 连接到相同的服务器和端口。客户端 A 说 "How are you?",客户端 B 说 "Doing good." 有点像聊天服务器。我正在考虑让服务器从客户端 A 获取消息并发送给客户端 B。到目前为止,我有这个工作的客户端和服务器程序使用证书进行连接。我遇到的问题是我的服务器发送回客户端 A,我不知道如何发送到第二个连接(客户端 B)。
客户端
#!/usr/bin/ruby
require "socket"
require "openssl"
require "thread"
host = ARGV[0]
port = Integer(ARGV[1])
socket = TCPSocket.new(host, port)
certificate = OpenSSL::X509::Certificate.new(File.open("server.crt"))
ssl = OpenSSL::SSL::SSLSocket.new(socket)
ssl.sync_close = true
ssl.connect
if ssl.peer_cert.to_s != certificate.to_s
stderrr.puts "Unexpected certificate"
exit(1)
end
# Get input through the server
Thread.new {
begin
while server_res = ssl.gets.chomp
puts server_res
end
rescue
$stderr.puts "Error in server response loop: " + $!
end
}
# send out the STDIN to the server
while (client_sent = STDIN.gets.chomp)
ssl.puts client_sent
end
服务器
#!/usr/bin/ruby
require "socket"
require "openssl"
require "thread"
port = Integer(ARGV[0])
server = TCPServer.new(port)
sslCont = OpenSSL::SSL::SSLContext.new
sslCont.cert = OpenSSL::X509::Certificate.new(File.open("server.crt"))
sslCont.key = OpenSSL::PKey::RSA.new(File.open("server.key"))
sslServ = OpenSSL::SSL::SSLServer.new(server, sslCont)
loop {
connection = sslServ.accept
Thread.new {
begin
while (client_sent = connection.gets) do
client_sent = client_sent.chomp
puts "Client Sent: " + client_sent
server_res = "Server Response: " + client_sent
puts server_res
connection.puts server_res
end
rescue
$stderr.puts $!
end
}
}
保留已接受连接的数组
connections = []
当有人连接或断开连接时保持最新状态
connections << connection ... connections.delete(connection)
发送时,您可以发送给所有的人:
connections.each do |conn| conn.puts server_res end
或者除了当前的所有:
connections.each do |conn| next if conn == connection conn.puts server_res end
编辑:从注释中移出,因为它很重要:将
connections.delete
放入begin...rescue...finally...end
块的finally
子句中。这样,当连接因任何原因中断时(无论是自然地打破while
条件,还是异常异常),它都会被执行。你不能做的是把它放在线程块之外,因为这样每个connection
都会在放入后立即从connections
中取出。