# 5.1 网关服务器

# 5.1.1 基础介绍

网关服务器作为所有客户端的入口,通常具备以下功能:

  • 为客户端提供连接支持
  • 管理并维护客户端连接
  • 转发客户端消息到目标节点服务器
  • 下发后端服务器消息到指定客户端

due (opens new window) 框架中,网关服(gate)采用模块化的架构思路,开发者可以根据自身的业务情况任意搭配模块化组件。

# 5.1.2 TCP网关示例

以下完整示例详见:gate-tcp-example (opens new window)

  1. 创建项目
$ mkdir gate-tcp-example
1
  1. 安装依赖
$ cd gate-tcp-example
$ go mod init gate-tcp-example
$ go get github.com/dobyte/due/v2@v2.4.2
$ go get github.com/dobyte/due/network/tcp/v2@e5cd009
$ go get github.com/dobyte/due/locate/redis/v2@e5cd009
$ go get github.com/dobyte/due/registry/consul/v2@e5cd009
1
2
3
4
5
6
  1. 启动配置

文件位置:gate-tcp-example/etc/etc.toml (opens new window)

# 进程号
pid = "./run/due.pid"
# 开发模式。支持模式:debug、test、release(设置优先级:配置文件 < 环境变量 < 运行参数 < mode.SetMode())
mode = "debug"
# 统一时区设置。项目中的时间获取请使用xtime.Now()
timezone = "Local"
# 容器关闭最大等待时间。支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为0
shutdownMaxWaitTime = "0s"

[cluster.gate]
    # 实例ID,集群中唯一。不填写默认自动生成唯一的实例ID
    id = ""
    # 实例名称
    name = "gate"
    # 内建RPC服务器监听地址。不填写默认随机监听
    addr = ":0"
    # 是否将内部通信地址暴露到公网。默认为false
    expose = false
    # RPC调用超时时间,支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为3s
    timeout = "3s"
    # 无状态路由消息分发策略。支持策略:随机(random)、轮询(rr)、加权轮询(wrr)。默认为random
    dispatch = "random"
    # 实例元数据
    [cluster.gate.metadata]
        # 键值对,且均为字符串类型。由于注册中心的元数据参数限制,建议将键值对的数量控制在20个以内,键的字符长度控制在127个字符内,值得字符长度控制在512个字符内。
        key = "value"

[locate.redis]
    # 客户端连接地址
    addrs = ["127.0.0.1:6379"]
    # 数据库号
    db = 0
    # 用户名
    username = ""
    # 密码
    password = ""
    # 私钥文件
    keyFile = ""
    # 证书文件
    certFile = ""
    # CA证书文件
    caFile = ""
    # 最大重试次数
    maxRetries = 3
    # key前缀
    prefix = "due:locate"

[registry.consul]
    # 客户端连接地址,默认为127.0.0.1:8500
    addr = "127.0.0.1:8500"
    # 是否启用健康检查,默认为true
    healthCheck = true
    # 健康检查时间间隔(秒),仅在启用健康检查后生效,默认为10
    healthCheckInterval = 10
    # 健康检查超时时间(秒),仅在启用健康检查后生效,默认为5
    healthCheckTimeout = 5
    # 是否启用心跳检查,默认为true
    heartbeatCheck = true
    # 心跳检查时间间隔(秒),仅在启用心跳检查后生效,默认为10
    heartbeatCheckInterval = 10
    # 健康检测失败后自动注销服务时间(秒),默认为30
    deregisterCriticalServiceAfter = 30

[network.tcp.server]
    # 服务器监听地址
    addr = ":3553"
    # 私钥文件
    keyFile = ""
    # 证书文件
    certFile = ""
    # 服务器最大连接数
    maxConnNum = 5000
    # 心跳间隔时间;设置为0则不启用心跳检测,支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为10s
    heartbeatInterval = "10s"
    # 心跳机制,默认resp
    heartbeatMechanism = "resp"
    # 授权超时时间,(在客户端建立连接后,如果在授权超时时间内未进行绑定用户操作,则被认定为未授权连接,服务器会强制断开连接)支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为0s,不进行授权检测
    authorizeTimeout = "0s"

[packet]
    # 字节序,默认为big。可选:little | big
    byteOrder = "big"
    # 路由字节数,默认为2字节
    routeBytes = 2
    # 序列号字节数,默认为2字节
    seqBytes = 2
    # 消息字节数,默认为5000字节
    bufferBytes = 5000
    # 是否携带服务器心跳时间
    heartbeatTime = false

