用c++写一个游戏服务端gRPC写网络框架
时间: 2024-02-18 10:37:00 浏览: 94
基于c++实现的GRPC服务端demo
3星 · 编辑精心推荐
好的,以下是一个简单的游戏服务端 gRPC 网络框架的实现,使用 C++ 编写:
1. 安装 gRPC
首先,需要安装 gRPC 库和 protobuf 库。可以按照官方文档进行安装。
2. 编写.proto文件
定义 RPC 接口,可以在.proto文件中定义。例如,我们定义以下接口:
```
syntax = "proto3";
package game;
service GameService {
rpc Connect (ClientInfo) returns (ServerInfo) {}
rpc Move (MoveRequest) returns (MoveResponse) {}
}
message ClientInfo {
string username = 1;
}
message ServerInfo {
int32 player_id = 1;
}
message MoveRequest {
int32 player_id = 1;
int32 x = 2;
int32 y = 3;
}
message MoveResponse {
bool success = 1;
}
```
3. 生成代码
使用 protobuf 工具生成客户端和服务器端的代码。在终端中运行以下命令:
```
$ protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` game.proto
$ protoc -I . --cpp_out=. game.proto
```
将生成的代码添加到项目中。
4. 实现服务器端
在服务器端,需要实现 gRPC 服务。以下是一个简单的实现:
```
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "game.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using game::ClientInfo;
using game::ServerInfo;
using game::MoveRequest;
using game::MoveResponse;
using game::GameService;
class GameServiceImpl final : public GameService::Service {
Status Connect(ServerContext* context, const ClientInfo* request, ServerInfo* response) override {
std::string prefix("Hello ");
response->set_player_id(1);
response->set_username(prefix + request->username());
return Status::OK;
}
Status Move(ServerContext* context, const MoveRequest* request, MoveResponse* response) override {
response->set_success(true);
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
GameServiceImpl service;
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main(int argc, char** argv) {
RunServer();
return 0;
}
```
在上面的代码中,我们实现了 Connect 和 Move 这两个接口。Connect 接口用于连接服务器,返回一个服务器分配的 player_id 和一个欢迎消息;Move 接口用于移动游戏角色。
5. 实现客户端
在客户端,需要使用 gRPC 客户端调用服务器提供的接口。以下是一个简单的实现:
```
#include <iostream>
#include <memory>
#include <string>
#include <grpc++/grpc++.h>
#include "game.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using game::ClientInfo;
using game::ServerInfo;
using game::MoveRequest;
using game::MoveResponse;
using game::GameService;
class GameClient {
public:
GameClient(std::shared_ptr<Channel> channel) : stub_(GameService::NewStub(channel)) {}
std::string Connect(const std::string& username) {
ClientInfo request;
request.set_username(username);
ServerInfo response;
ClientContext context;
Status status = stub_->Connect(&context, request, &response);
if (status.ok()) {
return response.username();
} else {
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
return "RPC failed";
}
}
bool Move(int32_t player_id, int32_t x, int32_t y) {
MoveRequest request;
request.set_player_id(player_id);
request.set_x(x);
request.set_y(y);
MoveResponse response;
ClientContext context;
Status status = stub_->Move(&context, request, &response);
if (status.ok()) {
return response.success();
} else {
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
return false;
}
}
private:
std::unique_ptr<GameService::Stub> stub_;
};
int main(int argc, char** argv) {
GameClient client(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
std::string username;
std::cout << "Enter your username: ";
std::cin >> username;
std::string welcome_message = client.Connect(username);
std::cout << welcome_message << std::endl;
int32_t player_id = 1;
int32_t x, y;
std::cout << "Enter x and y: ";
std::cin >> x >> y;
bool success = client.Move(player_id, x, y);
std::cout << "Move " << (success ? "succeeded" : "failed") << std::endl;
return 0;
}
```
在上面的代码中,我们实现了 Connect 和 Move 这两个接口的调用。Connect 接口用于连接服务器并获取欢迎消息;Move 接口用于移动游戏角色。
6. 编译运行
使用以下命令编译服务器端和客户端:
```
$ g++ -std=c++11 -I./ -I./generated -pthread -lgrpc++ -lgrpc -lprotobuf server.cpp game.grpc.pb.cc game.pb.cc -o server
$ g++ -std=c++11 -I./ -I./generated -pthread -lgrpc++ -lgrpc -lprotobuf client.cpp game.grpc.pb.cc game.pb.cc -o client
```
运行服务器端:
```
$ ./server
Server listening on 0.0.0.0:50051
```
运行客户端:
```
$ ./client
Enter your username: Alice
Hello Alice
Enter x and y: 1 2
Move succeeded
```
阅读全文