]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
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 'Thrift' | |
21 | require 'TFramedTransport' | |
22 | require '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 = | |
97 | self.inputTransportFactory:getTransport(client), | |
98 | self.outputTransportFactory:getTransport(client) | |
99 | local iprot, oprot = | |
100 | self.inputProtocolFactory:getProtocol(itrans), | |
101 | self.outputProtocolFactory:getProtocol(otrans) | |
102 | ||
103 | self:_clientBegin(iprot, oprot) | |
104 | while true do | |
105 | local ret, err = pcall(self.processor.process, self.processor, iprot, oprot) | |
106 | if ret == false and err then | |
107 | if not string.find(err, "TTransportException") then | |
108 | self:_handleException(err) | |
109 | end | |
110 | break | |
111 | end | |
112 | end | |
113 | itrans:close() | |
114 | otrans:close() | |
115 | end | |
116 | ||
117 | function TServer:close() | |
118 | self.serverTransport:close() | |
119 | end | |
120 | ||
121 | -- TSimpleServer | |
122 | -- Single threaded server that handles one transport (connection) | |
123 | TSimpleServer = __TObject:new(TServer, { | |
124 | __type = 'TSimpleServer', | |
125 | __stop = false | |
126 | }) | |
127 | ||
128 | function TSimpleServer:serve() | |
129 | self.serverTransport:listen() | |
130 | self:_preServe() | |
131 | while not self.__stop do | |
132 | client = self.serverTransport:accept() | |
133 | self:handle(client) | |
134 | end | |
135 | self:close() | |
136 | end | |
137 | ||
138 | function TSimpleServer:stop() | |
139 | self.__stop = true | |
140 | end |