[log]
    # 日志输出级别,可选:debug | info | warn | error | fatal | panic
    level = "info"
    # 堆栈的最低输出级别,可选:debug | info | warn | error | fatal | panic
    stackLevel = "error"
    # 时间格式,标准库时间格式
    timeFormat = "2006/01/02 15:04:05.000000"
    # 输出栈的跳过深度
    callSkip = 2
    # 是否启用调用文件全路径
    callFullPath = true
    # 日志输出终端
    terminals = ["console", "file"]
    # 控制台同步器配置
    [log.console]
        # 日志输出格式,可选:text | json
        format = "text"
    # 文件同步器配置
    [log.file]
        # 输出文件路径
        path = "./log/due.log"
        # 日志输出格式,可选:text | json
        format = "text"
        # 文件最大留存时间,d:天、h:时、m:分、s:秒
        maxAge = "7d"
        # 文件最大尺寸限制,支持单位: B | K | KB | M | MB | G | GB | T | TB | P | PB | E | EB | Z | ZB,默认为100M
        maxSize = "100M"
        # 文件翻转方式,可选:none | year | month | week | day | hour,默认为none
        rotate = "none"
        # 文件翻转时是否对文件进行压缩
        compress = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  1. 编写示例

文件位置:gate-tcp-example/main.go (opens new window)

package main

import (
	"github.com/dobyte/due/locate/redis/v2"
	"github.com/dobyte/due/network/tcp/v2"
	"github.com/dobyte/due/registry/consul/v2"
	"github.com/dobyte/due/v2"
	"github.com/dobyte/due/v2/cluster/gate"
)

