Skip to content

Commit

Permalink
README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
fish-tennis committed May 29, 2024
1 parent 8a47ef2 commit 8ecaacf
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 90 deletions.
71 changes: 27 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,36 @@ High performance network library,especially for game servers
- rpc
- Support Tcp,WebSocket(ws and wss)

## Core module

### Listener(https://github.com/fish-tennis/gnet/blob/main/listener.go)

Listen to a certain port, start a listening goroutine, and manage the connected connections

create a Listener:

## Usage
run a server
```go
netMgr.NewListener("127.0.0.1:10001", connectionConfig, codec, &echoServerHandler{}, &echoListenerHandler{})
codec := gnet.NewProtoCodec(nil)
handler := gnet.NewDefaultConnectionHandler(codec)
handler.Register(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage), onTestMessage, new(pb.TestMessage))
listenerConfig := &gnet.ListenerConfig{
AcceptConfig: gnet.DefaultConnectionConfig,
}
listenerConfig.AcceptConfig.Codec = codec
listenerConfig.AcceptConfig.Handler = handler
gnet.GetNetMgr().NewListener(ctx, "localhost:10001", listenerConfig)
```

### Connection(https://github.com/fish-tennis/gnet/blob/main/connection.go)

There are two types of connection:

- connector(call Connect() to connect the server)
- accept by listener(the server call accept() to accept a new connection)

create a Connector:

run a client
```go
netMgr.NewConnector("127.0.0.1:10001", connectionConfig, codec, &echoClientHandler{}, nil)
codec := gnet.NewProtoCodec(nil)
handler := gnet.NewDefaultConnectionHandler(codec)
handler.Register(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage), onTestMessage, new(pb.TestMessage))
connectionConfig := gnet.DefaultConnectionConfig
connectionConfig.Codec = clientCodec
connectionConfig.Handler = clientHandler
connector := gnet.GetNetMgr().NewConnector(ctx, "localhost:10001", &connectionConfig, nil)
connector.SendPacket(gnet.NewProtoPacket(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage),
&pb.TestMessage{
Name: "hello",
}))
```

### Packet(https://github.com/fish-tennis/gnet/blob/main/packet.go)

The common practices in game servers,the packet consists of a message number and a proto message,meanwhile gnet reserve a binary interface

### Encoding and decoding(https://github.com/fish-tennis/gnet/blob/main/codec.go)
## Encoding and decoding(https://github.com/fish-tennis/gnet/blob/main/codec.go)

gnet divide TCP stream based decoding into three layers

Expand All @@ -61,29 +61,12 @@ Layer3:protobuf deserialize,generate proto.Message

![decode](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/packet_decode.png)

### Handler(https://github.com/fish-tennis/gnet/blob/main/handler.go)

ListenerHandler:when the server accept a new connection or the accepted connection disconnected

ConnectionHandler:when the connection connected,disconnected,receive packet

gnet provided a default ConnectionHandler:

```go
handler := NewDefaultConnectionHandler(codec)
// register packet and process function
handler.Register(123, OnTest, new(pb.TestMessage))
func OnTest(conn Connection, packet Packet) {
testMessage := packet.Message().(*pb.TestMessage)
// do something
}
```

### Use RingBuffer to increase performance
## Use RingBuffer to increase performance

![ringbuffer-performance](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/ringbuffer-performance.png)

### rpc
## rpc
Rpc send a request to target and block wait reply,similar to grpc-go,but gnet use command id instead of method name
```go
request := gnet.NewProtoPacket(cmd, &pb.HelloRequest{
Expand All @@ -97,7 +80,7 @@ if err != nil {
logger.Info("reply:%v", reply)
```

### goroutine
## goroutine

![connection_goroutine](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/connection_goroutine.png)

Expand Down
87 changes: 41 additions & 46 deletions README_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,36 @@
- rpc
- 目前支持Tcp,WebSocket(ws and wss)

## 核心模块

### 监听Listener(https://github.com/fish-tennis/gnet/blob/main/listener.go)

监听某个端口,开启一个监听协程,并管理监听到的连接

创建一个Listener:

