文档章节

7.Utm示例-SmartFoxServer集成

dga4654dan
 dga4654dan
发布于 2016/03/28 10:17
字数 1414
阅读 105
收藏 0

Utm示例-SmartFoxServer集成

 

在各个平台上集成utm主要是通过一个过滤器将该平台收到的信息转发到utm里,由utm线程调度处理。

 

SmartFoxServer(这里测试使用的是2.9.0版本(在商用稳定运行的是2.7.0,由于该版本已经比较老所以这里没有使用))

一个Java写的跨平台socket服务端(收费),它已经实现了在很多平台上的客户端api(flash、html5、ios、android等),开发起来比较便捷,这里就不介绍关于smartFoxServer的基本内容了,只是关注如何在sfs上集成utm。(在sfs上的utm是经过一定商用环境的测试,稳定运行的)

 

相关的代码:

或 Git@OSC: http://git.oschina.net/daemon_c/UTM-demo下的 V_1_0_2_1 下的 UtmDemo_Sfs_2.9.0

 

(运行SmartFoxServer需要使用它自带的jdk,在其目录下的jre目录(主要是其jetty对jdk版本要求较高,也可以把它关掉,修改config目录下的server.xml下的webSocket))

 

 

首先创建一个名为GameServer的Extension,对应GameServerExtension类,在该类里的静态块实例化utm:

(如 Utm示例-公共部分 提及的“实例化utm”)

 

然后在GameServerExtension中添加过滤器(SfsUserRequestFilter)和处理器:

/**
* 添加sfs过滤器
*/
privatevoid addFilter() {
    //UTM过滤器(拦截用户请求改由utm负责处理,拦截用户登录断线等请求改由utm处理)
    addFilter("SynchronousControl",
        new SfsUserRequestFilter(userThreadMode.getUserThreadModeFilter()));
}


/**
* 添加sfs事件监听器
*/
privatevoid addEventHandler() {
    //用户登陆事件(实际上并没有调用,但是必须存在,否则sfs不会派发该事件(SfsUserRequestFilterl拦截不到))
    addEventHandler(SFSEventType.USER_LOGIN, OnUserLoginHandler_Old.class);
    
    //用户断线事件(实际上并没有什么处理,但是必须存在,否则sfs不会派发该事件(SfsUserRequestFilterl拦截不到))
    addEventHandler(SFSEventType.USER_LOGOUT, OnUserGoneHandler.class);

    //用户断线事件(实际上并没有什么处理,但是必须存在,否则sfs不会派发该事件(SfsUserRequestFilterl拦截不到))
    addEventHandler(SFSEventType.USER_DISCONNECT, OnUserGoneHandler.class);

    // 服务器启动完毕事件
    addEventHandler(SFSEventType.SERVER_READY, OnServerReadyHandler.class);

}

 

下面来看下sfs过滤器(SfsUserRequestFilter)的实现:

1.      直接拦截用户请求改由utm负责处理(返回FilterAction.HALT)

publicFilterAction handleClientRequest(String cmd, User user, ISFSObjectparams) 
    throws SFSException {

    //拦截用户请求改由utm负责处理
    //调用该方法的线程池是在server.xml中配置的 extensionThreadPoolSettings(Ext),老版本sfs则是在 server.xml中的extensionControllerThreadPoolSize

    Integer userId = (Integer)user.getProperty(Cmd.Login._USER_ID);
    userThreadModeFilter.handleUserRequest(requestIds.getAndIncrement(),cmd, userId, params);

    return FilterAction.HALT;
}

 

2.      拦截sfs的系统事件转发给utm处理

public FilterAction handleServerEvent(ISFSEvent event)throws SFSException {

    //拦截用户登录断线等请求改由utm处理
    //调用该方法的线程池是在server.xml中配置的 extensionThreadPoolSettings(Sys),老版本sfs则是在 server.xml中的systemControllerThreadPoolSize

    switch (event.getType()) {
        case USER_LOGIN:

            //用户登录
            ISession session = (ISession)event.getParameter(SFSEventParam.SESSION);
            int sessionId = session.getId();

            Visitor visitor = new Visitor(session, session.getAddress());
            userThreadModeFilter.handleVisitorRequest(requestIds.getAndIncrement(), 
                Cmd.Login.CMD, sessionId,visitor, event);
            
            //抛出SfsStopLoginException,阻止sfs登录流程继续走下去(如果返回FilterAction.HALT,则前端会受到 loginError的回调,所以这里用异常阻止)
            //请不要尝试在这里抛出SFSLoginException,否则前端会认为登录失败

            throw new SfsStopLoginException();


        case USER_DISCONNECT:
        case USER_LOGOUT:

            //用户断线或者注销
            User sfsUser =(User)event.getParameter(SFSEventParam.USER);

            Integer userId =(Integer)sfsUser.getProperty(Cmd.Login._USER_ID);
            com.dc.sfs.obj.User user =ControlCenter.getUser(userId);

            if( user !=null ) {

                LoggerCenter.userRquestLogger.log(sfsUser.getName(),
                LoggerCenter.getBeforeInfo()
                    .append("cmd:sfs user disconnect and execute utmdisconnect\n") );
                
                userThreadModeFilter.disconnect(requestIds.getAndIncrement(), user);


           } else {
                LoggerCenter.userRquestLogger.log(sfsUser.getName(),
                LoggerCenter.getBeforeInfo().append("cmd:sfs user disconnect only !\n") );
           }

           break;

      default:
           break;
    }

    return FilterAction.CONTINUE;
}

 