func main() {
	// 创建容器
	container := due.NewContainer()
	// 创建服务器
	server := tcp.NewServer()
	// 创建用户定位器
	locator := redis.NewLocator()
	// 创建服务发现
	registry := consul.NewRegistry()
	// 创建网关组件
	component := gate.NewGate(
		gate.WithServer(server),
		gate.WithLocator(locator),
		gate.WithRegistry(registry),
	)
	// 添加网关组件
	container.Add(component)
	// 启动容器
	container.Serve()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  1. 启动服务
$ cd gate-tcp-example
$ go run main.go
                    ____  __  ________
                   / __ \/ / / / ____/
                  / / / / / / / __/
                 / /_/ / /_/ / /___
                /_____/\____/_____/
┌──────────────────────────────────────────────────────┐
| [Website] https://github.com/dobyte/due              |
| [Version] v2.4.2                                     |
└──────────────────────────────────────────────────────┘
┌────────────────────────Global────────────────────────┐
| PID: 10680                                           |
| Mode: debug                                          |
| Time: 2025-10-30 11:44:50.3154263 +0800 CST          |
└──────────────────────────────────────────────────────┘
┌─────────────────────────Gate─────────────────────────┐
| ID: c996de98-b542-11f0-8753-f4f19e1f0070             |
| Name: gate                                           |
| Link: 192.168.2.202:51121                            |
| Server: [tcp] 0.0.0.0:3553                           |
| Locator: redis                                       |
| Registry: consul                                     |
└──────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 5.1.2 WS网关示例

以下完整示例详见:gate-ws-example (opens new window)

  1. 创建项目
$ mkdir gate-ws-example
1
  1. 安装依赖
$ cd gate-ws-example
$ go mod init gate-ws-example
$ go get github.com/dobyte/due/v2@v2.4.2
$ go get github.com/dobyte/due/network/ws/v2@e5cd009
$ go get github.com/dobyte/due/locate/redis/v2@e5cd009
$ go get github.com/dobyte/due/registry/consul/v2@e5cd009
1
2
3
4
5
6
  1. 启动配置

文件位置:gate-ws-example/etc/etc.toml (opens new window)

# 进程号
pid = "./run/due.pid"
# 开发模式。支持模式:debug、test、release(设置优先级:配置文件 < 环境变量 < 运行参数 < mode.SetMode())
mode = "debug"
# 统一时区设置。项目中的时间获取请使用xtime.Now()
timezone = "Local"
# 容器关闭最大等待时间。支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为0
shutdownMaxWaitTime = "0s"

[cluster.gate]
    # 实例ID,集群中唯一。不填写默认自动生成唯一的实例ID
    id = ""
    # 实例名称
    name = "gate"
    # 内建RPC服务器监听地址。不填写默认随机监听
    addr = ":0"
    # 是否将内部通信地址暴露到公网。默认为false
    expose = false
    # RPC调用超时时间,支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为3s
    timeout = "3s"
    # 无状态路由消息分发策略。支持策略:随机(random)、轮询(rr)、加权轮询(wrr)。默认为random
    dispatch = "random"
    # 实例元数据
    [cluster.gate.metadata]
        # 键值对,且均为字符串类型。由于注册中心的元数据参数限制,建议将键值对的数量控制在20个以内,键的字符长度控制在127个字符内,值得字符长度控制在512个字符内。
        key = "value"

[locate.redis]
    # 客户端连接地址
    addrs = ["127.0.0.1:6379"]
    # 数据库号
    db = 0
    # 用户名
    username = ""
    # 密码
    password = ""
    # 私钥文件
    keyFile = ""
    # 证书文件
    certFile = ""
    # CA证书文件
    caFile = ""
    # 最大重试次数
    maxRetries = 3
    # key前缀
    prefix = "due:locate"

[registry.consul]
    # 客户端连接地址,默认为127.0.0.1:8500
    addr = "127.0.0.1:8500"
    # 是否启用健康检查,默认为true
    healthCheck = true
    # 健康检查时间间隔(秒),仅在启用健康检查后生效,默认为10
    healthCheckInterval = 10
    # 健康检查超时时间(秒),仅在启用健康检查后生效,默认为5
    healthCheckTimeout = 5
    # 是否启用心跳检查,默认为true
    heartbeatCheck = true
    # 心跳检查时间间隔(秒),仅在启用心跳检查后生效,默认为10
    heartbeatCheckInterval = 10
    # 健康检测失败后自动注销服务时间(秒),默认为30
    deregisterCriticalServiceAfter = 30

[network.ws.server]
    # 服务器监听地址
    addr = ":3553"
    # 客户端连接路径
    path = "/"
    # 服务器最大连接数
    maxConnNum = 5000
    # 秘钥文件
    keyFile = ""
    # 证书文件
    certFile = ""
    # 跨域检测,空数组时不允许任何连接升级成websocket,未设置此参数时允许所有的链接升级成websocket
    origins = ["*"]
    # 握手超时时间,支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为10s
    handshakeTimeout = "10s"
    # 心跳检测间隔时间。设置为0则不启用心跳检测,支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为10s
    heartbeatInterval = "10s"
    # 心跳机制,默认为resp响应式心跳。可选:resp 响应式心跳 | tick 定时主推心跳
    heartbeatMechanism = "resp"
    # 授权超时时间,(在客户端建立连接后,如果在授权超时时间内未进行绑定用户操作,则被认定为未授权连接,服务器会强制断开连接)支持单位:纳秒(ns)、微秒(us | µs)、毫秒(ms)、秒(s)、分(m)、小时(h)、天(d)。默认为0s,不进行授权检测
    authorizeTimeout = "0s"

[packet]
    # 字节序,默认为big。可选:little | big
    byteOrder = "big"
    # 路由字节数,默认为2字节
    routeBytes = 2
    # 序列号字节数,默认为2字节
    seqBytes = 2
    # 消息字节数,默认为5000字节
    bufferBytes = 5000
    # 是否携带服务器心跳时间
    heartbeatTime = false

[log]
    # 日志输出级别,可选:debug | info | warn | error | fatal | panic
    level = "info"
    # 堆栈的最低输出级别,可选:debug | info | warn | error | fatal | panic
    stackLevel = "error"
    # 时间格式,标准库时间格式
    timeFormat = "2006/01/02 15:04:05.000000"
    # 输出栈的跳过深度
    callSkip = 2
    # 是否启用调用文件全路径
    callFullPath = true
    # 日志输出终端
    terminals = ["console", "file"]
    # 控制台同步器配置
    [log.console]
        # 日志输出格式,可选:text | json
        format = "text"
    # 文件同步器配置
    [log.file]
        # 输出文件路径
        path = "./log/due.log"
        # 日志输出格式,可选:text | json
        format = "text"
        # 文件最大留存时间,d:天、h:时、m:分、s:秒
        maxAge = "7d"
        # 文件最大尺寸限制,支持单位: B | K | KB | M | MB | G | GB | T | TB | P | PB | E | EB | Z | ZB,默认为100M
        maxSize = "100M"
        # 文件翻转方式,可选:none | year | month | week | day | hour,默认为none
        rotate = "none"
        # 文件翻转时是否对文件进行压缩
        compress = false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  1. 编写示例

文件位置:gate-ws-example/main.go (opens new window)

package main

import (
	"github.com/dobyte/due/locate/redis/v2"
	"github.com/dobyte/due/network/ws/v2"
	"github.com/dobyte/due/registry/consul/v2"
	"github.com/dobyte/due/v2"
	"github.com/dobyte/due/v2/cluster/gate"
)

func main() {
	// 创建容器
	container := due.NewContainer()
	// 创建服务器
	server := ws.NewServer()
	// 创建用户定位器
	locator := redis.NewLocator()
	// 创建服务发现
	registry := consul.NewRegistry()
	// 创建网关组件
	component := gate.NewGate(
		gate.WithServer(server),
		gate.WithLocator(locator),
		gate.WithRegistry(registry),
	)
	// 添加网关组件
	container.Add(component)
	// 启动容器
	container.Serve()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  1. 启动服务
$ cd gate-ws-example
$ go run main.go
                    ____  __  ________
                   / __ \/ / / / ____/
                  / / / / / / / __/
                 / /_/ / /_/ / /___
                /_____/\____/_____/
┌──────────────────────────────────────────────────────┐
| [Website] https://github.com/dobyte/due              |
| [Version] v2.4.2                                     |
└──────────────────────────────────────────────────────┘
┌────────────────────────Global────────────────────────┐
| PID: 12900                                           |
| Mode: debug                                          |
| Time: 2025-10-30 11:46:10.5658389 +0800 CST          |
└──────────────────────────────────────────────────────┘
┌─────────────────────────Gate─────────────────────────┐
| ID: f96c107b-b542-11f0-b80e-f4f19e1f0070             |
| Name: gate                                           |
| Link: 192.168.2.202:51392                            |
| Server: [ws] 0.0.0.0:3553                            |
| Locator: redis                                       |
| Registry: consul                                     |
└──────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24