前言
上篇文章讲解了项目搭建以及脚手架Cli的搭建和简单的测试,由于目前设计的框架分为socket服务和Rpc服务两部分,那么本篇文章将主要实现创建grpc服务部分
项目环境
- 系统:windows10
- Node:v16.14.2
- pnpm:8.2.0
项目开源地址github.com/whwanyt/pin…
创建
由于要实现socket.io和grpc两个服务并对外保持一直的调用方式,所以将socket.io适配从core包中抽出,在packages目录下新建platform-grpc和platform-socket.io两个包,并进行初始化
安装
实现grpc服务,我们主要是基于@grpc/grpc-js
和@grpc/proto-loader
这两个库来实现
pnpm i @grpc/grpc-js@grpc/proto-loader
platform-socket.io 实现
import { createServer } from "http";
import { Server, ServerOptions as SocketServerOptions } from "socket.io";
export class SocketServer {
private server: Server | undefined;
create(options: SocketServerOptions) {
const httpServer = createServer();
this.server = new Server(httpServer, options as SocketServerOptions);
return this;
}
listen(port: number) {
this.server!.listen(port);
}
}
platform-grpc 实现
import {
Server,
ServerCredentials,
loadPackageDefinition,
UntypedServiceImplementation,
} from "@grpc/grpc-js";
import protoLoader from "@grpc/proto-loader";
export class GrpcServer {
private server: Server | undefined;
create() {
this.server = new Server();
return this;
}
listen(host: string) {
this.server!.bindAsync(host, ServerCredentials.createInsecure(), () => {
this.server!.start();
});
}
}
以上便是对grpc和socket.io的简单库实现,在之后gprc还需要实现client相关,此处先实现服务侧
Core修改
将@pinecone/platform-socket.io
和@pinecone/platform-grpc
两个包导入到core项目中并修改初始化方法
import { SocketServer } from "@pinecone/platform-socket.io";
import { GrpcServer } from "@pinecone/platform-grpc";
....
async initialize(options: ServiceOptions) {
switch (options.transport) {
case Transport.GRPC:
return new GrpcServer().create();
default:
return new SocketServer().create(options.options);
}
}
如上便是实现了通过不同的项目启动参数实现不同的服务初始化 修改启动函数
listen(port: number) {
switch (this.options!.transport) {
case Transport.GRPC:
(this.server! as GrpcServer).listen("0.0.0.0:" + port);
Log.Info(`GrpcServer prot ${port}`, "AppServer");
break;
case Transport.SOCKET:
(this.server! as SocketServer).listen(port);
Log.Info(`SocketServer prot http://127.0.0.1:${port}`, "AppServer");
break;
default:
Log.Error(`暂不支持该服务类型`, "AppServer");
break;
}
}
在上边示例代码中,通过判断是grpc还是socket服务传入host/prot参数
测试
在我们之前创建的example测试项目中先不进行修改直接启动
socket服务启动测试
import { AppFactory, Transport } from "@pinecone/core";
import { AppModule } from "./app";
async function main() {
const app = await AppFactory.create(AppModule, {
transport: Transport.GRPC,
options: {},
});
app.listen(3000);
}
main();
Grpc服务启动测试
import { AppFactory, Transport } from "@pinecone/core";
import { AppModule } from "./app";
async function main() {
const app = await AppFactory.create(AppModule, {
transport: Transport.GRPC,
options: {},
});
app.listen(3000);
}
main();
小结
以上是这个游戏服务框架的Core-Grpc部分的实现,也对项目整体结构进行了进一步优化,下一篇将主要讲解实现一个日志库来实现更优化的日志输出和存储
后记
希望大佬们提出宝贵意见,谢谢👏