blob: a49fb474bf1f27bc00aadeb3fd172aae5fdfbc90 [file] [log] [blame] [view]
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001# Building of samples for different platforms
2
Jens Geyerffb97e12019-12-06 23:43:08 +01003# Requirements
4- NET Core Standard 3.1 (LTS) runtime or SDK (see below for further info)
Jens Geyeraa0c8b32019-01-28 23:27:45 +01005
6# How to build
Jens Geyerec439542019-11-01 19:19:44 +01007- Download and install the latest .NET Core SDK for your platform https://dotnet.microsoft.com/download/dotnet-core
Jens Geyeraa0c8b32019-01-28 23:27:45 +01008- Ensure that you have thrift.exe which supports netstd lib and it added to PATH
9- Go to current folder
10- Run **build.sh** or **build.cmd** from the root of cloned repository
11- Check tests in **src/Tests** folder
12- Continue with /tutorials/netstd
13
14# How to run
15
Kengo Sekibee4f2f2019-12-29 17:04:50 +090016Depending on the platform, the name of the generated executables will vary. On Linux, it is just "Client" or "Server", on Windows it is "Client.exe" and "Server.exe". In the following, we use the abbreviated form "Client" and "Server".
Jens Geyeraa0c8b32019-01-28 23:27:45 +010017
18- build
19- go to folder (Client/Server)
Jens Geyerffb97e12019-12-06 23:43:08 +010020- run the generated executables: server first, then client from a second console
Jens Geyeraa0c8b32019-01-28 23:27:45 +010021
Kengo Sekibee4f2f2019-12-29 17:04:50 +090022# Known issues
Jens Geyeraa0c8b32019-01-28 23:27:45 +010023- In trace logging mode you can see some not important internal exceptions
24
25# Running of samples
Jens Geyerffb97e12019-12-06 23:43:08 +010026On machines that do not have the SDK installed, you need to install the NET Core runtime first. The SDK is only needed to build programs, otherwise the runtime is sufficient.
Jens Geyeraa0c8b32019-01-28 23:27:45 +010027
28# NetCore Server
29
30Usage:
31
Kengo Sekibee4f2f2019-12-29 17:04:50 +090032 Server -help
Jens Geyeraa0c8b32019-01-28 23:27:45 +010033 will diplay help information
34
Kengo Sekibee4f2f2019-12-29 17:04:50 +090035 Server -tr:<transport> -pr:<protocol>
Jens Geyeraa0c8b32019-01-28 23:27:45 +010036 will run server with specified arguments (tcp transport and binary protocol by default)
37
38Options:
39
40 -tr (transport):
41 tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010042 namedpipe - namedpipe transport will be used (pipe address - "".test"")
43 http - http transport will be used (http address - ""localhost:9090"")
44 tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
Kyle Smith0bc47122019-03-27 11:41:34 -040045
46 -bf (buffering):
47 none - (default) no transport factory will be used
48 buffered - buffered transport factory will be used
49 framed - framed transport factory will be used (this must match the client)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010050
51 -pr (protocol):
52 binary - (default) binary protocol will be used
53 compact - compact protocol will be used
54 json - json protocol will be used
Kengo Sekibee4f2f2019-12-29 17:04:50 +090055 multiplexed - multiplexed protocol will be used
56
Jens Geyeraa0c8b32019-01-28 23:27:45 +010057Sample:
58
Jens Geyerffb97e12019-12-06 23:43:08 +010059 Server -tr:tcp
Jens Geyeraa0c8b32019-01-28 23:27:45 +010060
61**Remarks**:
62
63 For TcpTls mode certificate's file ThriftTest.pfx should be in directory with binaries in case of command line usage (or at project level in case of debugging from IDE).
64 Password for certificate - "ThriftTest".
65
66
67
68# NetCore Client
69
70Usage:
71
Kengo Sekibee4f2f2019-12-29 17:04:50 +090072 Client -help
Jens Geyeraa0c8b32019-01-28 23:27:45 +010073 will diplay help information
74
Jens Geyerffb97e12019-12-06 23:43:08 +010075 Client -tr:<transport> -pr:<protocol> -mc:<numClients>
Jens Geyeraa0c8b32019-01-28 23:27:45 +010076 will run client with specified arguments (tcp transport and binary protocol by default)
77
78Options:
79
80 -tr (transport):
81 tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010082 namedpipe - namedpipe transport will be used (pipe address - "".test"")
83 http - http transport will be used (address - ""http://localhost:9090"")
84 tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
Kyle Smith0bc47122019-03-27 11:41:34 -040085
86 -bf (buffering):
87 none - (default) no transport factory will be used
88 buffered - buffered transport factory will be used
89 framed - framed transport factory will be used (this must match the client)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010090
91 -pr (protocol):
92 binary - (default) binary protocol will be used
93 compact - compact protocol will be used
94 json - json protocol will be used
Kengo Sekibee4f2f2019-12-29 17:04:50 +090095 multiplexed - multiplexed protocol will be used
96
Jens Geyeraa0c8b32019-01-28 23:27:45 +010097 -mc (multiple clients):
98 <numClients> - number of multiple clients to connect to server (max 100, default 1)
99
100Sample:
101
Jens Geyerffb97e12019-12-06 23:43:08 +0100102 Client -tr:tcp -pr:binary -mc:10
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100103
104Remarks:
105
106 For TcpTls mode certificate's file ThriftTest.pfx should be in directory
107 with binaries in case of command line usage (or at project level in case of debugging from IDE).
108 Password for certificate - "ThriftTest".
109
110# How to test communication between NetCore and Python
111
Jens Geyerffb97e12019-12-06 23:43:08 +0100112* Generate code with the latest **thrift** utility
113* Ensure that **thrift** generated folder **gen-py** with generated code for Python exists
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100114* Create **client.py** and **server.py** from the code examples below and save them to the folder with previosly generated folder **gen-py**
115* Run netstd samples (client and server) and python samples (client and server)
116
117Remarks:
118
119Samples of client and server code below use correct methods (operations)
120and fields (properties) according to generated contracts from *.thrift files
121
122At Windows 10 add record **127.0.0.1 testserver** to **C:\Windows\System32\drivers\etc\hosts** file
123for correct work of python server
124
125
126**Python Client:**
127
128```python
129import sys
130import glob
131sys.path.append('gen-py')
132
133from tutorial import Calculator
134from tutorial.ttypes import InvalidOperation, Operation, Work
135
136from thrift import Thrift
137from thrift.transport import TSocket
138from thrift.transport import TTransport
139from thrift.protocol import TBinaryProtocol
140
141
142def main():
143 # Make socket
144 transport = TSocket.TSocket('127.0.0.1', 9090)
145
146 # Buffering is critical. Raw sockets are very slow
147 transport = TTransport.TBufferedTransport(transport)
148
149 # Wrap in a protocol
150 protocol = TBinaryProtocol.TBinaryProtocol(transport)
151
152 # Create a client to use the protocol encoder
153 client = Calculator.Client(protocol)
154
155 # Connect!
156 transport.open()
157
158 client.Ping()
159 print('ping()')
160
161 sum = client.Add(1, 1)
162 print(('1+1=%d' % (sum)))
163
164 work = Work()
165
166 work.Op = Operation.Divide
167 work.Num1 = 1
168 work.Num2 = 0
169
170 try:
171 quotient = client.Calculate(1, work)
172 print('Whoa? You know how to divide by zero?')
173 print('FYI the answer is %d' % quotient)
174 except InvalidOperation as e:
175 print(('InvalidOperation: %r' % e))
176
177 work.Op = Operation.Substract
178 work.Num1 = 15
179 work.Num2 = 10
180
181 diff = client.Calculate(1, work)
182 print(('15-10=%d' % (diff)))
183
184 log = client.GetStruct(1)
185 print(('Check log: %s' % (log.Value)))
186
187 client.Zip()
188 print('zip()')
189
190 # Close!
191 transport.close()
192
193if __name__ == '__main__':
194 try:
195 main()
196 except Thrift.TException as tx:
197 print('%s' % tx.message)
198```
199
200
201**Python Server:**
202
203
204```python
205import glob
206import sys
207sys.path.append('gen-py')
208
209from tutorial import Calculator
210from tutorial.ttypes import InvalidOperation, Operation
211
212from shared.ttypes import SharedStruct
213
214from thrift.transport import TSocket
215from thrift.transport import TTransport
216from thrift.protocol import TBinaryProtocol
217from thrift.server import TServer
218
219
220class CalculatorHandler:
221 def __init__(self):
222 self.log = {}
223
224 def Ping(self):
225 print('ping()')
226
227 def Add(self, n1, n2):
228 print('add(%d,%d)' % (n1, n2))
229 return n1 + n2
230
231 def Calculate(self, logid, work):
232 print('calculate(%d, %r)' % (logid, work))
233
234 if work.Op == Operation.Add:
235 val = work.Num1 + work.Num2
236 elif work.Op == Operation.Substract:
237 val = work.Num1 - work.Num2
238 elif work.Op == Operation.Multiply:
239 val = work.Num1 * work.Num2
240 elif work.Op == Operation.Divide:
241 if work.Num2 == 0:
Kengo Sekibee4f2f2019-12-29 17:04:50 +0900242 raise InvalidOperation(work.Op, 'Cannot divide by 0')
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100243 val = work.Num1 / work.Num2
244 else:
Kengo Sekibee4f2f2019-12-29 17:04:50 +0900245 raise InvalidOperation(work.Op, 'Invalid operation')
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100246
247 log = SharedStruct()
248 log.Key = logid
249 log.Value = '%d' % (val)
250 self.log[logid] = log
251
252 return val
253
254 def GetStruct(self, key):
255 print('getStruct(%d)' % (key))
256 return self.log[key]
257
258 def Zip(self):
259 print('zip()')
260
261if __name__ == '__main__':
262 handler = CalculatorHandler()
263 processor = Calculator.Processor(handler)
264 transport = TSocket.TServerSocket(host="testserver", port=9090)
265 tfactory = TTransport.TBufferedTransportFactory()
266 pfactory = TBinaryProtocol.TBinaryProtocolFactory()
267
268 server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
269 print('Starting the server...')
270 server.serve()
271 print('done.')
272
273 # You could do one of these for a multithreaded server
274 # server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
275 # server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
276```