Hello, I’m exploring the possibility of calling service methods and passing
existing data to it.
That is, starting the server to function without an explicit connection to
the client and receiving data from the client. This is something like a
transport, should work over UDP and is suitable for *unary* requests and
responses.
Based on *helloworld*.
Used: hack of contract violation and access to private fields; custom types
for mirroring inaccessible types from *.cc.
Everything works, `GreeterServiceImpl::SayHello` is called with the
necessary data, and there are the following problems.
I’m struggling with resource leaks now and the thread
`ThreadInternalsWindows::thread_body` hangs forever in the function
`grpc::internal::UnaryRunHandlerHelper()` on call
`param.call->cq()->Pluck(&ops);`
Any ideas on how to fix it? Or perhaps try a different approach to calling
service methods?
Here are some of the steps:
```
// client data, from gRPC helloworld, done as SerializeToArray()
std::vector< unsigned char > fromUdp = { 0x0a, 0x05, 0x77, 0x6f, 0x72,
0x6c, 0x64 };
// get grpc_core server
::grpc_core::Server *servC = ::grpc_core::Server::FromC( server ->c_server(
) );
// 'unprivate' hack to get access to
'&grpc_core::Server::registered_methods_'
typedef std::vector<std::unique_ptr<grpc_core::Server::RegisteredMethod>>
&rm_t;
rm_t vecRm2 = (servC) ->*get(B_member());
// at index 0 is "/helloworld.Greeter/SayHello"
grpc_core_Server_RegisteredMethod *srm0 =
(grpc_core_Server_RegisteredMethod *)vecRm2[ 0 ].get( );
// main method
auto matcher = srm0 ->matcher.get( );
// main call object
grpc_call_create_args args_call_create = {};
// emulate grpc_core::Server::ChannelData::AcceptStream and
Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone
...
// create channel
...
absl::StatusOr<grpc_core::RefCountedPtr<grpc_core::Channel>> channel0 =
grpc_core::Channel::CreateWithBuilder( &builder );
grpc_core::RefCountedPtr<grpc_core::Channel> channelX = channel0.value( );
...
// filling main call object
args_call_create.channel = channelX;
args_call_create.server = servC;
args_call_create.server_transport_data = reinterpret_cast<void* >( id ); //
for !is_client
args_call_create.send_deadline = grpc_core::Timestamp::InfFuture( );
// prepare to filling client data
grpc_call* call;
grpc_error_handle error = grpc_call_create( &args_call_create, &call );
grpc_call_stack* call_stack = grpc_call_get_call_stack( call );
grpc_call_element* elem = grpc_call_stack_element(call_stack, 0);
auto* calld = static_cast<grpc_core::Server::CallData*>(elem->call_data);
calld ->Start( elem );
// filling client data
calld ->payload_ = grpc_raw_byte_buffer_create( nullptr, 0 );
grpc_byte_buffer* buffer = calld ->payload_;
grpc_core::SliceBuffer buf;
grpc_core::Slice single = grpc_core::Slice::FromCopiedBuffer( fromUdp.data(
), fromUdp.size( ) );
buf.Append( std::move( single ) );
grpc_slice_buffer_move_into( buf.c_slice_buffer( ), &calld ->payload_
->data.raw.slice_buffer );
// call main method
matcher ->MatchOrQueue( 0, calld );
// something to wait execution in other thread
std::this_thread::sleep_for( std::chrono::seconds( 3 ) );
```
I think I need to emulate a call to some kind of `grpc_closure` in
`ExecCtx::Flush`, I can’t find it yet.
This is my first post. While searching, I couldn't find anyone posting
links to their repo here. Can I post a GitHub link here as an add-on?
--
You received this message because you are subscribed to the Google Groups
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/grpc-io/ea62a088-88e3-4042-915a-94301799e8f8n%40googlegroups.com.