再来看下一个前后端简单的交互过程(HeartbeatHandler心跳):

由客户端发给服务端一个请求,带有一个requestCode参数,服务端接收到并返回该参数

(在sfs里实现心跳机制,可以前端每n秒发送一个心跳给后台,前端可以根据a*n秒没有收到回复后认为已经和服务端断开,而服务端sfs可以将extension配置文件中的overrideMaxUserIdleTime为a*n秒则在a*n秒内没收到前端的任何消息就会断掉该用户,在服务端并不需要开发者处理)

 

服务端:(HeartbeatHandler)

服务端处理器只需要实现IRequestHandler接口即可,由于该接口方法较多,所以直接继承了一个实现了部分方法的实现类,通常的cmd处理器只需要继承它并实现handlerUserRequest和queueFull即可。

publicvoid handlerUserRequest(int requestId, User user, ISFSObject param) {

    //给用户返回心跳信息
    try {

        //获得请求参数
        int requestCode = param.getInt(Cmd.Heartbeat.REQUEST_CODE);

        //给用户返回信息
        SFSObject returnObject =new SFSObject();
        returnObject.putInt(Cmd.Heartbeat._RESULT_CODE,Cmd.SuccessCode.SUCCESS);
        returnObject.putInt(Cmd.Heartbeat._REQUEST_CODE, requestCode);
        ControlCenter.sendToUser(Cmd.Heartbeat.CMD, returnObject,user);
    
    } catch (Exception e) {
        
        SFSObject returnObject =new SFSObject();
        returnObject.putInt(Cmd.Heartbeat._RESULT_CODE, Cmd.ErroCode.UNKNOW);
        ControlCenter.sendToUser(Cmd.Heartbeat.CMD, returnObject,user);

        LoggerCenter.userRquestLogger.log(user.userName, e);

    }
}

 

客户端:(UTM-Demo\V_1_0_2_1\UtmDemo_Sfs_2.9.0\UtmDemo_Sfs_2.9.0_Client项目的SfsClientTest)

发送:

public void sendHeartBeat(int requestCode) {

    ISFSObject param = new SFSObject();
    param.putInt(Cmd.Heartbeat.REQUEST_CODE, requestCode);
        
    smartFox.send(new ExtensionRequest(Cmd.Heartbeat.CMD, param));
}

 

接收:(此处仅简单的打印出收到的信息)

 

运行效果: SmartFoxServer 的启动类为:com.smartfoxserver.v2.Main

左边为服务端,可以看到有关资源数量的打印:原来为0,后面客户端连上后变为1

右边是客户端,可以看到

1.      登录成功后服务端返回的cmd:Login,其中参数A=0(resultCode=SUCCESS)

2.      客户端给后台发送心跳后后台的返回cmd:heartbeat(心跳),其中参数A=0(resultCode=SUCCESS),C=n(请求参数=n)

 

也可以在服务端的用户日志中看到该用户和后台的交互日志:

 

 

更多细节可以查看SfsUserThreadMode_V_0.9.0 和 SfsUserThreadModeTest_V_0.9.0 的源码

 

 

 

 

 

1.Utm简介

2. Utm 模块设计

3. Utm详细实现-用户生命流程

4. Utm详细实现-用户资源管理

5.Utm线程模型

6. Utm示例-公共部分

7. Utm示例-SmartFoxServer集成

8. Utm示例-Netty集成

9.(1.0.2版本更新)用户队列管理 与 用户异常处理

 

© 著作权归作者所有

dga4654dan
粉丝 2
博文 11
码字总数 16338
作品 1
高级程序员
私信 提问
UTM 用户线程模型

Utm-简介 Git@OSC: http://git.oschina.net/daemonc/UTM ( utm相关:http://git.oschina.net/daemonc/QTM) UTM-Demo Git@OSC: http://git.oschina.net/daemon_c/UTM-demo (SmartFoxServer,Ne......

dga4654dan
2016/03/28
1K
1
SmartFoxServer简介(一)

最近见很多人问道SmartFoxServer的问题,看大家很抓狂,网上的文章也很零碎。索性抛砖引玉,共同求进步吧。 先简单介绍下SmartFoxServer吧,一个非常优秀的跨平台socket服务器,内有很多游戏...

idreamblue
2013/04/10
4.6K
3
smartfoxserver2X入门指导翻译2

原文http://docs2x.smartfoxserver.com/Overview/sfs2x-platform-stack SmartFoxServer 2X platform stack smartfoxserver2X平台架构 In this document we take a bird’s eye view at the S......

gongweixin
2013/11/06
3.3K
0
SmartFoxServer管理工具使用(未完待续)

原文地址http://docs2x.smartfoxserver.com/GettingStarted/admintool大意如下:SmartFoxServer2X的管理工具可以用来监控和管理SmartFoxServer2X,主要有一下特性:1、完全视图化的设置,包括...

gongweixin
2013/11/27
688
1
JAVA NIO non-blocking模式实现高并发服务器

Java自1.4以后,加入了新IO特性,NIO. 号称new IO. NIO带来了non-blocking特性. 这篇文章主要讲的是如何使用NIO的网络新特性,来构建高性能非阻塞并发服务器. 文章基于个人理解,我也来搞搞NIO.,...

xpbug
2013/01/10
7.4K
4

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部