| -- | 
 | -- 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 |