├── README.md ├── lib ├── libluabitwise.so ├── libluabpack.so ├── liblualongnumber.so └── resty │ └── thrift │ ├── GenericObjectPool.lua │ ├── Object.lua │ ├── RpcClient.lua │ ├── RpcClientFactory.lua │ ├── thrift-idl │ ├── lua_test_TestService.lua │ └── lua_test_ttypes.lua │ └── thrift-lua │ ├── TBinaryProtocol.lua │ ├── TBufferedTransport.lua │ ├── TFramedTransport.lua │ ├── TMemoryBuffer.lua │ ├── TProtocol.lua │ ├── TServer.lua │ ├── TSocket.lua │ ├── TTransport.lua │ └── Thrift.lua └── t ├── lua_test_TestService.lua ├── lua_test_ttypes.lua ├── test.lua └── test.thrift /README.md: -------------------------------------------------------------------------------- 1 | Name 2 | === 3 | lua-resty-thrift - Lua thrift client driver for the ngx_lua based on the cosocket API 4 | 5 | Synopsis 6 | === 7 | 8 | *nginx.conf:* 9 | ```lua 10 | 11 | server { 12 | location /test{ 13 | content_by_lua ' 14 | local GenericObjectPool = require "resty.thrift.GenericObjectPool" 15 | local TestServiceClient = require "resty.thrift.thrift-idl.lua_test_TestService" 16 | local ngx = ngx 17 | local client = GenericObjectPool:connection(TestServiceClient,'127.0.0.1',9090) 18 | local res = client:say('thrift') 19 | GenericObjectPool:returnConnection(client) 20 | ngx.say(res) 21 | '; 22 | } 23 | 24 | } 25 | 26 | ``` 27 | 28 | *thrift:* 29 | ```thrift 30 | namespace java com.test.thrift 31 | namespace lua lua_test 32 | 33 | service TestService { 34 | string say(1:string request) 35 | } 36 | ``` 37 | 38 | 1. 将本项目lib目录下的resty目录拷贝到openresty的安装目录 39 | :> cp lib/resty /${openresty.path}/lualib/ 40 | 2. create thrift lua client (thrift 0.9.3) 41 | 用thrift命令生成thrift客户端 42 | :> thrift gen -lua tets.thrift 43 | 3. 将生成的文件拷贝openresty安装目录下的lualib/resty/thrift/thrift-idl/目录 44 | :>cp gen-lua/*_Service.lua /${openresty.path}/lualib/resty/thrift/thrift-idl/ 45 | 4. :> cp gen-lua/*_ttypes.lua /${openresty.path}/lualib/resty/thrift/thrift-idl/ 46 | 5. Replace *_Service.lua *_Service.lua `require` 47 | 由于thrift生成的文件都是全局变量,而openresty建议使用的是local变量,因此需要把生成的文件变量改掉。 48 | *_ttypes.lua: 49 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' -- local 方式引入变量 50 | local TType = Thrift[1] -- TType 变量被存放在Thrift数组里,下面变量同理 51 | local TMessageType = Thrift[2] 52 | local __TObject = Thrift[3] 53 | local TException = Thrift[4] 54 | local TApplicationException = Thrift[5] 55 | local __TClient = Thrift[6] 56 | 57 | *_Service.lua: 58 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 59 | local TType = Thrift[1] 60 | local TMessageType = Thrift[2] 61 | local __TObject = Thrift[3] 62 | local TException = Thrift[4] 63 | local TApplicationException = Thrift[5] 64 | local __TClient = Thrift[6] 65 | 6. 拷贝本项目下的所有so包到/usr/local/lib/ 如果该目录不在系统加载so包的默认设置里,可以手动一下,或者将so包放到/usr/lib/里 66 | :> cp lua-resty-thrift/lib/*.so /usr/local/lib/ 67 | 7. 添加so包后需要让so包被加载 68 | :> ldconfig 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /lib/libluabitwise.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiajunsongfan/lua-resty-thrift/d039b4b38ce69f5af89a7e26ef1acd2db166b101/lib/libluabitwise.so -------------------------------------------------------------------------------- /lib/libluabpack.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiajunsongfan/lua-resty-thrift/d039b4b38ce69f5af89a7e26ef1acd2db166b101/lib/libluabpack.so -------------------------------------------------------------------------------- /lib/liblualongnumber.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiajunsongfan/lua-resty-thrift/d039b4b38ce69f5af89a7e26ef1acd2db166b101/lib/liblualongnumber.so -------------------------------------------------------------------------------- /lib/resty/thrift/GenericObjectPool.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --Author: xiajun 3 | --Date: 20151120 4 | -- 5 | local Object = require 'resty.thrift.Object' 6 | local RpcClientFactory = require 'resty.thrift.RpcClientFactory' 7 | local ngx = ngx 8 | local GenericObjectPool = Object:new({ 9 | __type = 'GenericObjectPool', 10 | maxTotal = 100, 11 | maxIdleTime = 60000 12 | }) 13 | function GenericObjectPool:init(conf) 14 | end 15 | -- 16 | --从连接池获取rpc客户端 17 | --ngx nginx容器变量 18 | -- 19 | function GenericObjectPool:connection(thriftClient,ip,port) 20 | local client = RpcClientFactory:createClient(thriftClient,ip,port) 21 | return client 22 | end 23 | -- 24 | --回收连接资源到连接池 25 | --client rpc客户端对象 26 | -- 27 | function GenericObjectPool:returnConnection(client) 28 | if(client ~= nil)then 29 | if (client.iprot.trans.trans:isOpen())then 30 | client.iprot.trans.trans:setKeepalive(self.maxIdleTime, self.maxTotal) 31 | else 32 | ngx.log(ngx.ERR,"return rpc client fail ,socket close.") 33 | end 34 | end 35 | end 36 | -- 37 | --设置连接池的大小 38 | --Maxtotal 连接池大小 39 | -- 40 | function GenericObjectPool:setMaxTotal(maxTotal) 41 | self.maxTotal = maxTotal 42 | end 43 | function GenericObjectPool:clear() 44 | 45 | end 46 | function GenericObjectPool:remove() 47 | 48 | end 49 | return GenericObjectPool 50 | -------------------------------------------------------------------------------- /lib/resty/thrift/Object.lua: -------------------------------------------------------------------------------- 1 | -- 2 | ----Author: xiajun 3 | ----Date: 20151120 4 | ---- 5 | function ttype(obj) 6 | if type(obj) == 'table' and obj.__type and type(obj.__type) == 'string' then 7 | return obj.__type 8 | end 9 | return type(obj) 10 | end 11 | function __obj_index(self, key) 12 | local obj = rawget(self, key) 13 | if obj ~=nil then 14 | return obj 15 | end 16 | local p = rawget(self,'__parent') 17 | if p then 18 | return __obj_index(p,key) 19 | end 20 | return nil 21 | end 22 | local Object = { 23 | __type = 'Object', 24 | __mt = { 25 | __index = __obj_index 26 | } 27 | } 28 | function Object:new(init_obj) 29 | local obj = {} 30 | if ttype(obj) == 'table' then 31 | obj = init_obj 32 | end 33 | obj.__parent = self 34 | setmetatable(obj,Object.__mt) 35 | return obj 36 | end 37 | function Object:ttype() 38 | if self and self.__type then 39 | return self.__type 40 | end 41 | return type(self) 42 | end 43 | return Object 44 | -------------------------------------------------------------------------------- /lib/resty/thrift/RpcClient.lua: -------------------------------------------------------------------------------- 1 | -- 2 | ----Author: xiajun 3 | ----Date: 20151020 4 | ---- 5 | local TSocket = require "resty.thrift.thrift-lua.TSocket" 6 | local TFramedTransport = require "resty.thrift.thrift-lua.TFramedTransport" 7 | local TBinaryProtocol = require "resty.thrift.thrift-lua.TBinaryProtocol" 8 | local Object = require "resty.thrift.Object" 9 | 10 | local RpcClient = Object:new({ 11 | __type = 'RpcClient', 12 | timeout = 1001, 13 | readTimeout = 500 14 | }) 15 | 16 | --初始化RPC连接 17 | function RpcClient:init(ip,port) 18 | local socket = TSocket:new{ 19 | host = ip, 20 | port = port, 21 | readTimeout = self.readTimeout 22 | } 23 | socket:setTimeout(self.timeout) 24 | local transport = TFramedTransport:new{ 25 | trans = socket 26 | } 27 | local protocol = TBinaryProtocol:new{ 28 | trans = transport 29 | } 30 | transport:open() 31 | return protocol; 32 | end 33 | --创建RPC客户端 34 | function RpcClient:createClient(thriftClient)end 35 | return RpcClient 36 | -------------------------------------------------------------------------------- /lib/resty/thrift/RpcClientFactory.lua: -------------------------------------------------------------------------------- 1 | -- 2 | ----Author: xiajun 3 | ----Date: 20151020 4 | ---- 5 | local RpcClient = require "resty.thrift.RpcClient" 6 | --local TestServiceClient = require "resty.thrift.thrift-idl.lua_test_TestService" 7 | local RpcClientFactory = RpcClient:new({ 8 | __type = 'Client' 9 | }) 10 | function RpcClientFactory:createClient(thriftClient,ip,port) 11 | local protocol=self:init(ip,port) 12 | local client = thriftClient:new{ 13 | iprot = protocol, 14 | oprot = protocol 15 | } 16 | return client 17 | end 18 | return RpcClientFactory 19 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-idl/lua_test_TestService.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Autogenerated by Thrift 3 | -- 4 | -- DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | -- @generated 6 | -- 7 | 8 | 9 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 10 | local TType = Thrift[1] 11 | local TMessageType = Thrift[2] 12 | local __TObject = Thrift[3] 13 | local TException = Thrift[4] 14 | local TApplicationException = Thrift[5] 15 | local __TClient = Thrift[6] 16 | local types = require 'resty.thrift.thrift-idl.lua_test_ttypes' 17 | local say_args = nil --要在上面定义该变量,不然在send_say方法中找不到 18 | local say_result = nil 19 | local TestServiceClient = __TObject.new(__TClient, { 20 | __type = 'TestServiceClient' 21 | }) 22 | 23 | function TestServiceClient:say(request) 24 | self:send_say(request) 25 | return self:recv_say(request) 26 | end 27 | 28 | function TestServiceClient:send_say(request) 29 | self.oprot:writeMessageBegin('say', TMessageType.CALL, self._seqid) 30 | local args = say_args:new{} 31 | args.request = request 32 | args:write(self.oprot) 33 | self.oprot:writeMessageEnd() 34 | self.oprot.trans:flush() 35 | end 36 | 37 | function TestServiceClient:recv_say(request) 38 | local fname, mtype, rseqid = self.iprot:readMessageBegin() 39 | if mtype == TMessageType.EXCEPTION then 40 | local x = TApplicationException:new{} 41 | x:read(self.iprot) 42 | self.iprot:readMessageEnd() 43 | error(x) 44 | end 45 | local result = say_result:new{} 46 | result:read(self.iprot) 47 | self.iprot:readMessageEnd() 48 | if result.success then 49 | return result.success 50 | end 51 | error(TApplicationException:new{errorCode = TApplicationException.MISSING_RESULT}) 52 | end 53 | local TestServiceIface = __TObject:new{ 54 | __type = 'TestServiceIface' 55 | } 56 | 57 | 58 | local TestServiceProcessor = __TObject.new(__TProcessor 59 | , { 60 | __type = 'TestServiceProcessor' 61 | }) 62 | 63 | function TestServiceProcessor:process(iprot, oprot, server_ctx) 64 | local name, mtype, seqid = iprot:readMessageBegin() 65 | local func_name = 'process_' .. name 66 | if not self[func_name] or ttype(self[func_name]) ~= 'function' then 67 | iprot:skip(TType.STRUCT) 68 | iprot:readMessageEnd() 69 | x = TApplicationException:new{ 70 | errorCode = TApplicationException.UNKNOWN_METHOD 71 | } 72 | oprot:writeMessageBegin(name, TMessageType.EXCEPTION, seqid) 73 | x:write(oprot) 74 | oprot:writeMessageEnd() 75 | oprot.trans:flush() 76 | else 77 | self[func_name](self, seqid, iprot, oprot, server_ctx) 78 | end 79 | end 80 | 81 | function TestServiceProcessor:process_say(seqid, iprot, oprot, server_ctx) 82 | local args = say_args:new{} 83 | local reply_type = TMessageType.REPLY 84 | args:read(iprot) 85 | iprot:readMessageEnd() 86 | local result = say_result:new{} 87 | local status, res = pcall(self.handler.say, self.handler, args.request) 88 | if not status then 89 | reply_type = TMessageType.EXCEPTION 90 | result = TApplicationException:new{message = res} 91 | else 92 | result.success = res 93 | end 94 | oprot:writeMessageBegin('say', reply_type, seqid) 95 | result:write(oprot) 96 | oprot:writeMessageEnd() 97 | oprot.trans:flush() 98 | end 99 | 100 | -- HELPER FUNCTIONS AND STRUCTURES 101 | 102 | say_args = __TObject:new{ 103 | request 104 | } 105 | 106 | function say_args:read(iprot) 107 | iprot:readStructBegin() 108 | while true do 109 | local fname, ftype, fid = iprot:readFieldBegin() 110 | if ftype == TType.STOP then 111 | break 112 | elseif fid == 1 then 113 | if ftype == TType.STRING then 114 | self.request = iprot:readString() 115 | else 116 | iprot:skip(ftype) 117 | end 118 | else 119 | iprot:skip(ftype) 120 | end 121 | iprot:readFieldEnd() 122 | end 123 | iprot:readStructEnd() 124 | end 125 | 126 | function say_args:write(oprot) 127 | oprot:writeStructBegin('say_args') 128 | if self.request then 129 | oprot:writeFieldBegin('request', TType.STRING, 1) 130 | oprot:writeString(self.request) 131 | oprot:writeFieldEnd() 132 | end 133 | oprot:writeFieldStop() 134 | oprot:writeStructEnd() 135 | end 136 | 137 | say_result = __TObject:new{ 138 | success 139 | } 140 | 141 | function say_result:read(iprot) 142 | iprot:readStructBegin() 143 | while true do 144 | local fname, ftype, fid = iprot:readFieldBegin() 145 | if ftype == TType.STOP then 146 | break 147 | elseif fid == 0 then 148 | if ftype == TType.STRING then 149 | self.success = iprot:readString() 150 | else 151 | iprot:skip(ftype) 152 | end 153 | else 154 | iprot:skip(ftype) 155 | end 156 | iprot:readFieldEnd() 157 | end 158 | iprot:readStructEnd() 159 | end 160 | 161 | function say_result:write(oprot) 162 | oprot:writeStructBegin('say_result') 163 | if self.success then 164 | oprot:writeFieldBegin('success', TType.STRING, 0) 165 | oprot:writeString(self.success) 166 | oprot:writeFieldEnd() 167 | end 168 | oprot:writeFieldStop() 169 | oprot:writeStructEnd() 170 | end 171 | return TestServiceClient 172 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-idl/lua_test_ttypes.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Autogenerated by Thrift 3 | -- 4 | -- DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | -- @generated 6 | -- 7 | 8 | 9 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 10 | local TType = Thrift[1] 11 | local TMessageType = Thrift[2] 12 | local __TObject = Thrift[3] 13 | local TException = Thrift[4] 14 | local TApplicationException = Thrift[5] 15 | local __TClient = Thrift[6] 16 | 17 | local TestServiceClient = __TObject.new(__TClient, { 18 | __type = 'TestServiceClient' 19 | }) 20 | 21 | function TestServiceClient:say(request) 22 | self:send_say(request) 23 | return self:recv_say(request) 24 | end 25 | 26 | function TestServiceClient:send_say(request) 27 | self.oprot:writeMessageBegin('say', TMessageType.CALL, self._seqid) 28 | local args = say_args:new{} 29 | args.request = request 30 | args:write(self.oprot) 31 | self.oprot:writeMessageEnd() 32 | self.oprot.trans:flush() 33 | end 34 | 35 | function TestServiceClient:recv_say(request) 36 | local fname, mtype, rseqid = self.iprot:readMessageBegin() 37 | if mtype == TMessageType.EXCEPTION then 38 | local x = TApplicationException:new{} 39 | x:read(self.iprot) 40 | self.iprot:readMessageEnd() 41 | error(x) 42 | end 43 | local result = say_result:new{} 44 | result:read(self.iprot) 45 | self.iprot:readMessageEnd() 46 | if result.success then 47 | return result.success 48 | end 49 | error(TApplicationException:new{errorCode = TApplicationException.MISSING_RESULT}) 50 | end 51 | local TestServiceIface = __TObject:new{ 52 | __type = 'TestServiceIface' 53 | } 54 | 55 | 56 | local TestServiceProcessor = __TObject.new(__TProcessor 57 | , { 58 | __type = 'TestServiceProcessor' 59 | }) 60 | 61 | function TestServiceProcessor:process(iprot, oprot, server_ctx) 62 | local name, mtype, seqid = iprot:readMessageBegin() 63 | local func_name = 'process_' .. name 64 | if not self[func_name] or ttype(self[func_name]) ~= 'function' then 65 | iprot:skip(TType.STRUCT) 66 | iprot:readMessageEnd() 67 | x = TApplicationException:new{ 68 | errorCode = TApplicationException.UNKNOWN_METHOD 69 | } 70 | oprot:writeMessageBegin(name, TMessageType.EXCEPTION, seqid) 71 | x:write(oprot) 72 | oprot:writeMessageEnd() 73 | oprot.trans:flush() 74 | else 75 | self[func_name](self, seqid, iprot, oprot, server_ctx) 76 | end 77 | end 78 | 79 | function TestServiceProcessor:process_say(seqid, iprot, oprot, server_ctx) 80 | local args = say_args:new{} 81 | local reply_type = TMessageType.REPLY 82 | args:read(iprot) 83 | iprot:readMessageEnd() 84 | local result = say_result:new{} 85 | local status, res = pcall(self.handler.say, self.handler, args.request) 86 | if not status then 87 | reply_type = TMessageType.EXCEPTION 88 | result = TApplicationException:new{message = res} 89 | else 90 | result.success = res 91 | end 92 | oprot:writeMessageBegin('say', reply_type, seqid) 93 | result:write(oprot) 94 | oprot:writeMessageEnd() 95 | oprot.trans:flush() 96 | end 97 | 98 | -- HELPER FUNCTIONS AND STRUCTURES 99 | 100 | local say_args = __TObject:new{ 101 | request 102 | } 103 | 104 | function say_args:read(iprot) 105 | iprot:readStructBegin() 106 | while true do 107 | local fname, ftype, fid = iprot:readFieldBegin() 108 | if ftype == TType.STOP then 109 | break 110 | elseif fid == 1 then 111 | if ftype == TType.STRING then 112 | self.request = iprot:readString() 113 | else 114 | iprot:skip(ftype) 115 | end 116 | else 117 | iprot:skip(ftype) 118 | end 119 | iprot:readFieldEnd() 120 | end 121 | iprot:readStructEnd() 122 | end 123 | 124 | function say_args:write(oprot) 125 | oprot:writeStructBegin('say_args') 126 | if self.request then 127 | oprot:writeFieldBegin('request', TType.STRING, 1) 128 | oprot:writeString(self.request) 129 | oprot:writeFieldEnd() 130 | end 131 | oprot:writeFieldStop() 132 | oprot:writeStructEnd() 133 | end 134 | 135 | local say_result = __TObject:new{ 136 | success 137 | } 138 | 139 | function say_result:read(iprot) 140 | iprot:readStructBegin() 141 | while true do 142 | local fname, ftype, fid = iprot:readFieldBegin() 143 | if ftype == TType.STOP then 144 | break 145 | elseif fid == 0 then 146 | if ftype == TType.STRING then 147 | self.success = iprot:readString() 148 | else 149 | iprot:skip(ftype) 150 | end 151 | else 152 | iprot:skip(ftype) 153 | end 154 | iprot:readFieldEnd() 155 | end 156 | iprot:readStructEnd() 157 | end 158 | 159 | function say_result:write(oprot) 160 | oprot:writeStructBegin('say_result') 161 | if self.success then 162 | oprot:writeFieldBegin('success', TType.STRING, 0) 163 | oprot:writeString(self.success) 164 | oprot:writeFieldEnd() 165 | end 166 | oprot:writeFieldStop() 167 | oprot:writeStructEnd() 168 | end 169 | return TestServiceClient 170 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TBinaryProtocol.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | local libluabpack = require "libluabpack" 20 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 21 | local TType = Thrift[1] 22 | local __TObject = Thrift[3] 23 | 24 | local TBinaryProtocol = __TObject:new{ 25 | __type = 'TBinaryProtocol', 26 | VERSION_MASK = -65536, -- 0xffff0000 27 | VERSION_1 = -2147418112, -- 0x80010000 28 | TYPE_MASK = 0x000000ff, 29 | strictRead = false, 30 | strictWrite = true 31 | } 32 | 33 | function TBinaryProtocol:writeMessageBegin(name, ttype, seqid) 34 | if self.strictWrite then 35 | self:writeI32(bit.bor(TBinaryProtocol.VERSION_1, ttype)) 36 | self:writeString(name) 37 | self:writeI32(seqid) 38 | else 39 | self:writeString(name) 40 | self:writeByte(ttype) 41 | self:writeI32(seqid) 42 | end 43 | end 44 | 45 | function TBinaryProtocol:writeMessageEnd() 46 | end 47 | 48 | function TBinaryProtocol:writeStructBegin(name) 49 | end 50 | 51 | function TBinaryProtocol:writeStructEnd() 52 | end 53 | 54 | function TBinaryProtocol:writeFieldBegin(name, ttype, id) 55 | self:writeByte(ttype) 56 | self:writeI16(id) 57 | end 58 | 59 | function TBinaryProtocol:writeFieldEnd() 60 | end 61 | 62 | function TBinaryProtocol:writeFieldStop() 63 | self:writeByte(TType.STOP); 64 | end 65 | 66 | function TBinaryProtocol:writeMapBegin(ktype, vtype, size) 67 | self:writeByte(ktype) 68 | self:writeByte(vtype) 69 | self:writeI32(size) 70 | end 71 | 72 | function TBinaryProtocol:writeMapEnd() 73 | end 74 | 75 | function TBinaryProtocol:writeListBegin(etype, size) 76 | self:writeByte(etype) 77 | self:writeI32(size) 78 | end 79 | 80 | function TBinaryProtocol:writeListEnd() 81 | end 82 | 83 | function TBinaryProtocol:writeSetBegin(etype, size) 84 | self:writeByte(etype) 85 | self:writeI32(size) 86 | end 87 | 88 | function TBinaryProtocol:writeSetEnd() 89 | end 90 | 91 | function TBinaryProtocol:writeBool(bool) 92 | if bool then 93 | self:writeByte(1) 94 | else 95 | self:writeByte(0) 96 | end 97 | end 98 | 99 | function TBinaryProtocol:writeByte(byte) 100 | local buff = libluabpack.bpack('c', byte) 101 | self.trans:write(buff) 102 | end 103 | 104 | function TBinaryProtocol:writeI16(i16) 105 | local buff = libluabpack.bpack('s', i16) 106 | self.trans:write(buff) 107 | end 108 | 109 | function TBinaryProtocol:writeI32(i32) 110 | local buff = libluabpack.bpack('i', i32) 111 | self.trans:write(buff) 112 | end 113 | 114 | function TBinaryProtocol:writeI64(i64) 115 | local buff = libluabpack.bpack('l', i64) 116 | self.trans:write(buff) 117 | end 118 | 119 | function TBinaryProtocol:writeDouble(dub) 120 | local buff = libluabpack.bpack('d', dub) 121 | self.trans:write(buff) 122 | end 123 | 124 | function TBinaryProtocol:writeString(str) 125 | -- Should be utf-8 126 | self:writeI32(string.len(str)) 127 | self.trans:write(str) 128 | end 129 | 130 | function TBinaryProtocol:readMessageBegin() 131 | local sz, ttype, name, seqid = self:readI32() 132 | if sz < 0 then 133 | local version = bit.band(sz, TBinaryProtocol.VERSION_MASK) 134 | if version ~= TBinaryProtocol.VERSION_1 then 135 | terror(TProtocolException:new{ 136 | message = 'Bad version in readMessageBegin: ' .. sz 137 | }) 138 | end 139 | ttype = bit.band(sz, TBinaryProtocol.TYPE_MASK) 140 | name = self:readString() 141 | seqid = self:readI32() 142 | else 143 | if self.strictRead then 144 | terror(TProtocolException:new{message = 'No protocol version header'}) 145 | end 146 | name = self.trans:readAll(sz) 147 | ttype = self:readByte() 148 | seqid = self:readI32() 149 | end 150 | return name, ttype, seqid 151 | end 152 | 153 | function TBinaryProtocol:readMessageEnd() 154 | end 155 | 156 | function TBinaryProtocol:readStructBegin() 157 | return nil 158 | end 159 | 160 | function TBinaryProtocol:readStructEnd() 161 | end 162 | 163 | function TBinaryProtocol:readFieldBegin() 164 | local ttype = self:readByte() 165 | if ttype == TType.STOP then 166 | return nil, ttype, 0 167 | end 168 | local id = self:readI16() 169 | return nil, ttype, id 170 | end 171 | 172 | function TBinaryProtocol:readFieldEnd() 173 | end 174 | 175 | function TBinaryProtocol:readMapBegin() 176 | local ktype = self:readByte() 177 | local vtype = self:readByte() 178 | local size = self:readI32() 179 | return ktype, vtype, size 180 | end 181 | 182 | function TBinaryProtocol:readMapEnd() 183 | end 184 | 185 | function TBinaryProtocol:readListBegin() 186 | local etype = self:readByte() 187 | local size = self:readI32() 188 | return etype, size 189 | end 190 | 191 | function TBinaryProtocol:readListEnd() 192 | end 193 | 194 | function TBinaryProtocol:readSetBegin() 195 | local etype = self:readByte() 196 | local size = self:readI32() 197 | return etype, size 198 | end 199 | 200 | function TBinaryProtocol:readSetEnd() 201 | end 202 | 203 | function TBinaryProtocol:readBool() 204 | local byte = self:readByte() 205 | if byte == 0 then 206 | return false 207 | end 208 | return true 209 | end 210 | 211 | function TBinaryProtocol:readByte() 212 | local buff = self.trans:readAll(1) 213 | local val = libluabpack.bunpack('c', buff) 214 | return val 215 | end 216 | 217 | function TBinaryProtocol:readI16() 218 | local buff = self.trans:readAll(2) 219 | local val = libluabpack.bunpack('s', buff) 220 | return val 221 | end 222 | 223 | function TBinaryProtocol:readI32() 224 | local buff = self.trans:readAll(4) 225 | local val = libluabpack.bunpack('i', buff) 226 | return val 227 | end 228 | 229 | function TBinaryProtocol:readI64() 230 | local buff = self.trans:readAll(8) 231 | local val = libluabpack.bunpack('l', buff) 232 | return val 233 | end 234 | 235 | function TBinaryProtocol:readDouble() 236 | local buff = self.trans:readAll(8) 237 | local val = libluabpack.bunpack('d', buff) 238 | return val 239 | end 240 | 241 | function TBinaryProtocol:readString() 242 | local len = self:readI32() 243 | local str = self.trans:readAll(len) 244 | return str 245 | end 246 | 247 | --local TBinaryProtocolFactory = TProtocolFactory:new{ 248 | -- __type = 'TBinaryProtocolFactory', 249 | -- strictRead = false 250 | --} 251 | -- 252 | --function TBinaryProtocolFactory:getProtocol(trans) 253 | -- -- TODO Enforce that this must be a transport class (ie not a bool) 254 | -- if not trans then 255 | -- terror(TProtocolException:new{ 256 | -- message = 'Must supply a transport to ' .. ttype(self) 257 | -- }) 258 | -- end 259 | -- return TBinaryProtocol:new{ 260 | -- trans = trans, 261 | -- strictRead = self.strictRead, 262 | -- strictWrite = true 263 | -- } 264 | --end 265 | return TBinaryProtocol 266 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TBufferedTransport.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | 20 | local TTransport = require "resty.thrift.thrift-lua.TTransport" 21 | local TTransportException = TTransport[1] 22 | local TTransportBase = TTransport[2] 23 | local TServerTransportBase = TTransport[3] 24 | local TTransportFactoryBase = TTransport[4] 25 | 26 | local TBufferedTransport = TTransportBase:new{ 27 | __type = 'TBufferedTransport', 28 | rBufSize = 2048, 29 | wBufSize = 2048, 30 | wBuf = '', 31 | rBuf = '' 32 | } 33 | 34 | function TBufferedTransport:new(obj) 35 | if ttype(obj) ~= 'table' then 36 | error(ttype(self) .. 'must be initialized with a table') 37 | end 38 | 39 | -- Ensure a transport is provided 40 | if not obj.trans then 41 | error('You must provide ' .. ttype(self) .. ' with a trans') 42 | end 43 | 44 | return TTransportBase:new(obj) 45 | end 46 | 47 | function TBufferedTransport:isOpen() 48 | return self.trans:isOpen() 49 | end 50 | 51 | function TBufferedTransport:open() 52 | return self.trans:open() 53 | end 54 | 55 | function TBufferedTransport:close() 56 | return self.trans:close() 57 | end 58 | 59 | function TBufferedTransport:read(len) 60 | return self.trans:read(len) 61 | end 62 | 63 | function TBufferedTransport:readAll(len) 64 | return self.trans:readAll(len) 65 | end 66 | 67 | function TBufferedTransport:write(buf) 68 | self.wBuf = self.wBuf .. buf 69 | if string.len(self.wBuf) >= self.wBufSize then 70 | self.trans:write(self.wBuf) 71 | self.wBuf = '' 72 | end 73 | end 74 | 75 | function TBufferedTransport:flush() 76 | if string.len(self.wBuf) > 0 then 77 | self.trans:write(self.wBuf) 78 | self.wBuf = '' 79 | end 80 | end 81 | 82 | local TBufferedTransportFactory = TTransportFactoryBase:new{ 83 | __type = 'TBufferedTransportFactory' 84 | } 85 | 86 | function TBufferedTransportFactory:getTransport(trans) 87 | if not trans then 88 | terror(TTransportException:new{ 89 | message = 'Must supply a transport to ' .. ttype(self) 90 | }) 91 | end 92 | return TBufferedTransport:new{ 93 | trans = trans 94 | } 95 | end 96 | return TBufferedTransport 97 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TFramedTransport.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | local libluabpack = require "libluabpack" 20 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 21 | local __TObject = Thrift[3] 22 | 23 | local TFramedTransport = __TObject:new{ 24 | __type = 'TFramedTransport', 25 | doRead = true, 26 | doWrite = true, 27 | wBuf = '', 28 | rBuf = '' 29 | } 30 | 31 | function TFramedTransport:setTrans(trans) 32 | if ttype(trans) ~= 'table' then 33 | error(ttype(self) .. 'must be initialized with a table') 34 | end 35 | 36 | -- Ensure a transport is provided 37 | if not trans then 38 | error('You must provide ' .. ttype(self) .. ' with a trans') 39 | end 40 | self.trans = trans 41 | end 42 | 43 | function TFramedTransport:isOpen() 44 | return self.trans:isOpen() 45 | end 46 | 47 | function TFramedTransport:open() 48 | return self.trans:open() 49 | end 50 | 51 | function TFramedTransport:close() 52 | return self.trans:close() 53 | end 54 | 55 | function TFramedTransport:read(len) 56 | if string.len(self.rBuf) == 0 then 57 | self:__readFrame() 58 | end 59 | 60 | if self.doRead == false then 61 | return self.trans:read(len) 62 | end 63 | 64 | if len > string.len(self.rBuf) then 65 | local val = self.rBuf 66 | self.rBuf = '' 67 | return val 68 | end 69 | 70 | local val = string.sub(self.rBuf, 0, len) 71 | self.rBuf = string.sub(self.rBuf, len+1) 72 | return val 73 | end 74 | 75 | function TFramedTransport:__readFrame() 76 | local buf = self.trans:readAll(4) 77 | local frame_len = libluabpack.bunpack('i', buf) 78 | self.rBuf = self.trans:readAll(frame_len) 79 | end 80 | 81 | function TFramedTransport:readAll(len) 82 | return self:read(len) 83 | end 84 | 85 | function TFramedTransport:write(buf, len) 86 | if self.doWrite == false then 87 | return self.trans:write(buf, len) 88 | end 89 | 90 | if len and len < string.len(buf) then 91 | buf = string.sub(buf, 0, len) 92 | end 93 | self.wBuf = self.wBuf .. buf 94 | end 95 | 96 | function TFramedTransport:flush() 97 | if self.doWrite == false then 98 | return self.trans:flush() 99 | end 100 | 101 | -- If the write fails we still want wBuf to be clear 102 | local tmp = self.wBuf 103 | self.wBuf = '' 104 | local frame_len_buf = libluabpack.bpack("i", string.len(tmp)) 105 | self.trans:write(frame_len_buf) 106 | self.trans:write(tmp) 107 | self.trans:flush() 108 | end 109 | 110 | --local TFramedTransportFactory = TTransportFactoryBase:new{ 111 | -- __type = 'TFramedTransportFactory' 112 | --} 113 | --function TFramedTransportFactory:getTransport(trans) 114 | -- if not trans then 115 | -- terror(TProtocolException:new{ 116 | -- message = 'Must supply a transport to ' .. ttype(self) 117 | -- }) 118 | -- end 119 | -- return TFramedTransport:new{trans = trans} 120 | --end 121 | return TFramedTransport 122 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TMemoryBuffer.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | local TTransport = require "resty.thrift.thrift-lua.TTransport" 20 | local TTransportException = TTransport[1] 21 | local TTransportBase = TTransport[2] 22 | local TServerTransportBase = TTransport[3] 23 | local TTransportFactoryBase = TTransport[4] 24 | 25 | local TMemoryBuffer = TTransportBase:new{ 26 | __type = 'TMemoryBuffer', 27 | buffer = '', 28 | bufferSize = 1024, 29 | wPos = 0, 30 | rPos = 0 31 | } 32 | function TMemoryBuffer:isOpen() 33 | return 1 34 | end 35 | function TMemoryBuffer:open() end 36 | function TMemoryBuffer:close() end 37 | 38 | function TMemoryBuffer:peak() 39 | return self.rPos < self.wPos 40 | end 41 | 42 | function TMemoryBuffer:getBuffer() 43 | return self.buffer 44 | end 45 | 46 | function TMemoryBuffer:resetBuffer(buf) 47 | if buf then 48 | self.buffer = buf 49 | self.bufferSize = string.len(buf) 50 | else 51 | self.buffer = '' 52 | self.bufferSize = 1024 53 | end 54 | self.wPos = string.len(buf) 55 | self.rPos = 0 56 | end 57 | 58 | function TMemoryBuffer:available() 59 | return self.wPos - self.rPos 60 | end 61 | 62 | function TMemoryBuffer:read(len) 63 | local avail = self:available() 64 | if avail == 0 then 65 | return '' 66 | end 67 | 68 | if avail < len then 69 | len = avail 70 | end 71 | 72 | local val = string.sub(self.buffer, self.rPos + 1, self.rPos + len) 73 | self.rPos = self.rPos + len 74 | return val 75 | end 76 | 77 | function TMemoryBuffer:readAll(len) 78 | local avail = self:available() 79 | 80 | if avail < len then 81 | local msg = string.format('Attempt to readAll(%d) found only %d available', 82 | len, avail) 83 | terror(TTransportException:new{message = msg}) 84 | end 85 | -- read should block so we don't need a loop here 86 | return self:read(len) 87 | end 88 | 89 | function TMemoryBuffer:write(buf) 90 | self.buffer = self.buffer .. buf 91 | self.wPos = self.wPos + string.len(buf) 92 | end 93 | 94 | function TMemoryBuffer:flush() end 95 | 96 | return TMemoryBuffer 97 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TProtocol.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 20 | local TType = Thrift[1] 21 | local __TObject = Thrift[3] 22 | local TException = Thrift[4] 23 | 24 | local TProtocolException = TException:new { 25 | UNKNOWN = 0, 26 | INVALID_DATA = 1, 27 | NEGATIVE_SIZE = 2, 28 | SIZE_LIMIT = 3, 29 | BAD_VERSION = 4, 30 | INVALID_PROTOCOL = 5, 31 | DEPTH_LIMIT = 6, 32 | errorCode = 0, 33 | __type = 'TProtocolException' 34 | } 35 | function TProtocolException:__errorCodeToString() 36 | if self.errorCode == self.INVALID_DATA then 37 | return 'Invalid data' 38 | elseif self.errorCode == self.NEGATIVE_SIZE then 39 | return 'Negative size' 40 | elseif self.errorCode == self.SIZE_LIMIT then 41 | return 'Size limit' 42 | elseif self.errorCode == self.BAD_VERSION then 43 | return 'Bad version' 44 | elseif self.errorCode == self.INVALID_PROTOCOL then 45 | return 'Invalid protocol' 46 | elseif self.errorCode == self.DEPTH_LIMIT then 47 | return 'Exceeded size limit' 48 | else 49 | return 'Default (unknown)' 50 | end 51 | end 52 | 53 | local TProtocolBase = __TObject:new{ 54 | __type = 'TProtocolBase', 55 | trans 56 | } 57 | 58 | function TProtocolBase:new(obj) 59 | if ttype(obj) ~= 'table' then 60 | error(ttype(self) .. 'must be initialized with a table') 61 | end 62 | 63 | -- Ensure a transport is provided 64 | if not obj.trans then 65 | error('You must provide ' .. ttype(self) .. ' with a trans') 66 | end 67 | 68 | return __TObject.new(self, obj) 69 | end 70 | 71 | function TProtocolBase:writeMessageBegin(name, ttype, seqid) end 72 | function TProtocolBase:writeMessageEnd() end 73 | function TProtocolBase:writeStructBegin(name) end 74 | function TProtocolBase:writeStructEnd() end 75 | function TProtocolBase:writeFieldBegin(name, ttype, id) end 76 | function TProtocolBase:writeFieldEnd() end 77 | function TProtocolBase:writeFieldStop() end 78 | function TProtocolBase:writeMapBegin(ktype, vtype, size) end 79 | function TProtocolBase:writeMapEnd() end 80 | function TProtocolBase:writeListBegin(ttype, size) end 81 | function TProtocolBase:writeListEnd() end 82 | function TProtocolBase:writeSetBegin(ttype, size) end 83 | function TProtocolBase:writeSetEnd() end 84 | function TProtocolBase:writeBool(bool) end 85 | function TProtocolBase:writeByte(byte) end 86 | function TProtocolBase:writeI16(i16) end 87 | function TProtocolBase:writeI32(i32) end 88 | function TProtocolBase:writeI64(i64) end 89 | function TProtocolBase:writeDouble(dub) end 90 | function TProtocolBase:writeString(str) end 91 | function TProtocolBase:readMessageBegin() end 92 | function TProtocolBase:readMessageEnd() end 93 | function TProtocolBase:readStructBegin() end 94 | function TProtocolBase:readStructEnd() end 95 | function TProtocolBase:readFieldBegin() end 96 | function TProtocolBase:readFieldEnd() end 97 | function TProtocolBase:readMapBegin() end 98 | function TProtocolBase:readMapEnd() end 99 | function TProtocolBase:readListBegin() end 100 | function TProtocolBase:readListEnd() end 101 | function TProtocolBase:readSetBegin() end 102 | function TProtocolBase:readSetEnd() end 103 | function TProtocolBase:readBool() end 104 | function TProtocolBase:readByte() end 105 | function TProtocolBase:readI16() end 106 | function TProtocolBase:readI32() end 107 | function TProtocolBase:readI64() end 108 | function TProtocolBase:readDouble() end 109 | function TProtocolBase:readString() end 110 | 111 | function TProtocolBase:skip(ttype) 112 | if type == TType.STOP then 113 | return 114 | elseif ttype == TType.BOOL then 115 | self:readBool() 116 | elseif ttype == TType.BYTE then 117 | self:readByte() 118 | elseif ttype == TType.I16 then 119 | self:readI16() 120 | elseif ttype == TType.I32 then 121 | self:readI32() 122 | elseif ttype == TType.I64 then 123 | self:readI64() 124 | elseif ttype == TType.DOUBLE then 125 | self:readDouble() 126 | elseif ttype == TType.STRING then 127 | self:readString() 128 | elseif ttype == TType.STRUCT then 129 | local name = self:readStructBegin() 130 | while true do 131 | local name, ttype, id = self:readFieldBegin() 132 | if ttype == TType.STOP then 133 | break 134 | end 135 | self:skip(ttype) 136 | self:readFieldEnd() 137 | end 138 | self:readStructEnd() 139 | elseif ttype == TType.MAP then 140 | local kttype, vttype, size = self:readMapBegin() 141 | for i = 1, size, 1 do 142 | self:skip(kttype) 143 | self:skip(vttype) 144 | end 145 | self:readMapEnd() 146 | elseif ttype == TType.SET then 147 | local ettype, size = self:readSetBegin() 148 | for i = 1, size, 1 do 149 | self:skip(ettype) 150 | end 151 | self:readSetEnd() 152 | elseif ttype == TType.LIST then 153 | local ettype, size = self:readListBegin() 154 | for i = 1, size, 1 do 155 | self:skip(ettype) 156 | end 157 | self:readListEnd() 158 | end 159 | end 160 | 161 | local TProtocolFactory = __TObject:new{ 162 | __type = 'TProtocolFactory', 163 | } 164 | function TProtocolFactory:getProtocol(trans) end 165 | return {TProtocolException,TProtocolBase} 166 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TServer.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | 20 | require 'resty.thrift.thrift-lua.Thrift' 21 | require 'resty.thrift.thrift-lua.TFramedTransport' 22 | require 'resty.thrift.thrift-lua.TBinaryProtocol' 23 | 24 | -- TServer 25 | TServer = __TObject:new{ 26 | __type = 'TServer' 27 | } 28 | 29 | -- 2 possible constructors 30 | -- 1. {processor, serverTransport} 31 | -- 2. {processor, serverTransport, transportFactory, protocolFactory} 32 | function TServer:new(args) 33 | if ttype(args) ~= 'table' then 34 | error('TServer must be initialized with a table') 35 | end 36 | if args.processor == nil then 37 | terror('You must provide ' .. ttype(self) .. ' with a processor') 38 | end 39 | if args.serverTransport == nil then 40 | terror('You must provide ' .. ttype(self) .. ' with a serverTransport') 41 | end 42 | 43 | -- Create the object 44 | local obj = __TObject.new(self, args) 45 | 46 | if obj.transportFactory then 47 | obj.inputTransportFactory = obj.transportFactory 48 | obj.outputTransportFactory = obj.transportFactory 49 | obj.transportFactory = nil 50 | else 51 | obj.inputTransportFactory = TFramedTransportFactory:new{} 52 | obj.outputTransportFactory = obj.inputTransportFactory 53 | end 54 | 55 | if obj.protocolFactory then 56 | obj.inputProtocolFactory = obj.protocolFactory 57 | obj.outputProtocolFactory = obj.protocolFactory 58 | obj.protocolFactory = nil 59 | else 60 | obj.inputProtocolFactory = TBinaryProtocolFactory:new{} 61 | obj.outputProtocolFactory = obj.inputProtocolFactory 62 | end 63 | 64 | -- Set the __server variable in the handler so we can stop the server 65 | obj.processor.handler.__server = self 66 | 67 | return obj 68 | end 69 | 70 | function TServer:setServerEventHandler(handler) 71 | self.serverEventHandler = handler 72 | end 73 | 74 | function TServer:_clientBegin(content, iprot, oprot) 75 | if self.serverEventHandler and 76 | type(self.serverEventHandler.clientBegin) == 'function' then 77 | self.serverEventHandler:clientBegin(iprot, oprot) 78 | end 79 | end 80 | 81 | function TServer:_preServe() 82 | if self.serverEventHandler and 83 | type(self.serverEventHandler.preServe) == 'function' then 84 | self.serverEventHandler:preServe(self.serverTransport:getSocketInfo()) 85 | end 86 | end 87 | 88 | function TServer:_handleException(err) 89 | if string.find(err, 'TTransportException') == nil then 90 | print(err) 91 | end 92 | end 93 | 94 | function TServer:serve() end 95 | function TServer:handle(client) 96 | local itrans, otrans, iprot, oprot, ret, err = 97 | self.inputTransportFactory:getTransport(client), 98 | self.outputTransportFactory:getTransport(client), 99 | self.inputProtocolFactory:getProtocol(client), 100 | self.outputProtocolFactory:getProtocol(client) 101 | 102 | self:_clientBegin(iprot, oprot) 103 | while true do 104 | ret, err = pcall(self.processor.process, self.processor, iprot, oprot) 105 | if ret == false and err then 106 | if not string.find(err, "TTransportException") then 107 | self:_handleException(err) 108 | end 109 | break 110 | end 111 | end 112 | itrans:close() 113 | otrans:close() 114 | end 115 | 116 | function TServer:close() 117 | self.serverTransport:close() 118 | end 119 | 120 | -- TSimpleServer 121 | -- Single threaded server that handles one transport (connection) 122 | TSimpleServer = __TObject:new(TServer, { 123 | __type = 'TSimpleServer', 124 | __stop = false 125 | }) 126 | 127 | function TSimpleServer:serve() 128 | self.serverTransport:listen() 129 | self:_preServe() 130 | while not self.__stop do 131 | client = self.serverTransport:accept() 132 | self:handle(client) 133 | end 134 | self:close() 135 | end 136 | 137 | function TSimpleServer:stop() 138 | self.__stop = true 139 | end 140 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TSocket.lua: -------------------------------------------------------------------------------- 1 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 2 | local tcp = ngx.socket.tcp 3 | local __TObject = Thrift[3] 4 | -- TSocket 5 | local TSocket = __TObject:new{ 6 | __type = 'TSocket', 7 | timeout = 1000, 8 | host = 'localhost', 9 | port = 9090, 10 | handle 11 | } 12 | 13 | function TSocket:isOpen() 14 | if self.handle then 15 | return true 16 | end 17 | return false 18 | end 19 | function TSocket:setTimeout(timeout) 20 | if timeout and ttype(timeout) == 'number' then 21 | if self.handle then 22 | self.handle:settimeout(timeout) 23 | end 24 | self.timeout = timeout 25 | end 26 | end 27 | 28 | function TSocket:close() 29 | if self.handle then 30 | self.handle:close() 31 | self.handle = nil 32 | end 33 | end 34 | 35 | function TSocket:open() 36 | if self.handle then 37 | self:close() 38 | end 39 | local sock = tcp() 40 | local ok, err = sock:connect(self.host, self.port) 41 | if ok then 42 | self.handle = sock 43 | sock:settimeout(self.timeout) 44 | end 45 | 46 | if err then 47 | error("TTransportException: Could not connect to "..self.host .." : "..self.port.."("..err..")") 48 | end 49 | end 50 | 51 | function TSocket:read(len) 52 | local sock = self.handle 53 | sock:settimeout(self.readTimeout) 54 | local buf,err,partial = sock:receive(len) 55 | if err == 'timeout' then 56 | error("TTransportException: TIMED_OUT") 57 | end 58 | if not buf or string.len(buf) ~= len then 59 | error("TTransportException: UNKNOWN ip: "..self.host.." port: "..self.port) 60 | end 61 | return buf 62 | end 63 | 64 | function TSocket:readAll(len) 65 | local buf, have, chunk = '', 0 66 | while have < len do 67 | chunk = self:read(len - have) 68 | have = have + string.len(chunk) 69 | buf = buf .. chunk 70 | 71 | if string.len(chunk) == 0 then 72 | error("TTransportException: end_of_file.") 73 | end 74 | end 75 | return buf 76 | end 77 | 78 | function TSocket:write(buf) 79 | local sock = self.handle 80 | sock:send(buf) 81 | end 82 | 83 | function TSocket:flush() 84 | end 85 | --set socket connection pool 86 | function TSocket:setKeepalive(...) 87 | local sock = self.handle 88 | sock:setkeepalive(...) 89 | end 90 | return TSocket 91 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/TTransport.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 20 | local TType = Thrift[1] 21 | local __TObject = Thrift[3] 22 | local TException = Thrift[4] 23 | 24 | local TTransportException = TException:new { 25 | UNKNOWN = 0, 26 | NOT_OPEN = 1, 27 | ALREADY_OPEN = 2, 28 | TIMED_OUT = 3, 29 | END_OF_FILE = 4, 30 | INVALID_FRAME_SIZE = 5, 31 | INVALID_TRANSFORM = 6, 32 | INVALID_CLIENT_TYPE = 7, 33 | errorCode = 0, 34 | __type = 'TTransportException' 35 | } 36 | 37 | function TTransportException:__errorCodeToString() 38 | if self.errorCode == self.NOT_OPEN then 39 | return 'Transport not open' 40 | elseif self.errorCode == self.ALREADY_OPEN then 41 | return 'Transport already open' 42 | elseif self.errorCode == self.TIMED_OUT then 43 | return 'Transport timed out' 44 | elseif self.errorCode == self.END_OF_FILE then 45 | return 'End of file' 46 | elseif self.errorCode == self.INVALID_FRAME_SIZE then 47 | return 'Invalid frame size' 48 | elseif self.errorCode == self.INVALID_TRANSFORM then 49 | return 'Invalid transform' 50 | elseif self.errorCode == self.INVALID_CLIENT_TYPE then 51 | return 'Invalid client type' 52 | else 53 | return 'Default (unknown)' 54 | end 55 | end 56 | 57 | local TTransportBase = __TObject:new{ 58 | __type = 'TTransportBase' 59 | } 60 | 61 | function TTransportBase:isOpen() end 62 | function TTransportBase:open() end 63 | function TTransportBase:close() end 64 | function TTransportBase:read(len) end 65 | function TTransportBase:readAll(len) 66 | local buf, have, chunk = '', 0 67 | while have < len do 68 | chunk = self:read(len - have) 69 | have = have + string.len(chunk) 70 | buf = buf .. chunk 71 | 72 | if string.len(chunk) == 0 then 73 | terror(TTransportException:new{ 74 | errorCode = TTransportException.END_OF_FILE 75 | }) 76 | end 77 | end 78 | return buf 79 | end 80 | function TTransportBase:write(buf) end 81 | function TTransportBase:flush() end 82 | 83 | local TServerTransportBase = __TObject:new{ 84 | __type = 'TServerTransportBase' 85 | } 86 | function TServerTransportBase:listen() end 87 | function TServerTransportBase:accept() end 88 | function TServerTransportBase:close() end 89 | 90 | local TTransportFactoryBase = __TObject:new{ 91 | __type = 'TTransportFactoryBase' 92 | } 93 | function TTransportFactoryBase:getTransport(trans) 94 | return trans 95 | end 96 | 97 | return {TTransportException,TTransportBase} 98 | -------------------------------------------------------------------------------- /lib/resty/thrift/thrift-lua/Thrift.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Licensed to the Apache Software Foundation (ASF) under one 3 | -- or more contributor license agreements. See the NOTICE file 4 | -- distributed with this work for additional information 5 | -- regarding copyright ownership. The ASF licenses this file 6 | -- to you under the Apache License, Version 2.0 (the 7 | -- "License"); you may not use this file except in compliance 8 | -- with the License. You may obtain a copy of the License at 9 | -- 10 | -- http://www.apache.org/licenses/LICENSE-2.0 11 | -- 12 | -- Unless required by applicable law or agreed to in writing, 13 | -- software distributed under the License is distributed on an 14 | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | -- KIND, either express or implied. See the License for the 16 | -- specific language governing permissions and limitations 17 | -- under the License. 18 | -- 19 | 20 | ---- namespace thrift 21 | --thrift = {} 22 | --setmetatable(thrift, {__index = _G}) --> perf hit for accessing global methods 23 | --setfenv(1, thrift) 24 | 25 | function ttype(obj) 26 | if type(obj) == 'table' and 27 | obj.__type and 28 | type(obj.__type) == 'string' then 29 | return obj.__type 30 | end 31 | return type(obj) 32 | end 33 | 34 | function terror(e) 35 | if e and e.__tostring then 36 | error(e:__tostring()) 37 | return 38 | end 39 | error(e) 40 | end 41 | 42 | function ttable_size(t) 43 | local count = 0 44 | for k, v in pairs(t) do 45 | count = count + 1 46 | end 47 | return count 48 | end 49 | 50 | local version = '0.9.3' 51 | 52 | local TType = { 53 | STOP = 0, 54 | VOID = 1, 55 | BOOL = 2, 56 | BYTE = 3, 57 | I08 = 3, 58 | DOUBLE = 4, 59 | I16 = 6, 60 | I32 = 8, 61 | I64 = 10, 62 | STRING = 11, 63 | UTF7 = 11, 64 | STRUCT = 12, 65 | MAP = 13, 66 | SET = 14, 67 | LIST = 15, 68 | UTF8 = 16, 69 | UTF16 = 17 70 | } 71 | 72 | local TMessageType = { 73 | CALL = 1, 74 | REPLY = 2, 75 | EXCEPTION = 3, 76 | ONEWAY = 4 77 | } 78 | 79 | -- Recursive __index function to achieve inheritance 80 | function __tobj_index(self, key) 81 | local v = rawget(self, key) 82 | if v ~= nil then 83 | return v 84 | end 85 | 86 | local p = rawget(self, '__parent') 87 | if p then 88 | return __tobj_index(p, key) 89 | end 90 | 91 | return nil 92 | end 93 | 94 | -- Basic Thrift-Lua Object 95 | local __TObject = { 96 | __type = '__TObject', 97 | __mt = { 98 | __index = __tobj_index 99 | } 100 | } 101 | function __TObject:new(init_obj) 102 | local obj = {} 103 | if ttype(obj) == 'table' then 104 | obj = init_obj 105 | end 106 | 107 | -- Use the __parent key and the __index function to achieve inheritance 108 | obj.__parent = self 109 | setmetatable(obj, __TObject.__mt) 110 | return obj 111 | end 112 | 113 | -- Return a string representation of any lua variable 114 | function thrift_print_r(t) 115 | local ret = '' 116 | local ltype = type(t) 117 | if (ltype == 'table') then 118 | ret = ret .. '{ ' 119 | for key,value in pairs(t) do 120 | ret = ret .. tostring(key) .. '=' .. thrift_print_r(value) .. ' ' 121 | end 122 | ret = ret .. '}' 123 | elseif ltype == 'string' then 124 | ret = ret .. "'" .. tostring(t) .. "'" 125 | else 126 | ret = ret .. tostring(t) 127 | end 128 | return ret 129 | end 130 | 131 | -- Basic Exception 132 | local TException = __TObject:new{ 133 | message, 134 | errorCode, 135 | __type = 'TException' 136 | } 137 | function TException:__tostring() 138 | if self.message then 139 | return string.format('%s: %s', self.__type, self.message) 140 | else 141 | local message 142 | if self.errorCode and self.__errorCodeToString then 143 | message = string.format('%d: %s', self.errorCode, self:__errorCodeToString()) 144 | else 145 | message = thrift_print_r(self) 146 | end 147 | return string.format('%s:%s', self.__type, message) 148 | end 149 | end 150 | 151 | local TApplicationException = TException:new{ 152 | UNKNOWN = 0, 153 | UNKNOWN_METHOD = 1, 154 | INVALID_MESSAGE_TYPE = 2, 155 | WRONG_METHOD_NAME = 3, 156 | BAD_SEQUENCE_ID = 4, 157 | MISSING_RESULT = 5, 158 | INTERNAL_ERROR = 6, 159 | PROTOCOL_ERROR = 7, 160 | INVALID_TRANSFORM = 8, 161 | INVALID_PROTOCOL = 9, 162 | UNSUPPORTED_CLIENT_TYPE = 10, 163 | errorCode = 0, 164 | __type = 'TApplicationException' 165 | } 166 | 167 | function TApplicationException:__errorCodeToString() 168 | if self.errorCode == self.UNKNOWN_METHOD then 169 | return 'Unknown method' 170 | elseif self.errorCode == self.INVALID_MESSAGE_TYPE then 171 | return 'Invalid message type' 172 | elseif self.errorCode == self.WRONG_METHOD_NAME then 173 | return 'Wrong method name' 174 | elseif self.errorCode == self.BAD_SEQUENCE_ID then 175 | return 'Bad sequence ID' 176 | elseif self.errorCode == self.MISSING_RESULT then 177 | return 'Missing result' 178 | elseif self.errorCode == self.INTERNAL_ERROR then 179 | return 'Internal error' 180 | elseif self.errorCode == self.PROTOCOL_ERROR then 181 | return 'Protocol error' 182 | elseif self.errorCode == self.INVALID_TRANSFORM then 183 | return 'Invalid transform' 184 | elseif self.errorCode == self.INVALID_PROTOCOL then 185 | return 'Invalid protocol' 186 | elseif self.errorCode == self.UNSUPPORTED_CLIENT_TYPE then 187 | return 'Unsupported client type' 188 | else 189 | return 'Default (unknown)' 190 | end 191 | end 192 | 193 | function TException:read(iprot) 194 | iprot:readStructBegin() 195 | while true do 196 | local fname, ftype, fid = iprot:readFieldBegin() 197 | if ftype == TType.STOP then 198 | break 199 | elseif fid == 1 then 200 | if ftype == TType.STRING then 201 | self.message = iprot:readString() 202 | else 203 | iprot:skip(ftype) 204 | end 205 | elseif fid == 2 then 206 | if ftype == TType.I32 then 207 | self.errorCode = iprot:readI32() 208 | else 209 | iprot:skip(ftype) 210 | end 211 | else 212 | iprot:skip(ftype) 213 | end 214 | iprot:readFieldEnd() 215 | end 216 | iprot:readStructEnd() 217 | end 218 | 219 | function TException:write(oprot) 220 | oprot:writeStructBegin('TApplicationException') 221 | if self.message then 222 | oprot:writeFieldBegin('message', TType.STRING, 1) 223 | oprot:writeString(self.message) 224 | oprot:writeFieldEnd() 225 | end 226 | if self.errorCode then 227 | oprot:writeFieldBegin('type', TType.I32, 2) 228 | oprot:writeI32(self.errorCode) 229 | oprot:writeFieldEnd() 230 | end 231 | oprot:writeFieldStop() 232 | oprot:writeStructEnd() 233 | end 234 | 235 | -- Basic Client (used in generated lua code) 236 | local __TClient = __TObject:new{ 237 | __type = '__TClient', 238 | _seqid = 0 239 | } 240 | function __TClient:new(obj) 241 | if ttype(obj) ~= 'table' then 242 | error('TClient must be initialized with a table') 243 | end 244 | 245 | -- Set iprot & oprot 246 | if obj.protocol then 247 | obj.iprot = obj.protocol 248 | obj.oprot = obj.protocol 249 | obj.protocol = nil 250 | elseif not obj.iprot then 251 | error('You must provide ' .. ttype(self) .. ' with an iprot') 252 | end 253 | if not obj.oprot then 254 | obj.oprot = obj.iprot 255 | end 256 | 257 | return __TObject.new(self, obj) 258 | end 259 | 260 | function __TClient:close() 261 | self.iprot.trans:close() 262 | self.oprot.trans:close() 263 | end 264 | 265 | -- Basic Processor (used in generated lua code) 266 | local __TProcessor = __TObject:new{ 267 | __type = '__TProcessor' 268 | } 269 | function __TProcessor:new(obj) 270 | if ttype(obj) ~= 'table' then 271 | error('TProcessor must be initialized with a table') 272 | end 273 | 274 | -- Ensure a handler is provided 275 | if not obj.handler then 276 | error('You must provide ' .. ttype(self) .. ' with a handler') 277 | end 278 | 279 | return __TObject.new(self, obj) 280 | end 281 | return {TType,TMessageType,__TObject,TException,TApplicationException,__TClient} 282 | -------------------------------------------------------------------------------- /t/lua_test_TestService.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Autogenerated by Thrift 3 | -- 4 | -- DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | -- @generated 6 | -- 7 | 8 | 9 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 10 | local TType = Thrift[1] 11 | local TMessageType = Thrift[2] 12 | local __TObject = Thrift[3] 13 | local TException = Thrift[4] 14 | local TApplicationException = Thrift[5] 15 | local __TClient = Thrift[6] 16 | local types = require 'resty.thrift.thrift-idl.lua_test_ttypes' 17 | local say_args = nil --要在上面定义该变量,不然在send_say方法中找不到 18 | local say_result = nil 19 | local TestServiceClient = __TObject.new(__TClient, { 20 | __type = 'TestServiceClient' 21 | }) 22 | 23 | function TestServiceClient:say(request) 24 | self:send_say(request) 25 | return self:recv_say(request) 26 | end 27 | 28 | function TestServiceClient:send_say(request) 29 | self.oprot:writeMessageBegin('say', TMessageType.CALL, self._seqid) 30 | local args = say_args:new{} 31 | args.request = request 32 | args:write(self.oprot) 33 | self.oprot:writeMessageEnd() 34 | self.oprot.trans:flush() 35 | end 36 | 37 | function TestServiceClient:recv_say(request) 38 | local fname, mtype, rseqid = self.iprot:readMessageBegin() 39 | if mtype == TMessageType.EXCEPTION then 40 | local x = TApplicationException:new{} 41 | x:read(self.iprot) 42 | self.iprot:readMessageEnd() 43 | error(x) 44 | end 45 | local result = say_result:new{} 46 | result:read(self.iprot) 47 | self.iprot:readMessageEnd() 48 | if result.success then 49 | return result.success 50 | end 51 | error(TApplicationException:new{errorCode = TApplicationException.MISSING_RESULT}) 52 | end 53 | local TestServiceIface = __TObject:new{ 54 | __type = 'TestServiceIface' 55 | } 56 | 57 | 58 | local TestServiceProcessor = __TObject.new(__TProcessor 59 | , { 60 | __type = 'TestServiceProcessor' 61 | }) 62 | 63 | function TestServiceProcessor:process(iprot, oprot, server_ctx) 64 | local name, mtype, seqid = iprot:readMessageBegin() 65 | local func_name = 'process_' .. name 66 | if not self[func_name] or ttype(self[func_name]) ~= 'function' then 67 | iprot:skip(TType.STRUCT) 68 | iprot:readMessageEnd() 69 | x = TApplicationException:new{ 70 | errorCode = TApplicationException.UNKNOWN_METHOD 71 | } 72 | oprot:writeMessageBegin(name, TMessageType.EXCEPTION, seqid) 73 | x:write(oprot) 74 | oprot:writeMessageEnd() 75 | oprot.trans:flush() 76 | else 77 | self[func_name](self, seqid, iprot, oprot, server_ctx) 78 | end 79 | end 80 | 81 | function TestServiceProcessor:process_say(seqid, iprot, oprot, server_ctx) 82 | local args = say_args:new{} 83 | local reply_type = TMessageType.REPLY 84 | args:read(iprot) 85 | iprot:readMessageEnd() 86 | local result = say_result:new{} 87 | local status, res = pcall(self.handler.say, self.handler, args.request) 88 | if not status then 89 | reply_type = TMessageType.EXCEPTION 90 | result = TApplicationException:new{message = res} 91 | else 92 | result.success = res 93 | end 94 | oprot:writeMessageBegin('say', reply_type, seqid) 95 | result:write(oprot) 96 | oprot:writeMessageEnd() 97 | oprot.trans:flush() 98 | end 99 | 100 | -- HELPER FUNCTIONS AND STRUCTURES 101 | 102 | say_args = __TObject:new{ 103 | request 104 | } 105 | 106 | function say_args:read(iprot) 107 | iprot:readStructBegin() 108 | while true do 109 | local fname, ftype, fid = iprot:readFieldBegin() 110 | if ftype == TType.STOP then 111 | break 112 | elseif fid == 1 then 113 | if ftype == TType.STRING then 114 | self.request = iprot:readString() 115 | else 116 | iprot:skip(ftype) 117 | end 118 | else 119 | iprot:skip(ftype) 120 | end 121 | iprot:readFieldEnd() 122 | end 123 | iprot:readStructEnd() 124 | end 125 | 126 | function say_args:write(oprot) 127 | oprot:writeStructBegin('say_args') 128 | if self.request then 129 | oprot:writeFieldBegin('request', TType.STRING, 1) 130 | oprot:writeString(self.request) 131 | oprot:writeFieldEnd() 132 | end 133 | oprot:writeFieldStop() 134 | oprot:writeStructEnd() 135 | end 136 | 137 | say_result = __TObject:new{ 138 | success 139 | } 140 | 141 | function say_result:read(iprot) 142 | iprot:readStructBegin() 143 | while true do 144 | local fname, ftype, fid = iprot:readFieldBegin() 145 | if ftype == TType.STOP then 146 | break 147 | elseif fid == 0 then 148 | if ftype == TType.STRING then 149 | self.success = iprot:readString() 150 | else 151 | iprot:skip(ftype) 152 | end 153 | else 154 | iprot:skip(ftype) 155 | end 156 | iprot:readFieldEnd() 157 | end 158 | iprot:readStructEnd() 159 | end 160 | 161 | function say_result:write(oprot) 162 | oprot:writeStructBegin('say_result') 163 | if self.success then 164 | oprot:writeFieldBegin('success', TType.STRING, 0) 165 | oprot:writeString(self.success) 166 | oprot:writeFieldEnd() 167 | end 168 | oprot:writeFieldStop() 169 | oprot:writeStructEnd() 170 | end 171 | return TestServiceClient 172 | -------------------------------------------------------------------------------- /t/lua_test_ttypes.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Autogenerated by Thrift 3 | -- 4 | -- DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | -- @generated 6 | -- 7 | 8 | 9 | local Thrift = require 'resty.thrift.thrift-lua.Thrift' 10 | local TType = Thrift[1] 11 | local TMessageType = Thrift[2] 12 | local __TObject = Thrift[3] 13 | local TException = Thrift[4] 14 | local TApplicationException = Thrift[5] 15 | local __TClient = Thrift[6] 16 | 17 | local TestServiceClient = __TObject.new(__TClient, { 18 | __type = 'TestServiceClient' 19 | }) 20 | 21 | function TestServiceClient:say(request) 22 | self:send_say(request) 23 | return self:recv_say(request) 24 | end 25 | 26 | function TestServiceClient:send_say(request) 27 | self.oprot:writeMessageBegin('say', TMessageType.CALL, self._seqid) 28 | local args = say_args:new{} 29 | args.request = request 30 | args:write(self.oprot) 31 | self.oprot:writeMessageEnd() 32 | self.oprot.trans:flush() 33 | end 34 | 35 | function TestServiceClient:recv_say(request) 36 | local fname, mtype, rseqid = self.iprot:readMessageBegin() 37 | if mtype == TMessageType.EXCEPTION then 38 | local x = TApplicationException:new{} 39 | x:read(self.iprot) 40 | self.iprot:readMessageEnd() 41 | error(x) 42 | end 43 | local result = say_result:new{} 44 | result:read(self.iprot) 45 | self.iprot:readMessageEnd() 46 | if result.success then 47 | return result.success 48 | end 49 | error(TApplicationException:new{errorCode = TApplicationException.MISSING_RESULT}) 50 | end 51 | local TestServiceIface = __TObject:new{ 52 | __type = 'TestServiceIface' 53 | } 54 | 55 | 56 | local TestServiceProcessor = __TObject.new(__TProcessor 57 | , { 58 | __type = 'TestServiceProcessor' 59 | }) 60 | 61 | function TestServiceProcessor:process(iprot, oprot, server_ctx) 62 | local name, mtype, seqid = iprot:readMessageBegin() 63 | local func_name = 'process_' .. name 64 | if not self[func_name] or ttype(self[func_name]) ~= 'function' then 65 | iprot:skip(TType.STRUCT) 66 | iprot:readMessageEnd() 67 | x = TApplicationException:new{ 68 | errorCode = TApplicationException.UNKNOWN_METHOD 69 | } 70 | oprot:writeMessageBegin(name, TMessageType.EXCEPTION, seqid) 71 | x:write(oprot) 72 | oprot:writeMessageEnd() 73 | oprot.trans:flush() 74 | else 75 | self[func_name](self, seqid, iprot, oprot, server_ctx) 76 | end 77 | end 78 | 79 | function TestServiceProcessor:process_say(seqid, iprot, oprot, server_ctx) 80 | local args = say_args:new{} 81 | local reply_type = TMessageType.REPLY 82 | args:read(iprot) 83 | iprot:readMessageEnd() 84 | local result = say_result:new{} 85 | local status, res = pcall(self.handler.say, self.handler, args.request) 86 | if not status then 87 | reply_type = TMessageType.EXCEPTION 88 | result = TApplicationException:new{message = res} 89 | else 90 | result.success = res 91 | end 92 | oprot:writeMessageBegin('say', reply_type, seqid) 93 | result:write(oprot) 94 | oprot:writeMessageEnd() 95 | oprot.trans:flush() 96 | end 97 | 98 | -- HELPER FUNCTIONS AND STRUCTURES 99 | 100 | local say_args = __TObject:new{ 101 | request 102 | } 103 | 104 | function say_args:read(iprot) 105 | iprot:readStructBegin() 106 | while true do 107 | local fname, ftype, fid = iprot:readFieldBegin() 108 | if ftype == TType.STOP then 109 | break 110 | elseif fid == 1 then 111 | if ftype == TType.STRING then 112 | self.request = iprot:readString() 113 | else 114 | iprot:skip(ftype) 115 | end 116 | else 117 | iprot:skip(ftype) 118 | end 119 | iprot:readFieldEnd() 120 | end 121 | iprot:readStructEnd() 122 | end 123 | 124 | function say_args:write(oprot) 125 | oprot:writeStructBegin('say_args') 126 | if self.request then 127 | oprot:writeFieldBegin('request', TType.STRING, 1) 128 | oprot:writeString(self.request) 129 | oprot:writeFieldEnd() 130 | end 131 | oprot:writeFieldStop() 132 | oprot:writeStructEnd() 133 | end 134 | 135 | local say_result = __TObject:new{ 136 | success 137 | } 138 | 139 | function say_result:read(iprot) 140 | iprot:readStructBegin() 141 | while true do 142 | local fname, ftype, fid = iprot:readFieldBegin() 143 | if ftype == TType.STOP then 144 | break 145 | elseif fid == 0 then 146 | if ftype == TType.STRING then 147 | self.success = iprot:readString() 148 | else 149 | iprot:skip(ftype) 150 | end 151 | else 152 | iprot:skip(ftype) 153 | end 154 | iprot:readFieldEnd() 155 | end 156 | iprot:readStructEnd() 157 | end 158 | 159 | function say_result:write(oprot) 160 | oprot:writeStructBegin('say_result') 161 | if self.success then 162 | oprot:writeFieldBegin('success', TType.STRING, 0) 163 | oprot:writeString(self.success) 164 | oprot:writeFieldEnd() 165 | end 166 | oprot:writeFieldStop() 167 | oprot:writeStructEnd() 168 | end 169 | return TestServiceClient 170 | -------------------------------------------------------------------------------- /t/test.lua: -------------------------------------------------------------------------------- 1 | local GenericObjectPool = require 'resty.thrift.GenericObjectPool' 2 | local TestServiceClient = require "resty.thrift.thrift-idl.lua_test_TestService" 3 | local ngx = ngx 4 | 5 | local client = GenericObjectPool:connection(TestServiceClient,'127.0.0.1',9090) 6 | local res = client:say('hi') 7 | GenericObjectPool:returnConnection(client) 8 | ngx.say(res) 9 | -------------------------------------------------------------------------------- /t/test.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.test.thrift 2 | namespace cpp lua_test 3 | namespace lua lua_test 4 | 5 | service TestService { 6 | string say(1:string request) 7 | } 8 | --------------------------------------------------------------------------------