| (* | |
| * 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. | |
| *) | |
| unit Thrift.Server; | |
| interface | |
| uses | |
| SysUtils, | |
| Thrift, | |
| Thrift.Protocol, | |
| Thrift.Transport; | |
| type | |
| IServer = interface | |
| ['{CF9F56C6-BB39-4C7D-877B-43B416572CE6}'] | |
| procedure Serve; | |
| procedure Stop; | |
| end; | |
| TServerImpl = class abstract( TInterfacedObject, IServer ) | |
| public | |
| type | |
| TLogDelegate = reference to procedure( str: string); | |
| protected | |
| FProcessor : IProcessor; | |
| FServerTransport : IServerTransport; | |
| FInputTransportFactory : ITransportFactory; | |
| FOutputTransportFactory : ITransportFactory; | |
| FInputProtocolFactory : IProtocolFactory; | |
| FOutputProtocolFactory : IProtocolFactory; | |
| FLogDelegate : TLogDelegate; | |
| class procedure DefaultLogDelegate( str: string); | |
| procedure Serve; virtual; abstract; | |
| procedure Stop; virtual; abstract; | |
| public | |
| constructor Create( | |
| AProcessor :IProcessor; | |
| AServerTransport: IServerTransport; | |
| AInputTransportFactory : ITransportFactory; | |
| AOutputTransportFactory : ITransportFactory; | |
| AInputProtocolFactory : IProtocolFactory; | |
| AOutputProtocolFactory : IProtocolFactory; | |
| ALogDelegate : TLogDelegate | |
| ); overload; | |
| constructor Create( AProcessor :IProcessor; | |
| AServerTransport: IServerTransport); overload; | |
| constructor Create( | |
| AProcessor :IProcessor; | |
| AServerTransport: IServerTransport; | |
| ALogDelegate: TLogDelegate | |
| ); overload; | |
| constructor Create( | |
| AProcessor :IProcessor; | |
| AServerTransport: IServerTransport; | |
| ATransportFactory : ITransportFactory | |
| ); overload; | |
| constructor Create( | |
| AProcessor :IProcessor; | |
| AServerTransport: IServerTransport; | |
| ATransportFactory : ITransportFactory; | |
| AProtocolFactory : IProtocolFactory | |
| ); overload; | |
| end; | |
| TSimpleServer = class( TServerImpl) | |
| private | |
| FStop : Boolean; | |
| public | |
| constructor Create( AProcessor: IProcessor; AServerTransport: IServerTransport); overload; | |
| constructor Create( AProcessor: IProcessor; AServerTransport: IServerTransport; | |
| ALogDel: TServerImpl.TLogDelegate); overload; | |
| constructor Create( AProcessor: IProcessor; AServerTransport: IServerTransport; | |
| ATransportFactory: ITransportFactory); overload; | |
| constructor Create( AProcessor: IProcessor; AServerTransport: IServerTransport; | |
| ATransportFactory: ITransportFactory; AProtocolFactory: IProtocolFactory); overload; | |
| procedure Serve; override; | |
| procedure Stop; override; | |
| end; | |
| implementation | |
| { TServerImpl } | |
| constructor TServerImpl.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; ALogDelegate: TLogDelegate); | |
| var | |
| InputFactory, OutputFactory : IProtocolFactory; | |
| InputTransFactory, OutputTransFactory : ITransportFactory; | |
| begin | |
| InputFactory := TBinaryProtocolImpl.TFactory.Create; | |
| OutputFactory := TBinaryProtocolImpl.TFactory.Create; | |
| InputTransFactory := TTransportFactoryImpl.Create; | |
| OutputTransFactory := TTransportFactoryImpl.Create; | |
| Create( | |
| AProcessor, | |
| AServerTransport, | |
| InputTransFactory, | |
| OutputTransFactory, | |
| InputFactory, | |
| OutputFactory, | |
| ALogDelegate | |
| ); | |
| end; | |
| constructor TServerImpl.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport); | |
| var | |
| InputFactory, OutputFactory : IProtocolFactory; | |
| InputTransFactory, OutputTransFactory : ITransportFactory; | |
| begin | |
| InputFactory := TBinaryProtocolImpl.TFactory.Create; | |
| OutputFactory := TBinaryProtocolImpl.TFactory.Create; | |
| InputTransFactory := TTransportFactoryImpl.Create; | |
| OutputTransFactory := TTransportFactoryImpl.Create; | |
| Create( | |
| AProcessor, | |
| AServerTransport, | |
| InputTransFactory, | |
| OutputTransFactory, | |
| InputFactory, | |
| OutputFactory, | |
| DefaultLogDelegate | |
| ); | |
| end; | |
| constructor TServerImpl.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; ATransportFactory: ITransportFactory); | |
| var | |
| InputProtocolFactory : IProtocolFactory; | |
| OutputProtocolFactory : IProtocolFactory; | |
| begin | |
| InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | |
| OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | |
| Create( AProcessor, AServerTransport, ATransportFactory, ATransportFactory, | |
| InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate); | |
| end; | |
| constructor TServerImpl.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; AInputTransportFactory, | |
| AOutputTransportFactory: ITransportFactory; AInputProtocolFactory, | |
| AOutputProtocolFactory: IProtocolFactory; | |
| ALogDelegate : TLogDelegate); | |
| begin | |
| FProcessor := AProcessor; | |
| FServerTransport := AServerTransport; | |
| FInputTransportFactory := AInputTransportFactory; | |
| FOutputTransportFactory := AOutputTransportFactory; | |
| FInputProtocolFactory := AInputProtocolFactory; | |
| FOutputProtocolFactory := AOutputProtocolFactory; | |
| FLogDelegate := ALogDelegate; | |
| end; | |
| class procedure TServerImpl.DefaultLogDelegate( str: string); | |
| begin | |
| Writeln( str ); | |
| end; | |
| constructor TServerImpl.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; ATransportFactory: ITransportFactory; | |
| AProtocolFactory: IProtocolFactory); | |
| begin | |
| end; | |
| { TSimpleServer } | |
| constructor TSimpleServer.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport); | |
| var | |
| InputProtocolFactory : IProtocolFactory; | |
| OutputProtocolFactory : IProtocolFactory; | |
| InputTransportFactory : ITransportFactory; | |
| OutputTransportFactory : ITransportFactory; | |
| begin | |
| InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | |
| OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | |
| InputTransportFactory := TTransportFactoryImpl.Create; | |
| OutputTransportFactory := TTransportFactoryImpl.Create; | |
| inherited Create( AProcessor, AServerTransport, InputTransportFactory, | |
| OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate); | |
| end; | |
| constructor TSimpleServer.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; ALogDel: TServerImpl.TLogDelegate); | |
| var | |
| InputProtocolFactory : IProtocolFactory; | |
| OutputProtocolFactory : IProtocolFactory; | |
| InputTransportFactory : ITransportFactory; | |
| OutputTransportFactory : ITransportFactory; | |
| begin | |
| InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | |
| OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | |
| InputTransportFactory := TTransportFactoryImpl.Create; | |
| OutputTransportFactory := TTransportFactoryImpl.Create; | |
| inherited Create( AProcessor, AServerTransport, InputTransportFactory, | |
| OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, ALogDel); | |
| end; | |
| constructor TSimpleServer.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; ATransportFactory: ITransportFactory); | |
| begin | |
| inherited Create( AProcessor, AServerTransport, ATransportFactory, | |
| ATransportFactory, TBinaryProtocolImpl.TFactory.Create, TBinaryProtocolImpl.TFactory.Create, DefaultLogDelegate); | |
| end; | |
| constructor TSimpleServer.Create(AProcessor: IProcessor; | |
| AServerTransport: IServerTransport; ATransportFactory: ITransportFactory; | |
| AProtocolFactory: IProtocolFactory); | |
| begin | |
| inherited Create( AProcessor, AServerTransport, ATransportFactory, | |
| ATransportFactory, AProtocolFactory, AProtocolFactory, DefaultLogDelegate); | |
| end; | |
| procedure TSimpleServer.Serve; | |
| var | |
| client : ITransport; | |
| InputTransport : ITransport; | |
| OutputTransport : ITransport; | |
| InputProtocol : IProtocol; | |
| OutputProtocol : IProtocol; | |
| begin | |
| try | |
| FServerTransport.Listen; | |
| except | |
| on E: Exception do | |
| begin | |
| FLogDelegate( E.ToString); | |
| end; | |
| end; | |
| client := nil; | |
| InputTransport := nil; | |
| OutputTransport := nil; | |
| InputProtocol := nil; | |
| OutputProtocol := nil; | |
| while (not FStop) do | |
| begin | |
| try | |
| client := FServerTransport.Accept; | |
| FLogDelegate( 'Client Connected!'); | |
| InputTransport := FInputTransportFactory.GetTransport( client ); | |
| OutputTransport := FOutputTransportFactory.GetTransport( client ); | |
| InputProtocol := FInputProtocolFactory.GetProtocol( InputTransport ); | |
| OutputProtocol := FOutputProtocolFactory.GetProtocol( OutputTransport ); | |
| while ( FProcessor.Process( InputProtocol, OutputProtocol )) do | |
| begin | |
| if FStop then Break; | |
| end; | |
| except | |
| on E: TTransportException do | |
| begin | |
| if FStop then | |
| begin | |
| FLogDelegate('TSimpleServer was shutting down, caught ' + E.ClassName); | |
| end; | |
| end; | |
| on E: Exception do | |
| begin | |
| FLogDelegate( E.ToString ); | |
| end; | |
| end; | |
| if InputTransport <> nil then | |
| begin | |
| InputTransport.Close; | |
| end; | |
| if OutputTransport <> nil then | |
| begin | |
| OutputTransport.Close; | |
| end; | |
| end; | |
| if FStop then | |
| begin | |
| try | |
| FServerTransport.Close; | |
| except | |
| on E: TTransportException do | |
| begin | |
| FLogDelegate('TServerTranport failed on close: ' + E.Message); | |
| end; | |
| end; | |
| FStop := False; | |
| end; | |
| end; | |
| procedure TSimpleServer.Stop; | |
| begin | |
| FStop := True; | |
| FServerTransport.Close; | |
| end; | |
| end. |