# go-server
项目地址:[https://github.com/zboyco/go-server](https://github.com/zboyco/go-server)
go-server 是我在学习golang的过程中,从最简单的socket一步一步改造形成的。
目前功能如下:
1. 普通的socket功能,支持 tcp 和 udp,支持ip4和ip6
2. 使用标准库`bufio.Scanner`实现拆包,可以直接使用`bufio.Scanner`内置的拆包协议,当然也可以自定义拆包协议
3. 提供普通`OnMessage`和命令路由两种使用模式
4. 提供单个`Action`添加路由方法,同时也采用实现`ActionModule`接口的方式批量添加路由
5. 过滤器支持自定义,只需实现`ReceiveFilter`接口
6. 支持设置会话超时时间,超时的会话会自动关闭
7. 提供会话查找方法,可以根据ID或自定义属性查找会话
8. 支持tls
9. 提供简单的客户端实现[github.com/zboyco/go-server/client]
10. ...
问题如下:
1. ...原谅我不会写文档
2. 有什么问题大家留言
3. ...
# 使用方法
## 安装
```text
go get github.com/zboyco/go-server
```
## 简单使用
默认使用换行符`\n`拆分数据包
```go
// main
func main() {
// 新建服务
mainServer := goserver.New(goserver.TCP, "", 8080)
// 注册OnMessage事件
mainServer.SetOnMessage(onMessage)
// 开启服务
mainServer.Start()
}
// 接收数据方法
func onMessage(client *goserver.AppSession, token []byte) ([]byte, error) {
// 将bytes转为字符串
result := string(token)
// 输出结果
log.Println("接收到客户[", client.ID, "]数据:", result)
// 发送给客户端
// client.Send([]byte("Got!"))
return []byte("Got!"), nil
}
```
## 使用tls
使用`NewTCPWithTLS`方法新建一个tls tcp服务
> 目前只支持 tcp 协议
```go
crt, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
log.Fatalln(err.Error())
}
// 新建服务
mainServer := goserver.NewTCPWithTLS("", 8080, &tls.Config{
Certificates: []tls.Certificate{crt},
})
```
## 自定义拆包协议
go-server 采用标准库`bufio.Scanner`实现数据拆包,默认使用`ScanLines`实现换行符拆包,支持自定义拆包规则,可以根据自己的需求制定,只需要自定义一个`bufio.SplitFunc`方法即可。
假设我们采用 `head`+`body`的方式定义package,并指定第1个字节是`'$'`,第4个字节是`'#'`,第2、3位两个字节使用`int16`存储`body`长度,例子如下:
```go
func main() {
// 新建服务
mainServer := goserver.New(goserver.TCP, "", 8080)
// 根据协议定义拆包规则
mainServer.SetSplitFunc(func(data []byte, atEOF bool) (int, []byte, error) {
if atEOF {
return 0, nil, errors.New("EOF")
}
if data[0] != '$' || data[3] != '#' {
return 0, nil, errors.New("数据异常")
}
if len(data) > 4 {
length := int16(0)
binary.Read(bytes.NewReader(data[1:3]), binary.BigEndian, &length)
if int(length)+4 <= len(data) {
return int(length) + 4, data[4 : int(length)+4], nil
}
}
return 0, nil, nil
})
// 注册OnMessage事件
mainServer.SetOnMessage(onMessage)
// 开启服务
mainServer.Start()
}
// 接收数据方法
func onMessage(client *goserver.AppSession, token []byte) ([]byte, error) {
// 将bytes转为字符串
result := string(token)
// 输出结果
log.Println("接收到客户[", client.ID, "]数据:", result)
// 发送给客户端
// client.Send([]byte("Got!"))
return []byte("Got!"), nil
}
```
## 使用命令路由方式调用方法
上面的使用方法,我们都将接收到的消息放在一个`onMessage`中处理,而多数时候,我们希望将不同的请求使用不同的方法处理,go-server 提供了一种方式,配合`ReceiveFilter`过滤器 和`ActionModule`处理模块,可以实现不同请求调用不同方法。
`ReceiveFilter`过滤器有两个方法,`splitFunc`负责拆包,`resolveAction`负责将每一个`package`解析成`ActionName`和`Message`两个部分;
`ActionModule`处理模块负责注册方法到go-server中,供go-server调用;
> go-server 默认提供了两种常用的过滤器,分别为 `开始结束标记`和`固定头协议` 两种,也可以自定义过滤器,只需要实现`filter.ReceiveFilter`接口即可,自定义过滤器的方法参考[begin_end.go文件](https://github.com/zboyco/go-server/blob/master/filter/begin_end.go)
> `ActionModule`模块可以注册多个,只要调用`模块根路径(Root)`+`方法名`没有重复即可,如有重复,在注册的时候会返回错误提示。
> 注意实现`ActionModule`模块的方法名要以大写字母开头
下面用一个例子演示命令方式调用:
server端:
```go
func main() {
// 新建服务
mainServer := goserver.New(goserver.TCP, "", 8080)
// 开始结束标记过滤器
mainServer.SetReceiveFilter(&filter.BeginEndMarkReceiveFilter{
Begin: []byte{'!', '$'},
End: []byte{'$', '!'},
})
// 固定头部协议过滤器
//mainServer.SetReceiveFilter(&filter.FixedHeaderReceiveFilter{})
// 注册OnError事件
mainServer.SetOnError(onError)
// 添加单个Action
err := mainServer.Action("/test", func(client *goserver.AppSession, msg []byte) ([]byte, error) {
// 将bytes转为字符串
result := string(msg)
// 输出结果
log.Println("单独添加Action 接收到客户[", client.ID, "]数据:", result)
// 发送给客户端
// client.Send([]byte("Got!"))
return []byte("Got!"), nil
})
// 使用模块注册Action
err = mainServer.RegisterModule(&module{})
if err != nil {
log.Panic(err)
}
// 开启服务
mainServer.Start()
}
// 接收错误方法
func onError(err error) {
//输出结果
log.Println("错误: ", err)
}
// 定义Action模块
type module struct {
}
// 实现Root方法,返回调用根路径
func (m *module) Root() string {
return "/v1"
}
// 定义命令
// 注意方法名要以大写字母开头
// 调用路径即 /v1/say
func (m *module) Say(client *goserver.AppSession, token []byte) ([]byte, error) {
//将bytes转为字符串
result := string(token)
//输出结果
log.Println("Say方法 接收到客户[", client.ID, "]数据:", result)
// 发送给客户端
// client.Send([]byte("Got!"))
return []byte("Got!"), nil
}
```
client端:
```go
func SendByBeginEndMark(msg []byte) error {
filter := &filter.BeginEndMarkReceiveFilter{
Begin: []byte{'!', '$'},
End: []byte{'$', '!'},
}
c := client.NewBeginEndMarkClient(goserver.TCP, "", 8080, filter)
if err := c.Connect(); err != nil {
t.Fatal(err)
}
// 指定调用方法路径
return c.SendAction("/v1/say", msg)
}
```
## 自定义发送数据包过滤器
因为某些情况下,服务器收包和发包对协议的定义不一定一致,可以通过设置goserver主体的SendPacketFilter来实现服务器向客户端发送数据包时的封包协议,也可以通过方法过滤发送的数据包内容。
```go
func main() {
// 新建服务
mainServer := goserver.New(goserver.TCP, "", 8080)
// 开始结束标记过滤器
mainServer.SetReceiveFilter(&filter.BeginEndMarkReceiveFilter{
Begin: []byte{'!', '$'},
End: []byte{'$', '!'},
})
// 注册发送数据包过滤器
// 该示例设置为发送包封包与服务器拆包协议不同
mainServer.RegisterSendPacketFilter(goserver.Middlewares{
func(as *goserver.AppSession, b []byte) ([]byte, error) {
return bytes.Join([][]byte{{'#', '$'}, b, {'$', '#'}}, nil), nil
},
})
// 注册OnError事件
mainServer.SetOnError(onError)
// 使用模块注册Action
err = mainServer.RegisterModule(&module{})
if err != nil {
log.Panic(err)
}
// 开启服务
mainServer.Start()
}
```
## 中间件
goserver主体和ActionModule可以注册使用中间件,各自有before和after两个事件,都是相对于实际的action。如下:
goserver主体,直接使用方法注册
```go
mainServer.RegisterBeforeMiddlewares(goserver.Middlewares{
func(client *goserver.AppSession, token []byte) ([]byte, error) {
return []byte(string(token) + "-before1-")
没有合适的资源?快使用搜索试试~ 我知道了~
go-server 是Go 语言编写的服务器框架,开发者快速构建基于 TCP 和 UDP 协议的 socket 网络服务
共19个文件
go:14个
sum:1个
mod:1个
需积分: 5 0 下载量 119 浏览量
2024-05-23
17:09:58
上传
评论
收藏 24KB ZIP 举报
温馨提示
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
资源推荐
资源详情
资源评论
收起资源包目录
go-server 是一个用 Go 语言编写的简单而灵活的服务器框架,旨在帮助开发者快速构建基于 TCP 和 UDP 协议的 socket 网络服务。.zip (19个子文件)
content
session.go 2KB
server_test.go 6KB
go.mod 118B
go.sum 324B
LICENSE 1KB
client
simple.go 4KB
begin_end.go 1KB
sessionSource.go 2KB
server_udp.go 5KB
errors.go 235B
filter
interface.go 510B
begin_end.go 1KB
fixed_header.go 1KB
router.go 3KB
server.go 7KB
.gitignore 13B
server_tcp.go 4KB
example
main.go 5KB
README.md 17KB
共 19 条
- 1
资源评论
生瓜蛋子
- 粉丝: 3830
- 资源: 6140
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功