|  | -- | 
|  | -- Licensed to the Apache Software Foundation (ASF) under one | 
|  | -- or more contributor license agreements. See the NOTICE file | 
|  | -- distributed with this work for additional information | 
|  | -- regarding copyright ownership. The ASF licenses this file | 
|  | -- to you under the Apache License, Version 2.0 (the | 
|  | -- "License"); you may not use this file except in compliance | 
|  | -- with the License. You may obtain a copy of the License at | 
|  | -- | 
|  | --   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | -- | 
|  | -- Unless required by applicable law or agreed to in writing, | 
|  | -- software distributed under the License is distributed on an | 
|  | -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | -- KIND, either express or implied. See the License for the | 
|  | -- specific language governing permissions and limitations | 
|  | -- under the License. | 
|  | -- | 
|  |  | 
|  | require 'Thrift' | 
|  | require 'TFramedTransport' | 
|  | require 'TBinaryProtocol' | 
|  |  | 
|  | -- TServer | 
|  | TServer = __TObject:new{ | 
|  | __type = 'TServer' | 
|  | } | 
|  |  | 
|  | -- 2 possible constructors | 
|  | --   1. {processor, serverTransport} | 
|  | --   2. {processor, serverTransport, transportFactory, protocolFactory} | 
|  | function TServer:new(args) | 
|  | if ttype(args) ~= 'table' then | 
|  | error('TServer must be initialized with a table') | 
|  | end | 
|  | if args.processor == nil then | 
|  | terror('You must provide ' .. ttype(self) .. ' with a processor') | 
|  | end | 
|  | if args.serverTransport == nil then | 
|  | terror('You must provide ' .. ttype(self) .. ' with a serverTransport') | 
|  | end | 
|  |  | 
|  | -- Create the object | 
|  | local obj = __TObject.new(self, args) | 
|  |  | 
|  | if obj.transportFactory then | 
|  | obj.inputTransportFactory = obj.transportFactory | 
|  | obj.outputTransportFactory = obj.transportFactory | 
|  | obj.transportFactory = nil | 
|  | else | 
|  | obj.inputTransportFactory = TFramedTransportFactory:new{} | 
|  | obj.outputTransportFactory = obj.inputTransportFactory | 
|  | end | 
|  |  | 
|  | if obj.protocolFactory then | 
|  | obj.inputProtocolFactory = obj.protocolFactory | 
|  | obj.outputProtocolFactory = obj.protocolFactory | 
|  | obj.protocolFactory = nil | 
|  | else | 
|  | obj.inputProtocolFactory = TBinaryProtocolFactory:new{} | 
|  | obj.outputProtocolFactory = obj.inputProtocolFactory | 
|  | end | 
|  |  | 
|  | -- Set the __server variable in the handler so we can stop the server | 
|  | obj.processor.handler.__server = self | 
|  |  | 
|  | return obj | 
|  | end | 
|  |  | 
|  | function TServer:setServerEventHandler(handler) | 
|  | self.serverEventHandler = handler | 
|  | end | 
|  |  | 
|  | function TServer:_clientBegin(content, iprot, oprot) | 
|  | if self.serverEventHandler and | 
|  | type(self.serverEventHandler.clientBegin) == 'function' then | 
|  | self.serverEventHandler:clientBegin(iprot, oprot) | 
|  | end | 
|  | end | 
|  |  | 
|  | function TServer:_preServe() | 
|  | if self.serverEventHandler and | 
|  | type(self.serverEventHandler.preServe) == 'function' then | 
|  | self.serverEventHandler:preServe(self.serverTransport:getSocketInfo()) | 
|  | end | 
|  | end | 
|  |  | 
|  | function TServer:_handleException(err) | 
|  | if string.find(err, 'TTransportException') == nil then | 
|  | print(err) | 
|  | end | 
|  | end | 
|  |  | 
|  | function TServer:serve() end | 
|  | function TServer:handle(client) | 
|  | local itrans, otrans, iprot, oprot, ret, err = | 
|  | self.inputTransportFactory:getTransport(client), | 
|  | self.outputTransportFactory:getTransport(client), | 
|  | self.inputProtocolFactory:getProtocol(client), | 
|  | self.outputProtocolFactory:getProtocol(client) | 
|  |  | 
|  | self:_clientBegin(iprot, oprot) | 
|  | while true do | 
|  | ret, err = pcall(self.processor.process, self.processor, iprot, oprot) | 
|  | if ret == false and err then | 
|  | if not string.find(err, "TTransportException") then | 
|  | self:_handleException(err) | 
|  | end | 
|  | break | 
|  | end | 
|  | end | 
|  | itrans:close() | 
|  | otrans:close() | 
|  | end | 
|  |  | 
|  | function TServer:close() | 
|  | self.serverTransport:close() | 
|  | end | 
|  |  | 
|  | -- TSimpleServer | 
|  | --  Single threaded server that handles one transport (connection) | 
|  | TSimpleServer = __TObject:new(TServer, { | 
|  | __type = 'TSimpleServer', | 
|  | __stop = false | 
|  | }) | 
|  |  | 
|  | function TSimpleServer:serve() | 
|  | self.serverTransport:listen() | 
|  | self:_preServe() | 
|  | while not self.__stop do | 
|  | client = self.serverTransport:accept() | 
|  | self:handle(client) | 
|  | end | 
|  | self:close() | 
|  | end | 
|  |  | 
|  | function TSimpleServer:stop() | 
|  | self.__stop = true | 
|  | end |