## 使用
运行一个服务器
```go
netMgr.NewListener("127.0.0.1:10001", connectionConfig, codec, &echoServerHandler{}, &echoListenerHandler{})
codec := gnet.NewProtoCodec(nil)
handler := gnet.NewDefaultConnectionHandler(codec)
handler.Register(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage), onTestMessage, new(pb.TestMessage))
listenerConfig := &gnet.ListenerConfig{
AcceptConfig: gnet.DefaultConnectionConfig,
}
listenerConfig.AcceptConfig.Codec = codec
listenerConfig.AcceptConfig.Handler = handler
gnet.GetNetMgr().NewListener(ctx, "localhost:10001", listenerConfig)
```

### 连接Connection(https://github.com/fish-tennis/gnet/blob/main/connection.go)

对连接的封装,连接有2种:

- 一种是发起连接的一方(调用connect连接服务器的一方)
- 一种是Listener监听到的连接(Listener通过accept监听到的连接)

创建一个Connector:

运行一个客户端
```go
netMgr.NewConnector("127.0.0.1:10001", connectionConfig, codec, &echoClientHandler{}, nil)
codec := gnet.NewProtoCodec(nil)
handler := gnet.NewDefaultConnectionHandler(codec)
handler.Register(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage), onTestMessage, new(pb.TestMessage))
connectionConfig := gnet.DefaultConnectionConfig
connectionConfig.Codec = clientCodec
connectionConfig.Handler = clientHandler
connector := gnet.GetNetMgr().NewConnector(ctx, "localhost:10001", &connectionConfig, nil)
connector.SendPacket(gnet.NewProtoPacket(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage),
&pb.TestMessage{
Name: "hello",
}))
```

### 数据包Packet(https://github.com/fish-tennis/gnet/blob/main/packet.go)

游戏行业的常规做法,数据包由消息号和proto消息构成,同时预留一个二进制数据的接口(
不使用proto消息的应用可以使用该接口,如示例[不使用proto的echo](https://github.com/fish-tennis/gnet/blob/main/example/echo_data_test.go))

### 编解码Codec(https://github.com/fish-tennis/gnet/blob/main/codec.go)
## 编解码Codec(https://github.com/fish-tennis/gnet/blob/main/codec.go)

gnet把基于TCP流的解码分成3层

Expand All @@ -63,33 +62,15 @@ gnet把基于TCP流的解码分成3层

![decode](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/packet_decode.png)

### 应用层接口Handler(https://github.com/fish-tennis/gnet/blob/main/handler.go)

ListenerHandler:当监听到新连接和连接断开时,提供回调接口

ConnectionHandler:在连接成功或失败,连接断开,收到数据包时,提供回调接口

默认的ConnectionHandler用法:

```go
handler := NewDefaultConnectionHandler(codec)
// 注册消息结构体和对应的回调函数
handler.Register(123, OnTest, new(pb.TestMessage))
func OnTest(conn Connection, packet Packet) {
testMessage := packet.Message().(*pb.TestMessage)
// do something
}
```

### 使用RingBuffer来提高性能
## 使用RingBuffer来提高性能

![ringbuffer-performance](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/ringbuffer-performance.png)

举例:在一个游戏地图中,你周围有很多其他玩家,其他玩家的数据更新需要同步给你,服务器会向你发送很多Packet,如果不使用RingBuffer机制, 就会每个Packet调用一次net.Conn.Write,而net.Conn.Write是系统调用,代价是比较高的,如TcpConnectionSimple

如果使用RingBuffer机制,就会在实际调用net.Conn.Write之前,对多个Packet进行合并,从而减少net.Conn.Write的调用次数,从而提高性能.

### rpc
## rpc
gnet提供了类似rpc的接口,并不是标准的rpc方法调用,gnet使用消息号作为标识,而不是方法名,
向目标连接发送请求,并阻塞等待回复,本质类似于grpc-go
```go
Expand All @@ -104,12 +85,26 @@ if err != nil {
logger.Info("reply:%v", reply)
```

### go协程
## go协程

![connection_goroutine](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/connection_goroutine.png)

## 示例
example/helloworld: protobuf数据包

example/data_packet: 非protobuf数据包

example/custom_packet: 扩展自定义数据包

example/tcp_connection_simple: 不使用RingBuffer

example/packet_size: 数据包长度允许大于RingBuffer

example/websocket: websocket

example/rpc: rpc调用

example/simulate_game: 模拟一个简单的游戏场景,对比使用RingBuffer的性能差异

## 客户端网络库 Connector Library
C#: [gnet_csharp](https://github.com/fish-tennis/gnet_csharp)
Expand Down

0 comments on commit 8ecaacf

Please sign in to comment.