MEChat 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Chat.rb +53 -0
- data/NodeDiscovery.rb +68 -0
- data/bin/chatdsva +6 -0
- data/client.rb +94 -0
- data/lib/MEChat_pb.rb +38 -0
- data/lib/MEChat_services_pb.rb +43 -0
- data/logger.rb +33 -0
- data/main.rb +58 -0
- data/ricart_agrawala.rb +14 -0
- data/server.rb +34 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3e81b866dee38480b59aa955074aae862729bb58570f5f712cddf9f197c5359f
|
4
|
+
data.tar.gz: 408448930057f827d762744384b41bec7eea5046d25ec3311b9f4608b80a67fd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c3f4f4f96a05311799f72b2ba0a81b2482bcd5495c2f5c1aeb3d9c8bc53d236bcb4377c2bf6757f84c387f9c4097cba4e0fce543a7d57fed5b71bc6602757454
|
7
|
+
data.tar.gz: bef9f54ec1492c3eb3a6543bfb7da6e4403b3709a79d56410c47584e987594b60ea993030d31dc68823d5d6d65dc1c1a9ecf7053fbbd2dca6f7a7eb420a32527
|
data/Chat.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'grpc'
|
3
|
+
require 'MEChat_pb'
|
4
|
+
require 'MEChat_services_pb'
|
5
|
+
require_relative './logger.rb'
|
6
|
+
|
7
|
+
this_dir = File.expand_path(File.dirname(__FILE__))
|
8
|
+
lib_dir = File.join(this_dir, 'lib')
|
9
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
10
|
+
|
11
|
+
class Chat < DistributedChat::ChatService::Service
|
12
|
+
|
13
|
+
def initialize ip,port,node_service
|
14
|
+
@node_service = node_service
|
15
|
+
@ip = ip
|
16
|
+
@port = port
|
17
|
+
@logger = MQTTLogger.new topic: "chat", ip: "#{ip.ip_address}:#{port}"
|
18
|
+
end
|
19
|
+
|
20
|
+
private def send_reply(ip:)
|
21
|
+
chat = DistributedChat::ChatService::Stub.new("#{ip.ip_address}:#{ip.ip_port}", :this_channel_is_insecure)
|
22
|
+
chat.release_critical_section(DistributedChat::Request.new(
|
23
|
+
username: "#{ip.ip_address}:#{ip.ip_port}",
|
24
|
+
message: "Reply",
|
25
|
+
timestamp: $alg.clock
|
26
|
+
))
|
27
|
+
@logger.info "Sent reply to #{ip.ip_address}:#{ip.ip_port}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def send_message(msg, _call)
|
31
|
+
$messages << msg
|
32
|
+
puts "#{msg.username}: #{msg.message}"
|
33
|
+
DistributedChat::Response.new status_code: 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def request_critical_section(req,_call)
|
37
|
+
request = {:ip => Addrinfo.getaddrinfo(req.username.split(":")[0..-2].join(":"),req.username.split(":")[-1].to_i)[0], :message => req}
|
38
|
+
if $crit_section === 0
|
39
|
+
send_reply ip: request[:ip]
|
40
|
+
elsif $crit_section < 2 && request[:message].timestamp < $alg.clock
|
41
|
+
send_reply ip: request[:ip]
|
42
|
+
else
|
43
|
+
$alg.requests << request
|
44
|
+
end
|
45
|
+
DistributedChat::Response.new status_code: 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def release_critical_section(req,_call)
|
49
|
+
$alg.replies << Addrinfo.getaddrinfo(req.username.split(":")[0..-2].join(":"),req.username.split(":")[-1].to_i)[0]
|
50
|
+
$alg.clock = [req.timestamp,$alg.clock].max + 1
|
51
|
+
DistributedChat::Response.new status_code: 0
|
52
|
+
end
|
53
|
+
end
|
data/NodeDiscovery.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'grpc'
|
3
|
+
require 'MEChat_pb'
|
4
|
+
require 'MEChat_services_pb'
|
5
|
+
require_relative './logger.rb'
|
6
|
+
require 'socket'
|
7
|
+
|
8
|
+
this_dir = File.expand_path(File.dirname(__FILE__))
|
9
|
+
lib_dir = File.join(this_dir, 'lib')
|
10
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
11
|
+
|
12
|
+
class NodeInfoEnum
|
13
|
+
def initialize(nodes)
|
14
|
+
@nodes = nodes
|
15
|
+
end
|
16
|
+
|
17
|
+
def each
|
18
|
+
if block_given?
|
19
|
+
@nodes.each do |node|
|
20
|
+
yield DistributedChat::NodeInfo.new(address: node.address, port: node.port)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
enum_for(:each)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
class NodeDiscoveryImpl < DistributedChat::NodeDiscovery::Service
|
28
|
+
|
29
|
+
def initialize ip, port
|
30
|
+
@ip = ip
|
31
|
+
@port = port
|
32
|
+
@logger = MQTTLogger.new topic: "nodediscovery", ip: "#{ip.ip_address}:#{port}"
|
33
|
+
end
|
34
|
+
def register_node(node_info, _call)
|
35
|
+
if $nodes.find { |x| x.address === node_info.address && x.port === node_info.port }
|
36
|
+
@logger.warn node_info.address + ":" + node_info.port.to_s + " already registered"
|
37
|
+
raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::ALREADY_EXISTS, "Node with ip: " + node_info.address + ":" + node_info.port.to_s + " already registered")
|
38
|
+
else
|
39
|
+
$nodes.push node_info
|
40
|
+
puts node_info.address + ":" + node_info.port.to_s + " joined network"
|
41
|
+
@logger.info "Registered node with ip:" + node_info.address + ":" + node_info.port.to_s
|
42
|
+
end
|
43
|
+
nodes_to_return = $nodes.reject { |x| x.address === node_info.address && x.port === node_info.port }
|
44
|
+
to_remove = []
|
45
|
+
nodes_to_return.each do |node|
|
46
|
+
begin
|
47
|
+
nodediscovery = DistributedChat::NodeDiscovery::Stub.new("#{node.address}:#{node.port}", :this_channel_is_insecure)
|
48
|
+
nodediscovery.register_node(DistributedChat::NodeInfo.new(address: node_info.address, port: node_info.port))
|
49
|
+
rescue GRPC::Unavailable => e
|
50
|
+
to_remove << node
|
51
|
+
end
|
52
|
+
end
|
53
|
+
$nodes -= to_remove
|
54
|
+
nodes_to_return -= to_remove
|
55
|
+
nodes_to_return << DistributedChat::NodeInfo.new(address: @ip.ip_address, port: @port)
|
56
|
+
NodeInfoEnum.new(nodes_to_return).each
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_nodes(req,_call)
|
60
|
+
@logger.info "#{_call.peer[5..-1]} with username #{req.username} requested nodes list"
|
61
|
+
NodeInfoEnum.new($nodes).each
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_nodes_local
|
65
|
+
$nodes
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/bin/chatdsva
ADDED
data/client.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'grpc'
|
3
|
+
require 'MEChat_pb'
|
4
|
+
require 'MEChat_services_pb'
|
5
|
+
require_relative './NodeDiscovery.rb'
|
6
|
+
require_relative './logger.rb'
|
7
|
+
|
8
|
+
this_dir = File.expand_path(File.dirname(__FILE__))
|
9
|
+
lib_dir = File.join(this_dir, 'lib')
|
10
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
11
|
+
|
12
|
+
class Client
|
13
|
+
|
14
|
+
def initialize(ip: Addrinfo)
|
15
|
+
@ip = ip
|
16
|
+
@logger = MQTTLogger.new topic: "chat", ip: "#{ip.ip_address}:#{$port.to_s}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def connect(ip:)
|
20
|
+
nodediscovery = DistributedChat::NodeDiscovery::Stub.new("#{ip.ip_address}:#{ip.ip_port}", :this_channel_is_insecure)
|
21
|
+
nodediscovery.register_node(DistributedChat::NodeInfo.new(address: @ip.ip_address, port: $port)).each do |node|
|
22
|
+
$nodes.push node
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
private def request_critical_section
|
28
|
+
$alg.mutex.synchronize do
|
29
|
+
$alg.clock += 1
|
30
|
+
to_remove = []
|
31
|
+
$nodes.each do |node|
|
32
|
+
begin
|
33
|
+
chat = DistributedChat::ChatService::Stub.new("#{node.address}:#{node.port}", :this_channel_is_insecure)
|
34
|
+
@logger.info "Sent request to #{node.address}:#{node.port}"
|
35
|
+
chat.request_critical_section(DistributedChat::Request.new(
|
36
|
+
username: "#{@ip.ip_address}:#{$port.to_s}",
|
37
|
+
message: "Request",
|
38
|
+
timestamp: $alg.clock
|
39
|
+
))
|
40
|
+
rescue GRPC::Unavailable
|
41
|
+
to_remove << node
|
42
|
+
end
|
43
|
+
end
|
44
|
+
$nodes -= to_remove
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private def send_reply(ip:)
|
49
|
+
chat = DistributedChat::ChatService::Stub.new("#{ip.ip_address}:#{ip.ip_port}", :this_channel_is_insecure)
|
50
|
+
chat.release_critical_section(DistributedChat::Request.new(
|
51
|
+
username: "#{ip.ip_address}:#{ip.ip_port}",
|
52
|
+
message: "Reply",
|
53
|
+
timestamp: $alg.clock
|
54
|
+
))
|
55
|
+
@logger.info "Sent reply to #{ip.ip_address}:#{ip.ip_port}"
|
56
|
+
end
|
57
|
+
|
58
|
+
private def release_critical_section
|
59
|
+
$alg.mutex.synchronize do
|
60
|
+
$alg.requests.each do |request|
|
61
|
+
send_reply(ip: request[:ip])
|
62
|
+
end
|
63
|
+
$alg.requests.clear
|
64
|
+
$alg.replies.clear
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def run
|
69
|
+
new_msg = gets.chomp
|
70
|
+
while new_msg != "exit"
|
71
|
+
$crit_section = 1
|
72
|
+
request_critical_section
|
73
|
+
sleepdur = 0
|
74
|
+
while $alg.replies.length < $nodes.length
|
75
|
+
sleepdur += 0.1
|
76
|
+
@logger.info "#{@ip.ip_address}:#{$port.to_s} waiting for replies"
|
77
|
+
sleep 0.1
|
78
|
+
if sleepdur % 5 == 0
|
79
|
+
puts "Waiting for replies. #{$alg.replies.length}/#{$nodes.length} replies received"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
$crit_section = 2
|
83
|
+
$nodes.each do |node|
|
84
|
+
chat = DistributedChat::ChatService::Stub.new("#{node.address}:#{node.port}", :this_channel_is_insecure)
|
85
|
+
chat.send_message(DistributedChat::Request.new(username: "#{@ip.ip_address}:#{$port.to_s}", message: new_msg, timestamp: $alg.clock))
|
86
|
+
@logger.info "Sent message \"#{new_msg}\" to #{node.address}:#{node.port}"
|
87
|
+
end
|
88
|
+
$messages.push DistributedChat::Request.new(username: "#{@ip.ip_address}:#{$port.to_s}", message: new_msg, timestamp: $alg.clock)
|
89
|
+
release_critical_section
|
90
|
+
$crit_section = 0
|
91
|
+
new_msg = gets.chomp
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/MEChat_pb.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: MEChat.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x0cMEChat.proto\x12\x10\x64istributed_chat\"?\n\x07Request\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x11\n\ttimestamp\x18\x03 \x01(\x05\"\x1f\n\x08Response\x12\x13\n\x0bstatus_code\x18\x01 \x01(\x05\"O\n\x08NodeInfo\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x05\x12\x16\n\ttimestamp\x18\x03 \x01(\x05H\x00\x88\x01\x01\x42\x0c\n\n_timestamp2\xf5\x01\n\x0b\x43hatService\x12\x44\n\x0bSendMessage\x12\x19.distributed_chat.Request\x1a\x1a.distributed_chat.Response\x12O\n\x16RequestCriticalSection\x12\x19.distributed_chat.Request\x1a\x1a.distributed_chat.Response\x12O\n\x16ReleaseCriticalSection\x12\x19.distributed_chat.Request\x1a\x1a.distributed_chat.Response2\x9e\x01\n\rNodeDiscovery\x12H\n\x0cRegisterNode\x12\x1a.distributed_chat.NodeInfo\x1a\x1a.distributed_chat.NodeInfo0\x01\x12\x43\n\x08GetNodes\x12\x19.distributed_chat.Request\x1a\x1a.distributed_chat.NodeInfo0\x01\x42\t\xaa\x02\x06MEChatb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
|
12
|
+
begin
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
rescue TypeError
|
15
|
+
# Compatibility code: will be removed in the next major version.
|
16
|
+
require 'google/protobuf/descriptor_pb'
|
17
|
+
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
18
|
+
parsed.clear_dependency
|
19
|
+
serialized = parsed.class.encode(parsed)
|
20
|
+
file = pool.add_serialized_file(serialized)
|
21
|
+
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
22
|
+
imports = [
|
23
|
+
]
|
24
|
+
imports.each do |type_name, expected_filename|
|
25
|
+
import_file = pool.lookup(type_name).file_descriptor
|
26
|
+
if import_file.name != expected_filename
|
27
|
+
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
warn "Each proto file must use a consistent fully-qualified name."
|
31
|
+
warn "This will become an error in the next major version."
|
32
|
+
end
|
33
|
+
|
34
|
+
module DistributedChat
|
35
|
+
Request = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("distributed_chat.Request").msgclass
|
36
|
+
Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("distributed_chat.Response").msgclass
|
37
|
+
NodeInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("distributed_chat.NodeInfo").msgclass
|
38
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# Source: MEChat.proto for package 'distributed_chat'
|
3
|
+
|
4
|
+
require 'grpc'
|
5
|
+
require 'MEChat_pb'
|
6
|
+
|
7
|
+
module DistributedChat
|
8
|
+
module ChatService
|
9
|
+
class Service
|
10
|
+
|
11
|
+
include ::GRPC::GenericService
|
12
|
+
|
13
|
+
self.marshal_class_method = :encode
|
14
|
+
self.unmarshal_class_method = :decode
|
15
|
+
self.service_name = 'distributed_chat.ChatService'
|
16
|
+
|
17
|
+
# Method to send a message to the chat
|
18
|
+
rpc :SendMessage, ::DistributedChat::Request, ::DistributedChat::Response
|
19
|
+
# Method to request access to the critical section
|
20
|
+
rpc :RequestCriticalSection, ::DistributedChat::Request, ::DistributedChat::Response
|
21
|
+
# Method to release access to the critical section
|
22
|
+
rpc :ReleaseCriticalSection, ::DistributedChat::Request, ::DistributedChat::Response
|
23
|
+
end
|
24
|
+
|
25
|
+
Stub = Service.rpc_stub_class
|
26
|
+
end
|
27
|
+
# Define RPC methods for the distributed chat service
|
28
|
+
module NodeDiscovery
|
29
|
+
class Service
|
30
|
+
|
31
|
+
include ::GRPC::GenericService
|
32
|
+
|
33
|
+
self.marshal_class_method = :encode
|
34
|
+
self.unmarshal_class_method = :decode
|
35
|
+
self.service_name = 'distributed_chat.NodeDiscovery'
|
36
|
+
|
37
|
+
rpc :RegisterNode, ::DistributedChat::NodeInfo, stream(::DistributedChat::NodeInfo)
|
38
|
+
rpc :GetNodes, ::DistributedChat::Request, stream(::DistributedChat::NodeInfo)
|
39
|
+
end
|
40
|
+
|
41
|
+
Stub = Service.rpc_stub_class
|
42
|
+
end
|
43
|
+
end
|
data/logger.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mqtt'
|
4
|
+
|
5
|
+
class MQTTLogger
|
6
|
+
def initialize (topic: String, ip: String)
|
7
|
+
@client = MQTT::Client.new
|
8
|
+
@client.host = 'fireup.studio'
|
9
|
+
@client.connect
|
10
|
+
@topic = topic
|
11
|
+
@ip = ip
|
12
|
+
end
|
13
|
+
|
14
|
+
private def log level, msg
|
15
|
+
@client.publish(@topic, "#{@ip}|#{level}|#{msg}", retain=false)
|
16
|
+
end
|
17
|
+
|
18
|
+
def info msg
|
19
|
+
log "INFO",msg
|
20
|
+
end
|
21
|
+
|
22
|
+
def warn msg
|
23
|
+
log "WARN",msg
|
24
|
+
end
|
25
|
+
|
26
|
+
def error msg
|
27
|
+
log "ERROR",msg
|
28
|
+
end
|
29
|
+
|
30
|
+
def finalize
|
31
|
+
@client.disconnect
|
32
|
+
end
|
33
|
+
end
|
data/main.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'grpc'
|
3
|
+
require 'MEChat_pb'
|
4
|
+
require 'MEChat_services_pb'
|
5
|
+
require_relative './NodeDiscovery.rb'
|
6
|
+
require_relative './server.rb'
|
7
|
+
require_relative './client.rb'
|
8
|
+
require_relative './ricart_agrawala.rb'
|
9
|
+
|
10
|
+
this_dir = File.expand_path(File.dirname(__FILE__))
|
11
|
+
lib_dir = File.join(this_dir, 'lib')
|
12
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
13
|
+
$port = RandomPort::Pool::SINGLETON.acquire
|
14
|
+
$nodes = []
|
15
|
+
$messages = []
|
16
|
+
$crit_section = 0
|
17
|
+
$alg = RicartAgrawala.new
|
18
|
+
|
19
|
+
class Main
|
20
|
+
|
21
|
+
def pick_ip
|
22
|
+
addrs = Socket.ip_address_list.reject( &:ipv4_loopback? )
|
23
|
+
.reject( &:ipv6_loopback? )
|
24
|
+
puts "Please select by which IP to present to other nodes"
|
25
|
+
addrs.each_with_index do |x,i|
|
26
|
+
puts "[#{i}] #{x.ip_address}"
|
27
|
+
end
|
28
|
+
puts "[#{addrs.length}] Manual IP"
|
29
|
+
picked = gets.to_i 10
|
30
|
+
return addrs[picked] unless picked.to_i >= addrs.length
|
31
|
+
Addrinfo.getaddrinfo(gets.chomp,80)[0]
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_other_ip
|
35
|
+
puts "[J]oin network or [C]reate new network?"
|
36
|
+
choice = gets.chomp
|
37
|
+
return Addrinfo.getaddrinfo("224.0.0.1",80)[0] if choice.downcase[0] == "c"
|
38
|
+
puts "Please enter IP of a node in the network you wish to join"
|
39
|
+
ip = gets.chomp
|
40
|
+
puts "Please enter port of a node in the network you wish to join"
|
41
|
+
port = gets.to_i 10
|
42
|
+
Addrinfo.getaddrinfo(ip,port)[0]
|
43
|
+
end
|
44
|
+
|
45
|
+
def main
|
46
|
+
ip = pick_ip
|
47
|
+
connect_ip = get_other_ip
|
48
|
+
server = Thread.new { Server.new(ip: ip).run }
|
49
|
+
if connect_ip.ipv4_multicast?
|
50
|
+
client = Thread.new { Client.new(ip: ip).run }
|
51
|
+
else
|
52
|
+
client = Thread.new { Client.new(ip: ip).connect(ip: connect_ip); Client.new(ip: ip).run }
|
53
|
+
end
|
54
|
+
server.join
|
55
|
+
client.join
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/ricart_agrawala.rb
ADDED
data/server.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'grpc'
|
3
|
+
require 'random-port'
|
4
|
+
require 'MEChat_pb'
|
5
|
+
require 'MEChat_services_pb'
|
6
|
+
require_relative './NodeDiscovery.rb'
|
7
|
+
require_relative './Chat.rb'
|
8
|
+
|
9
|
+
this_dir = File.expand_path(File.dirname(__FILE__))
|
10
|
+
lib_dir = File.join(this_dir, 'lib')
|
11
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
class Server
|
14
|
+
def initialize(ip: Addrinfo)
|
15
|
+
@ip = ip
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
|
20
|
+
node_discovery = NodeDiscoveryImpl.new @ip, $port
|
21
|
+
chat = Chat.new @ip,$port,node_discovery
|
22
|
+
|
23
|
+
server = GRPC::RpcServer.new
|
24
|
+
server.add_http2_port("0.0.0.0:#{$port.to_s}", :this_port_is_insecure)
|
25
|
+
server.handle(node_discovery)
|
26
|
+
server.handle(chat)
|
27
|
+
puts "Server side running on " + $port.to_s
|
28
|
+
|
29
|
+
server.run_till_terminated_or_interrupted(['int', 'SIGTERM'])
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Server.new.run
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: MEChat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lukas Kaufmann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-01-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: grpc
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.13.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.13.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mqtt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: random-port
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.6.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.6.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rbs
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.3.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.3.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: grpc-tools
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.50'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.50'
|
111
|
+
description: SHM Chat app using gRPC and Ricart-Agrawala algorithm
|
112
|
+
email: kaufmlu1@fel.cvut.cz
|
113
|
+
executables:
|
114
|
+
- chatdsva
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- Chat.rb
|
119
|
+
- NodeDiscovery.rb
|
120
|
+
- bin/chatdsva
|
121
|
+
- client.rb
|
122
|
+
- lib/MEChat_pb.rb
|
123
|
+
- lib/MEChat_services_pb.rb
|
124
|
+
- logger.rb
|
125
|
+
- main.rb
|
126
|
+
- ricart_agrawala.rb
|
127
|
+
- server.rb
|
128
|
+
homepage:
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubygems_version: 3.4.10
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: gRPC Ruby shared memory chat app
|
151
|
+
test_files: []
|