Hprose-ruby与Rails结合使用心得

Hprose是一个不错在RPC协议引擎,开源、简洁、高效、易用,支持多种语言。下面是选取Hprose-ruby与Rails项目结合的一个测试,使用了Rails的middleware方式实现。

  1. 首先使用rails new hprose-rails新建一个项目;
  2. 编辑Gemfile文件加入uuidtools、hprose两个gem,需要跨域的同学建议使用rack-cors;
gem 'sqlite3'
gem 'uuidtools'
gem 'hprose'
gem 'rack-cors', :require => 'rack/cors'
  1. 在app目录下建立一个新的middleware目录,在该目录下建立一个data_port.rb文件;
#encoding: UTF-8
def hello(name)
  'Hello '+name+'!'
end

def get_user(id)
  User.find(id).as_json
end

def get_users_json
  User.all.as_json
end

class DataPort
  def initialize(app)
    @app = app
  end
  def call(env)
    if env['PATH_INFO'] == '/data_port/index'
      hprose_server = HproseHttpService.new
      # hprose_server.crossdomain = true
      hprose_server.add('hello')
      hprose_server.add('get_user')
      hprose_server.add('get_users_json')
      hprose_server.call(env)
    else
      @app.call(env)
    end
  end
end
  1. 编辑config/application.rb,加入以下代码,如果跨越使用rack-cors的同学,记得在resource中加入:credentials => true,并同时指定可以跨域的origins域名(不建议使用*通配符,有安全问题,详情请参考rack-cors的说明);
  #rails 5
  config.middleware.insert_before 0, Rack::Cors do
    allow do
      origins 'http://your.permitted.site'
      resource '/data_port/index', :headers => :any, :methods => [:get, :post, :options], :credentials => true
    end
  end

  config.middleware.use DataPort

  #rails3/4
  config.middleware.insert_before 0, 'Rack::Cors' do
    allow do
      origins 'http://your.permitted.site'
      resource '/data_port/index', :headers => :any, :methods => [:get, :post, :options], :credentials => true
    end
  end

  config.middleware.use 'DataPort'
  1. 为了测试数据,在db/development.sqlite3中建一个users表,并在app/models/中建一个user.rb
class User < ActiveRecord::Base
end
  1. 客户端我使用的是Delphi(好久没用,最近又有兴趣捡起来了,呵呵)。当然,你也可以用ruby、javascript或其他你熟悉的语音,这个就是hprose多语言支持的优势。
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, HproseCommon,
  HproseClient, HproseHttpClient, Vcl.Grids;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure FormDeactivate(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  {TUser = class
    Id: Integer;
    Name: String;
  end;}

var
  Form1: TForm1;
  Client: THproseHttpClient;

implementation

{$R *.dfm}

uses System.json;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Client := THproseHttpClient.Create(nil);
  Client.URI := 'http://localhost:3000/data_port/index';
  //Client.URI := 'http://hprose.com/example/'
end;

procedure TForm1.FormDeactivate(Sender: TObject);
begin
  Client.FreeOnRelease;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    ShowMessage(VarToStr(Client.Invoke('hello', ['中文'])));
  except
    on E:Exception do
      ShowMessage(E.ClassName+': '+E.Message);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  InvokeResult: Variant;
  users: IList;
  user: IMap;
  I: Integer;
  J: Integer;
begin
  try
    InvokeResult:=Client.Invoke('get_users_json');
    if VarIsList(InvokeResult) then
      begin
        ShowMessage('Invoke result is a IMapList.');
        users := VarToList(InvokeResult);
        StringGrid1.RowCount := users.Count+1;
        for I := 0 to users.Count-1 do begin
          user := VarToMap(users.Item[I]);
          for J := 0 to user.Keys.Count-1 do begin
            if I=0 then begin
              StringGrid1.ColCount := user.Keys.Count;
              StringGrid1.Rows[I][J] := user.Keys[J];
            end;
            StringGrid1.Rows[I+1][J] := user.Value[user.Keys[J]];
          end;
        end;
      end
    else
      ShowMessage('Invoke result is *NOT* a IMapList.');
  except
    on E:Exception do
      ShowMessage(E.ClassName+': '+E.Message);
  end;
end;

end.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容