forked from ni/grpc-labview
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgrpc_server.h
More file actions
273 lines (238 loc) · 9.76 KB
/
grpc_server.h
File metadata and controls
273 lines (238 loc) · 9.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
//---------------------------------------------------------------------
// LabVIEW implementation of a gRPC Server
//---------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#ifdef __WIN32__
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#endif
//---------------------------------------------------------------------
// IMPORTANT: lv_serialization_traits.h MUST be included BEFORE grpc headers
// This registers our custom SerializationTraits<LVMessage> specialization
//---------------------------------------------------------------------
#include <lv_serialization_traits.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/impl/codegen/async_generic_service.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/message_allocator.h>
#include <grpcpp/impl/codegen/method_handler.h>
#include <grpcpp/impl/codegen/proto_utils.h>
#include <grpcpp/impl/codegen/server_callback.h>
#include <grpcpp/impl/codegen/server_callback_handlers.h>
#include <grpcpp/impl/codegen/server_context.h>
#include <lv_interop.h>
#include <condition_variable>
#include <future>
#include <map>
#include <event_data.h>
#include <metadata_owner.h>
#include <lv_semaphore.h>
//---------------------------------------------------------------------
//---------------------------------------------------------------------
using grpc::Server;
using grpc::ServerBuilder;
using grpc::Status;
namespace grpc_labview
{
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class LabVIEWgRPCServer;
class LVMessage;
class CallData;
class MessageElementMetadata;
struct MessageMetadata;
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class ServerStartEventData : public EventData
{
public:
ServerStartEventData();
public:
int serverStartStatus;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class GenericMethodData : public EventData, public IMessageElementMetadataOwner
{
public:
GenericMethodData(CallData* call, ServerContext* context, std::shared_ptr<LVMessage> request, std::shared_ptr<LVMessage> response);
virtual std::shared_ptr<MessageMetadata> FindMetadata(const std::string& name) override;
std::shared_ptr<EnumMetadata> FindEnumMetadata(const std::string& name) {
return nullptr;
};
public:
CallData* _call;
std::shared_ptr<LVMessage> _request;
std::shared_ptr<LVMessage> _response;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
struct LVEventData
{
LVUserEventRef event;
std::string requestMetadataName;
std::string responseMetadataName;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class LabVIEWgRPCServer : public MessageElementMetadataOwner, public gRPCid
{
public:
LabVIEWgRPCServer();
int Run(std::string address, std::string serverCertificatePath, std::string serverKeyPath);
int ListeningPort();
void StopServer();
void RegisterEvent(std::string eventName, LVUserEventRef reference, std::string requestMessageName, std::string responseMessageName);
void RegisterGenericMethodEvent(LVUserEventRef item);
void SendEvent(std::string name, gRPCid* data);
bool FindEventData(std::string name, LVEventData& data);
bool HasGenericMethodEvent();
bool HasRegisteredServerMethod(std::string methodName);
private:
std::mutex _mutex;
std::unique_ptr<Server> _server;
std::unique_ptr<grpc::ServerCompletionQueue> _cq;
std::map<std::string, LVEventData> _registeredServerMethods;
LVUserEventRef _genericMethodEvent;
std::unique_ptr<grpc::AsyncGenericService> _rpcService;
std::unique_ptr<std::thread> _runThread;
bool _shutdown;
int _listeningPort;
private:
void RunServer(std::string address, std::string serverCertificatePath, std::string serverKeyPath, ServerStartEventData* serverStarted);
void HandleRpcs(grpc::ServerCompletionQueue *cq);
private:
static void StaticRunServer(LabVIEWgRPCServer* server, std::string address, std::string serverCertificatePath, std::string serverKeyPath, ServerStartEventData* serverStarted);
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class CallDataBase
{
public:
virtual void Proceed(bool ok) = 0;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class CallFinishedData : CallDataBase
{
public:
CallFinishedData(CallData* callData);
void Proceed(bool ok) override;
private:
CallData* _call;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class CallData : public CallDataBase, public IMessageElementMetadataOwner
{
public:
CallData(LabVIEWgRPCServer* server, grpc::AsyncGenericService* service, grpc::ServerCompletionQueue* cq);
std::shared_ptr<MessageMetadata> FindMetadata(const std::string& name) override;
std::shared_ptr<EnumMetadata> FindEnumMetadata(const std::string& name) {
return nullptr;
}
void Proceed(bool ok) override;
bool Write();
void Finish();
bool IsCancelled();
bool IsActive();
bool ReadNext();
void SetCallStatusError(std::string errorMessage);
void SetCallStatusError(grpc::StatusCode statusCode, std::string errorMessage);
grpc::StatusCode GetCallStatusCode();
private:
LabVIEWgRPCServer* _server;
grpc::AsyncGenericService* _service;
grpc::ServerCompletionQueue* _cq;
grpc::GenericServerContext _ctx;
grpc::GenericServerAsyncReaderWriter _stream;
grpc::ByteBuffer _rb;
grpc::Status _callStatus;
Semaphore _writeSemaphore;
std::shared_ptr<GenericMethodData> _methodData;
std::shared_ptr<LVMessage> _request;
std::shared_ptr<LVMessage> _response;
enum class CallStatus
{
Create,
WaitingForConnection,
WritingResponse,
Connected,
PendingFinish,
Finish
};
CallStatus _status;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class ReadNextTag : CallDataBase
{
public:
ReadNextTag(CallData* callData);
void Proceed(bool ok) override;
bool Wait();
private:
Semaphore _readCompleteSemaphore;
CallData* _callData;
bool _success;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
struct LVRegistrationRequest
{
LStrHandle eventName;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
struct LVServerEvent
{
LStrHandle eventData;
int32_t serverId;
int32_t status;
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#ifdef _PS_4
#pragma pack (push, 1)
#endif
struct GeneralMethodEventData
{
LStrHandle methodName;
gRPCid* methodData;
};
#ifdef _PS_4
#pragma pack (pop)
#endif
//---------------------------------------------------------------------
//---------------------------------------------------------------------
void OccurServerEvent(LVUserEventRef event, gRPCid* data);
void OccurServerEvent(LVUserEventRef event, gRPCid* data, std::string eventMethodName);
std::string read_keycert(const std::string &filename);
//---------------------------------------------------------------------
//---------------------------------------------------------------------
class ProtoDescriptorString {
// Static members
static ProtoDescriptorString* m_instance;
static std::mutex m_mutex;
// Non static members
std::string m_descriptor;
int m_refcount = 0; // Not a normal refcount. Its counts the number of time we set the descriptor string.
// Default private constructor to prevent instantiation
ProtoDescriptorString() = default;
// Delete copy constructor and assignment operator
ProtoDescriptorString(const ProtoDescriptorString&) = delete;
ProtoDescriptorString& operator=(const ProtoDescriptorString&) = delete;
public:
// Return the static class instance
static ProtoDescriptorString* getInstance();
// Set the descriptor string
void setDescriptor(std::string);
// Get the descriptor string
std::string getDescriptor();
// Delete the instance based on the refcount
void deleteInstance();
};
}