require 'service' require 'transport/messages' module Servicy # The Transport class is an abstract class whos implementations handle the # actual communication over the wire or in memory between server and client. # However, in the abstract, it doesn't matter how things are transported, # only that they are and conform to the format described here. class Transport attr_reader :config # @param [Hash] config Configuration options for the transport def initialize(config={}) @config = config end # Override this method to send a message from {Client} to {Server} def send(messge) raise NotImplementedError.new end # Override this method to yield a message when received on the {Server}. It # should yield to the provided block the message received as a # {Transport::Message} object, and send back the return value of the block # to the client. def start(&block) raise NotImplementedError.new end # Same as start, but used in creation of API handlers. def start_api(&block) raise NotImplementedError.new end # Called when a transport is stopped def stop end # This attempts to load a service based on the name. def self.method_missing(name, *args, &block) class_name = "#{name.to_s}Transport" begin c = Module.const_get(class_name) return c if c && c.ancestors.include?(Servicy::Transport) rescue NameError c = Servicy.const_get(class_name) return c if c && c.ancestors.include?(Servicy::Transport) end rescue super end def self.all ObjectSpace.each_object(Class).select { |klass| klass < self } end # Returns a printable string representing what protocol this would be used # as. Override if you like. def self.protocol_string self.name.split("Transport").first end # @param [Hash] values Key-value pairs for things to encode. def format(values) formatter.format(values); end def unformat(values) formatter.unformat(values) end # Method called to make a remote request of an API call. To be implemented # per transport. # @return [Object] the raw values coming back from the request, to be # passed to the formatter for unformatting. def remote_request(name, args) raise NotImplementedError.new end private def formatter @formatter ||= @config['format'] || Servicy.config.transport.format end end end # Load all the transports Dir[File.expand_path(File.join(File.dirname(__FILE__), 'transport', '*.rb'))].each do |file| next if file.start_with?('.') || File.directory?(file) require File.expand_path(file) end