pitaya学习实践笔记(3)-session与中间件

session

是个啥?参考官方文档:  https://pitaya.readthedocs.io/en/latest/features.html?highlight=session#sessions

本文中实际上我们主要用的函数:

1,Bind(ctx context.Context, uid string) error  绑定会话:通常用在处理登录业务的函数内:

例如客户端传来用户id,然后就将其作为session的uid,传入该函数即可。

后续客户端发来任意的消息时,session里就都会带上该id。其他业务就可以取出来,然后用用户id来进行业务处理,比如查询数据库。

2,Set(key string, value interface{})   根据键值 设置session存储的一条数据。该数据永远存在,直到客户端断开tcp连接。

Get(key string) interface{}  根据键值 返回数据

3,GetSessionFromCtx  通过上下文即可获得客户端和服务器的会话:

因为ctx(context.Context)基本上在任何业务处理函数获取到,再通过该函数就能直接获取到session,获取到session就能通过get函数获取到我们存入到里面的任意类型的数据

中间件

参考博客: go-pitaya学习笔记(8)-pipeline demo分析_我是大彩笔的博客-CSDN博客

得知一个很重要的点:pitaya框架的中间件函数是格式固定的。

中间件的使用:参考博客: go-pitaya学习笔记(8)-pipeline demo分析_我是大彩笔的博客-CSDN博客

假设这里有个业务函数:

func (r *Room) SetSessionData(ctx context.Context, data *SessionData) ([]byte, error) {

前置中间件函数格式:

HandlerTempl func(ctx context.Context, in interface{}) (c context.Context, out interface{}, err error)

红=框架传来  或=上一个前置中间件的返回值(绿色部分)

绿=传递给业务函数的入参(红)  或下一个前置中间件的入参(红)

后置中间件函数格式:

AfterHandlerTempl func(ctx context.Context, out interface{}, err error) (interface{}, error)

红=业务函数的返回值(绿)  或=上一个后置中间件的返回值(绿)

绿=传递给业务函数的入参(红)或下一个后置中间件的入参(红)

注意:

1,它传入的参数有ctx,这意味着我们能直接通过它获取到session,进而获取到我们存入的任何数据

2,响应客户端的业务函数(handler)格式也是固定的 ,参考:

https://pitaya.readthedocs.io/en/latest/API.html?highlight=component#handler-example

这意味着我们可以合理的在中间件包装数据或error变为自定义的结构体

实验

为了方便后续演示,这里将官方的源码的示例demo中的cluster项目( pitaya/examples/demo/cluster at main · topfreegames/pitaya · GitHub )

单独提取出来为一个项目,并在其基础上增加中间件与业务代码,同时改动的地方加上注释//new。

本文演示项目地址 :Aikxia alvis / pitayaServerDemo · GitLab

根据前面一篇博客  pitaya学习实践笔记(1)-跑通demo_蹦蹦八哥弹的博客-CSDN博客 。得知前端服务器=connector 后端=room

假设前端服务器connector不处理任何业务请求,所有的业务请求都交给后端服务器room

假设现在有这么个需求:

1,前置中间件检查用户任意一个请求的信息,如果用户未登录,则要拦截下来,并直接返回给客户端错误提示信息,不进行接下来的业务函数处理

2,并且要求登录本身这个请求不用验证,直接放行。

实现:

D:\Project\VSCode\pitayaServerDemo\cluster\middleware\before.go
// 未登录则要拦截下来,部分请求不用验证是否登录
func BeforeHandler_LoginCheck(ctx context.Context, in interface{}) (rsCtx context.Context, out interface{}, outErr error) {
	rsCtx = ctx
	out = in

	session := app.GetSessionFromCtx(ctx)
	route := session.Get("route")
	for _, rIn := range exceptInRoute { // 这些路径不用验证是否登录
		if rIn == route {
			return
		}
	}

	if session.UID() == "" {
		outErr = fmt.Errorf("未登录")
		return
	}
	return
}

D:\Project\VSCode\pitayaServerDemo\cluster\services\room.go
// new
func (r *Room) Login(ctx context.Context, data []byte) ([]byte, error) {
	s := r.app.GetSessionFromCtx(ctx)
	s.Bind(ctx, string(data))
	return []byte("Login success"), nil
}

要完成这个功能,那么我们首先需要知道请求的路径(route:对应到具体处理业务函数的位置;格式=服务器类型.组件名.函数名),如果是登录请求(route=room.room.login),那么直接放行让它进入到函数func (r *Room) Login(ctx context.Context, data []byte) 执行。如果是其他请求(比如 route=room.room.join)那么就检查用户是否登录了(session的uid默认为"",这里登录成功后执行Bind函数,然后uid就不为空了),否则直接返回给客户端错误提示信息,是则放行,让它可以进入到函数func (r *Room) Join(ctx context.Context)进行处理。

那么业务请求跑到中间件时,ctx是否自己带route之类的信息呢?

为了测试方便,将main.go改为启动后端,run.bat运行前端服务器,同时加入我们才写的前置中间件。

 通过pitaya-cli发条消息,结果显示ctx自带的数据只有ipversion,以及日志组件,并不带我们想要的route。

那我们怎么给每个到达后端服务器中间件的请求,在这之前加上route呢?

参考  : https://pitaya.readthedocs.io/en/latest/API.html?highlight=addroute#routing-messages

发现一个叫addRoute()的函数,同时知道了所有到达后端服务器的请求都要经过该函数,同时发现其入参正好带着

route参数,还要至关重要的ctx参数(我们可以直接通过GetSessionFromCtx 拿到session,然后将route存入session里面;或直接存入ctx里)。而请求到达中间件后,就可以通过ctx取出存入的数据。

路由方法:ctx上下文,route 路由实例,payload(载荷) 请求的参数和数据,cluster.Server 当前服务器的集群map

调换一下main.go和run.bat启动的服务器,并调试:

往addRoute()加上session存入ip,请求参数数据payload。

 后置中间件将完整请求信息和结果记录到log里:

通过pitaya_cli发送请求。最终效果

注:

sv->{"code":"PIT-000","msg":"nats: no responders available for request"}

是因为前端服务器一直开着,重启了后端服务器后立马客户端发请求,这时nat还没服务发现后端

嫌pitaya的日志打印(红色部分吗,大多是level=debug,warning)的太多的话,可以重写框架logger:

logger.SetLogger(initLogger())  //写到main函数内

func initLogger() interfaces.Logger {

    plog := logrus.New()

    plog.Formatter = new(logrus.TextFormatter)

    plog.Level = logrus.ErrorLevel//只显示err

    log := plog.WithFields(logrus.Fields{

        "source": "pitaya",

    })

    return logruswrapper.NewWithFieldLogger(log)

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值