Revision 21a7eaf9
Added by Marc Dequènes about 14 years ago
- ID 21a7eaf9331ab26b1c1d5ff7173c4b248f6a2967
bin/mapmaker_client | ||
---|---|---|
contact_peer("MapMaker") do |conv|
|
||
if conv
|
||
logger.info "Yo ! Conversation ready with MapMaker (#{conv.peer_name}) !"
|
||
conv_thread = conv.thread("plop")
|
||
conv.protocol.send_request_call(conv_thread, "/") do |reply|
|
||
pp reply
|
||
end
|
||
else
|
||
logger.error "Could not connect to MapMaker"
|
||
stop
|
lib/cyborghood/cyborg/conversation.rb | ||
---|---|---|
@action_id = @conv_thread.next_action_id if @action_id.nil?
|
||
@conv_thread.conversation.send_message(self)
|
||
@sent = true
|
||
|
||
# return message (convenience)
|
||
self
|
||
end
|
||
|
||
def create_reply(action_code, parameters = nil)
|
||
... | ... | |
MAXIMUM_ERROR_COUNT = 3
|
||
MAXIMUM_LINES = 1024
|
||
|
||
attr_reader :bot, :peer_name, :peer_capabilities
|
||
attr_reader :bot, :peer_name, :peer_capabilities, :protocol
|
||
|
||
def initialize(bot, block = nil)
|
||
@bot = bot
|
lib/cyborghood/cyborg/protocol.rb | ||
---|---|---|
VERSION = "0.1"
|
||
CAPABILITIES = []
|
||
|
||
@@request_callback = proc{|result| process_request_result(result) }
|
||
@@request_callback = proc do |result|
|
||
protocol = result[:reply_message].conv_thread.conversation.protocol
|
||
protocol.process_request_result(result)
|
||
end
|
||
|
||
# TODO:
|
||
# - check for request/reply couples (reply to wrong of non-existent request)
|
||
... | ... | |
@negociation_received = false
|
||
@negociation_sent = false
|
||
@negociation_ok = false
|
||
end
|
||
|
||
def self.process_request_result(result)
|
||
if result[:error]
|
||
send_error_action(result[:reply_message], result[:error])
|
||
else
|
||
send_reply_result(result[:reply_message], result[:action_result])
|
||
end
|
||
@action_followup = {}
|
||
end
|
||
|
||
def negociation_ok?
|
||
... | ... | |
end
|
||
end
|
||
|
||
def process_request_result(result)
|
||
if result[:error]
|
||
send_error_action(result[:reply_message], result[:error])
|
||
else
|
||
send_reply_result(result[:reply_message], result[:action_result])
|
||
end
|
||
end
|
||
|
||
def receive_announce_helo(message)
|
||
unless message.conv_thread.id == 0
|
||
return send_quit_decline "bad negociation"
|
||
... | ... | |
message.action_parameters[:node],
|
||
message.action_parameters[:data])
|
||
rescue
|
||
result[:error] = $!
|
||
result[:error] = $!.to_s
|
||
end
|
||
result
|
||
end
|
||
end
|
||
|
||
... | ... | |
|
||
def receive_request_describe(message)
|
||
# TODO: implement when ready in the interface
|
||
send_quit_decline(message, "not implemented")
|
||
send_reply_decline(message, "not implemented")
|
||
end
|
||
|
||
def receive_error_protocol(message)
|
||
logger.error "received protocol error notification from '#{@conversation.peer_name}': #{message.action_parameters[:error]}"
|
||
end
|
||
|
||
def receive_error_action(message)
|
||
cb = pop_callback(message)
|
||
if cb
|
||
cb.call({:reply => :error, :reason => message.action_parameters[:error]})
|
||
else
|
||
send_error_protocol("received reply for unknown action")
|
||
end
|
||
end
|
||
|
||
def receive_reply_ack(message)
|
||
# TODO
|
||
end
|
||
|
||
def receive_reply_decline(message)
|
||
cb = pop_callback(message)
|
||
if cb
|
||
cb.call({:reply => :decline, :reason => message.action_parameters[:reason]})
|
||
else
|
||
send_error_protocol("received reply for unknown action")
|
||
end
|
||
end
|
||
|
||
def receive_reply_result(message)
|
||
cb = pop_callback(message)
|
||
if cb
|
||
cb.call({:reply => :ok, :result => message.action_parameters[:result]})
|
||
else
|
||
send_error_protocol("received reply for unknown action")
|
||
end
|
||
end
|
||
|
||
def receive_quit_decline(message)
|
||
logger.warning "peer '#{@conversation.peer_name}' refused more conversation: #{message.action_parameters[:reason]}"
|
||
@conversation.set_comm_stop(true)
|
||
# TODO: notify client
|
||
end
|
||
|
||
def receive_quit_leaving(message)
|
||
logger.info "peer '#{@conversation.peer_name}' is leaving"
|
||
@conversation.set_comm_stop(true)
|
||
# TODO: notify client
|
||
end
|
||
... | ... | |
@conversation.thread('system').new_message("REQUEST EXISTS", { :node => node }).send
|
||
end
|
||
|
||
def send_request_call(conv_thread, node)
|
||
conv_thread.new_message("REQUEST CALL", { :node => node }).send
|
||
def send_request_call(conv_thread, node, &callback)
|
||
message = conv_thread.new_message("REQUEST CALL", { :node => node }).send
|
||
register_callback(message, callback)
|
||
end
|
||
|
||
def send_request_exists(conv_thread, node)
|
||
conv_thread.new_message("REQUEST EXISTS", { :node => node }).send
|
||
message = conv_thread.new_message("REQUEST EXISTS", { :node => node }).send
|
||
register_callback(message, callback)
|
||
end
|
||
|
||
def send_request_describe(conv_thread, node)
|
||
conv_thread.new_message("REQUEST DESCRIBE", { :node => node }).send
|
||
message = conv_thread.new_message("REQUEST DESCRIBE", { :node => node }).send
|
||
register_callback(message, callback)
|
||
end
|
||
|
||
def send_error_protocol(error, fatal = false)
|
||
... | ... | |
end
|
||
|
||
def send_reply_result(recv_message, result)
|
||
recv_message.create_reply("REPLY ACK", { :result => result }).send
|
||
recv_message.create_reply("REPLY RESULT", { :result => result }).send
|
||
end
|
||
|
||
def send_quit_decline(reason)
|
||
... | ... | |
@conversation.thread('system').new_message("QUIT LEAVING").send
|
||
end
|
||
end
|
||
|
||
protected
|
||
|
||
def register_callback(message, callback)
|
||
@action_followup[message.conv_thread.id] ||= {}
|
||
@action_followup[message.conv_thread.id][message.action_id] = callback
|
||
end
|
||
|
||
def pop_callback(message)
|
||
return nil unless @action_followup.has_key? message.conv_thread.id
|
||
return nil unless @action_followup[message.conv_thread.id].has_key? message.action_id
|
||
cb = @action_followup[message.conv_thread.id][message.action_id]
|
||
|
||
@action_followup[message.conv_thread.id].delete message.action_id
|
||
@action_followup.delete message.conv_thread.id if @action_followup[message.conv_thread.id].empty?
|
||
|
||
cb
|
||
end
|
||
end
|
||
end
|
Also available in: Unified diff
[evol] conversation/bot protocol rework §8 (refs #30): preliminary client-side protocol handling