§ Session机制

本章节对fox-server 内session创建、还原、多节点session共享机制进行叙述

§ 创建

登录新建session,保存session信息到数据库

// 从当前线程获取session,true 表示没有则新建
Session session = SessionManager.getInstance().getSessionFromCurrentThread(true);
// 再次登录时,客户端有可能会携带seId字段,这样取到的session可能会是旧session,需要清空原有数据
session.clearData();
session.clearSystemData();
//设置session为登录状态
session.login(true);
//更新session最后操作时间
session.setLastOpsTime(System.currentTimeMillis());
1
2
3
4
5
6
7
8
9

§ 校验权限

在权限校验过滤器中对服务调用请求进行登录校验,如未登录则拒绝服务

§ 转存会话ID

在消息过滤器中,将会话id置入JsonRequest对象
在before方法中,根据不同消息来源,分别设置session id

TIP

HTTP请求

if (inBean instanceof HttpMessage){
    HttpMessage httpMessage = (HttpMessage) inBean;
	......		
			Object content = httpMessage.getContent();
			// 如果入参为字符串转换为JSON对象
			if (this.isJsonString(content)) {
				String str = (String) content;
				try {
					// 解析JSON
					Object obj = JSON.parse(str);
					if (obj instanceof JSONObject) {
						//取得httpMessage头中的sessionId字段
						String sessionId = httpMessage.getHeader("sessionId");
						JSONObject jsonObj = (JSONObject) obj;
						// 获取请求头
						JSONObject header = jsonObj.getJSONObject("header");
						//将会话id设置头部中
						header.put("seId", sessionId!=null?sessionId:"");
						// 定义请求数据
						JsonRequest request = new JsonRequest();
						// 设置头
						if (header != null) {
							request.setHeaders(header);
						}
	......

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

TIP

SOCKET请求

if (inBean instanceof Message) {
		Message message = (Message) inBean;
		Object content = message.getContent();
		if (this.isJsonString(content)) {
			String str = (String) content;
			try {
				// 解析JSON
				Object obj = JSON.parse(str);
				if (obj instanceof JSONObject) {
					JSONObject jsonObj = (JSONObject) obj;
					// 获取请求头
					JSONObject header = jsonObj.getJSONObject("header");
					JsonRequest request = new JsonRequest();
					// 将session id和socket来源地址设置到请求对象头部
					if (header != null) {
						String sessionId = message.getHeader("seId");
						if (sessionId != null) {
							header.put("seId", sessionId);
						}
                        //获取socket来源地址
						String source = message.getHeader("src");
						if (source != null) {						header.put("src", source);
						}
						request.setHeaders(header);
    ......
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

§ 会话校验

在权限过滤器中对session进行还原与校验

public void before(Event e) {
    // 获取session
	Session session =  SessionManager.getInstance().getSessionFromCurrentThread(false);
    // 判断session是否存在
	if (session == null) {
        //从JsonRequest对象头部取得sessionId
        String sessionId = (String) request.getHeader("seId");
        ......
        //从脚本根据sessionId 还原session
        //如何设置脚本在下一小节进行介绍
        session = SessionManager.getInstance().getSesssionFromScript(sessionId);
        //对session状态进行判断 
        ......
        //更新数据表
        ......
    }else{
        //更新数据表
        ......
    }

    // 判断登录状态
    Boolean loginStatus = session.isLogin();
    if (!Boolean.TRUE.equals(loginStatus)) {	
		// 抛出异常
		throw new Exception("unlogin");
	}
}
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

§ 服务加入权限校验

在对应服务接口的配置文件中,加入消息过滤器与权限过滤器,如filter-im-base.xml,filter-auth.xml

<!--继承的名字是文件名,继承的文件必须为abstracttrue的文件 -->
    <package name="im" namespace="account"
        extends="filter-im-base.xml,filter-auth.xml">
1
2
3

§ 设置session创建脚本

应用启动时,应向session管理器中设置session创建脚本,该脚本从根据数据库中数据进行脚本还原,用于服务器多节点集群环境、或者长会话机制

在服务的init方法中设置session创建脚本,并将该服务设置为单例,onload=‘true’,建议该服务中不要添加过多接口,只加与登录相关接口

	public void init() throws Exception {
		SessionManager.getInstance().setCreateScript(new ICreateScript() {
            //根据session id 创建session
			public Session create(String id) {
				try {
					.....
                    //查询数据库会话表操作
                    //如存在继续创建session逻辑
                    //如不存在返回null
                    .....

					// 还原session
					Session session = SessionManager.getInstance().getSession(id,true);
					// 设置登录
					session.login(true);
                    //设置最后更新时间
                    session.setLastOpsTime(System.currentTimeMillis());
					//设置session元数据
					...
					return session;

				} catch (Exception e) {
					LoggerUtil.error(e.getMessage(), e);
					return null;
				}
			}
		});
	}
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
B I P!
最后更新于: 4/15/2022, 2:41:22 PM