Revision 69a12fdb
Added by Marc Dequènes about 14 years ago
- ID 69a12fdbdbd27a5673fa8b848b4a03c2aa671004
lib/cyborghood/cyborg/conversation.rb | ||
---|---|---|
|
||
module BotProtocol
|
||
VERSION = "0.1"
|
||
CAPABILITIES = []
|
||
|
||
@@request_callback = proc{|result| process_request_result(result) }
|
||
|
||
# TODO:
|
||
# - check for request/reply couples (reply to wrong of non-existent request)
|
||
... | ... | |
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"
|
||
... | ... | |
@negociation_ok = true
|
||
end
|
||
|
||
def receive_request_capabilities(message)
|
||
send_reply_result(message, @conversation.capabilities + CAPABILITIES)
|
||
end
|
||
|
||
def receive_request_call(message)
|
||
unless @conversation.bot.interface.is_node? message.parameters[:node]
|
||
return send_error_action(message, "bad node")
|
||
end
|
||
send_reply_ack(message)
|
||
@conversation.bot.schedule_task(@@request_callback) do
|
||
result = {
|
||
:reply_message => message
|
||
}
|
||
begin
|
||
result[:action_result] = @conversation.bot.interface.call(message.conv_thread.session,
|
||
message.parameters[:node],
|
||
message.parameters[:data])
|
||
rescue
|
||
result[:error] = $!
|
||
end
|
||
end
|
||
end
|
||
|
||
def receive_request_exists(message)
|
||
unless @conversation.bot.interface.is_node? message.parameters[:node]
|
||
return send_error_action(message, "bad node")
|
||
end
|
||
send_reply_ack(message)
|
||
@conversation.bot.schedule_task(@@request_callback) do
|
||
{
|
||
:reply_message => message,
|
||
:action_result => @conversation.bot.interface.has_node? message.parameters[:node]
|
||
}
|
||
end
|
||
end
|
||
|
||
def receive_request_describe(message)
|
||
# TODO: implement when ready in the interface
|
||
send_quit_decline(message, "not implemented")
|
||
end
|
||
|
||
def send_announce_helo(recv_message = nil)
|
||
action_code = "ANNOUNCE HELO"
|
||
message = (recv_message.nil? ? @conversation.thread('system').new_message(action_code) :
|
||
... | ... | |
recv_message.create_reply("ANNOUNCE OK").send
|
||
end
|
||
|
||
def send_request_capabilities
|
||
@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
|
||
end
|
||
|
||
def send_request_exists(conv_thread, node)
|
||
conv_thread.new_message("REQUEST EXISTS", { :node => node }).send
|
||
end
|
||
|
||
def send_request_describe(conv_thread, node)
|
||
conv_thread.new_message("REQUEST DESCRIBE", { :node => node }).send
|
||
end
|
||
|
||
def send_error_protocol(error, fatal = false)
|
||
@conversation.thread('system').new_message("ERROR PROTOCOL", { :error => error }).send
|
||
@conversation.set_error_status(fatal)
|
||
end
|
||
|
||
def send_error_action(recv_message, message)
|
||
recv_message.create_reply("ERROR ACTION", { :error => message }).send
|
||
def send_error_action(recv_message, error)
|
||
recv_message.create_reply("ERROR ACTION", { :error => error }).send
|
||
end
|
||
|
||
def send_reply_ack(recv_message)
|
||
... | ... | |
@protocol = BotProtocol.new(self)
|
||
end
|
||
|
||
def clear_receive_info
|
||
@receive_error = false
|
||
@receive_fatal_error = false
|
||
end
|
||
|
||
def send_line(msg)
|
||
send_data "#{msg}\n"
|
||
logger.debug "Sent data [#{identifier}]: #{msg}"
|
||
def capabilities
|
||
[]
|
||
end
|
||
|
||
def post_init
|
||
... | ... | |
check_errors
|
||
end
|
||
|
||
def check_errors
|
||
@error_count += 1 if @receive_error
|
||
|
||
msg_quit = nil
|
||
if @error_count >= MAXIMUM_ERROR_COUNT
|
||
msg_quit = "too much errors, terminating"
|
||
elsif @fatal_error
|
||
msg_quit = "previous fatal error"
|
||
end
|
||
|
||
unless msg_quit.nil?
|
||
send_quit_decline msg_quit
|
||
close_connection_after_writing
|
||
end
|
||
end
|
||
|
||
def receive_message(message)
|
||
logger.debug "Received message '#{action}' [#{identifier}]"
|
||
|
||
... | ... | |
|
||
protected
|
||
|
||
def clear_receive_info
|
||
@receive_error = false
|
||
@receive_fatal_error = false
|
||
end
|
||
|
||
def send_line(msg)
|
||
logger.debug "Sending data [#{identifier}]: #{msg}"
|
||
send_data "#{msg}\n"
|
||
end
|
||
|
||
def check_errors
|
||
@error_count += 1 if @receive_error
|
||
|
||
msg_quit = nil
|
||
if @error_count >= MAXIMUM_ERROR_COUNT
|
||
msg_quit = "too much errors, terminating"
|
||
elsif @fatal_error
|
||
msg_quit = "previous fatal error"
|
||
end
|
||
|
||
unless msg_quit.nil?
|
||
send_quit_decline msg_quit
|
||
close_connection_after_writing
|
||
end
|
||
end
|
||
|
||
def new_thread(name, id = nil)
|
||
id ||= @next_thread_id
|
||
th = ConversationThread.new(self, id, name)
|
||
... | ... | |
def identifier
|
||
"unix_socket/#{@signature}"
|
||
end
|
||
|
||
def capabilities
|
||
super + []
|
||
end
|
||
end
|
||
end
|
Also available in: Unified diff
[evol] conversation/bot protocol rework §6 (refs #30)