Apache thrift RPC フレームワークを使用して、PHP クライアントと C++ サーバー間の通信を確立しようとしています。何時間も実りのないデバッグを行った後、同じthriftファイルからJavaサーバーを構築し、動作するようになりました. C++ サーバーを実行すると、どのメソッドも呼び出されず、Java サーバーから応答を受け取った同じクライアントが例外をスローしますException: TSocket: timed out reading 4 bytes from localhost:65123
(クライアントの送信タイムアウトと受信タイムアウトの両方を 5 秒に設定したにもかかわらず)。少なくとも、このエラーは、サーバーが実行されていないときに発生するエラー [ ] とは異なるTSocket: Could not connect to localhost:65123 (Connection refused [111])
ため、C++ サーバーが少なくともクライアントが通信しているポートにバインドされていることがわかります。
(動作中の)Javaサーバーコードは次のとおりです。
public class Server
{
public static void Start(EncabulationGame.Processor<EncabulationInputListener> processor)
{
try
{
TServerTransport serverTransport = new TServerSocket(65123);
TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
System.out.println("Starting the simple server...");
server.serve();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
Start(new EncabulationGame.Processor<EncabulationInputListener>(new EncabulationInputListener()));
}
}
(非稼働) C++ サーバーは、アプリケーションのメイン処理スレッドとは別のスレッドで生成されます。コードは次のようになります。
void* ListenerThreadEntryPoint(void* threadStartData)
{
struct InputListenerThreadStartupData * threadData;
threadData = ((struct InputListenerThreadStartupData *) threadStartData);
int port = threadData->ListnerThreadPort;
shared_ptr<EncabulationGameHandler> handler(new EncabulationGameHandler(threadData));
shared_ptr<TProcessor> processor(new EncabulationGameProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
Java と C++ のサーバー コード スニペットはどちらも、thrift コンパイラが生成するスケルトン コードからカット アンド ペーストされています。
私は本当にこれを理解することはできません。C++ サーバーがクライアントに応答しないのはなぜですか? ハンドラー (コンストラクター以外) のどのメソッドも呼び出されないのはなぜですか? コミュニティが提供できるあらゆる支援に感謝します。thrift 0.9.0 ビルドを使用しています。
役立つ場合は、ハンドラーを実装するコードを次に示します。
class EncabulationGameHandler : virtual public EncabulationGameIf {
public:
EncabulationGameHandler(InputListenerThreadStartupData * threadData) {
// Your initialization goes here
}
int32_t RegisterPlayer() {
// Your implementation goes here
printf("RegisterPlayer\n");
}
void UnRegisterPlayer(const int32_t playerID) {
// Your implementation goes here
printf("UnRegisterPlayer\n");
}
bool IsGameRunning() {
// Your implementation goes here
printf("IsGameRunning\n");
}
int32_t GetPlayerScore(const int32_t playerID) {
// Your implementation goes here
printf("GetPlayerScore\n");
}
void Bounce(const int32_t playerID) {
// Your implementation goes here
printf("Bounce\n");
}
void ChangeColor(const int32_t playerID) {
// Your implementation goes here
printf("ChangeColor\n");
}
};