Code Monkey home page Code Monkey logo

nettyserver's Introduction

##A server baseed on netty add sping IOC without XML

netty同时处理HTTP和Websocket,并将HTTP请求路由到相应Action中;使用ehcache实现Session;spring IOC做管理容器,mybatis 做sql数据库ORM;spring data mongoDB做mongo的ORM;HikariCP做sql数据库连接池;Gson用于json解析和生成;logback日志处理。

####netty处理HTTP和websocket

  • smart.core.netty.HttpHandler:是一个自定义的ChannelHandler用于处理HTTP 和Websocket请求
  • Handler分别处理HTTP和Websocket
public void messageReceived(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof FullHttpRequest) {//如果是HTTP请求,进行HTTP操作
            handleHttpRequest(ctx, (FullHttpRequest) msg);
        } else if (msg instanceof WebSocketFrame) {//如果是Websocket请求,则进行websocket操作
            handleWebSocketFrame(ctx, (WebSocketFrame) msg);
        }
    }
  • 由于websocket也是基于HTTP的,需要判断是websocket后,将HTTP升级为Websocket
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
        logger.warn("uri:" + req.uri());
        if (req.uri().startsWith("/ws/join")) {//如果urL开头为/ws/join则升级为websocket
            mac = wsBeforeHandler(ctx, req);
            if (mac == null || mac.length() < 1) {
                RespTools.paraErrorBack(ctx,req,null);
                return;
            }
            WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                    getWebSocketLocation(req), null, true);
            handshaker = wsFactory.newHandshaker(req);
            if (handshaker == null) {
                WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
            } else {
                handshaker.handshake(ctx.channel(), req);
            }
        } else {//是HTTP请求则路由到Action
            RouteResult<Action> routeResult = rs.getRouter().route(req.method(), req.uri());
            Action action = routeResult.target();
            action.act(ctx, req);
        }
    }
  • websocket请求处理,这里是从websocket请求中获取客户端传来的json字符串,并将字符串转为javabean
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {

        // Check for closing frame
        if (frame instanceof CloseWebSocketFrame) {
            handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
            return;
        }
        if (frame instanceof PingWebSocketFrame) {
            ctx.write(new PongWebSocketFrame(frame.content().retain()));
            return;
        }
        if (frame instanceof TextWebSocketFrame) {
            devicePool.join(ctx.channel(), mac);
            String json = ((TextWebSocketFrame) frame).text();
            Logic.ReqRespType data= JsonTools.read(json,Logic.ReqRespType.class);
           //...
            return;
        }
    }
  • 如果是HTTP则需在RouterSetting中配置路由. 比如r.POST("api/get_verify_code", getVerifyCodeAct): 将url为"api/get_verify_code"的POST请求路由到LoginAct中
public class RouterSetting {
    @Autowired
    private Router<Action> router;
    @Autowired
    private GetVerifyCodeAct getVerifyCodeAct;//w
    @Autowired
    private LoginAct loginAct;
    @Autowired
    private RegisterAct registerAcc;

    public Router<Action> getRouter() {
        routerConfig(this.router);
        return this.router;
    }

    private void routerConfig(Router<Action> r) {
        r.POST("api/get_verify_code", getVerifyCodeAct);
        r.ANY("api/login", loginAct);
        r.GET("api/register", registerAcc);
    }
}
  • Action处理HTTP请求并返回
@Controller
public class LoginAct implements Action {
    private static final Logger logger = LoggerFactory.getLogger(LoginAct.class);
    @Override
    public void act(ChannelHandlerContext ctx, FullHttpRequest req) {
        String ip = HttpTools.getIp(req);
        String body = Convert.buf2Str(req.content());
        Get.Login get = JsonTools.read(body, Get.Login.class);//1.得到HTTP传来的json数据解析为javabean
        Sub.Register back;//构建返回给客户端的javabean的实例
        //...
        HttpTools.sendCorrectResp(ctx, req, back);//返回给客户端HTTP Response
    }
}
  • 添加Session(依靠ehcache)
private void addSession(long userId, String ip) {
        Logic.DeviceSession session = new Logic.DeviceSession(ip, "");
        Cache.add(userId + "", session, "6mn");//设置session的缓存时间为6分钟
        //debugSession(userId);
    }
  • 从HTTP请求中获取IP地址
String ip = HttpTools.getIp(req);

####netty参数设置

port=8090
netty.boss.thread.count=2
netty.worker.thread.count=1
netty.so.keepalive=true
netty.so.backlog=100

####项目依赖

 //---------------------单元测试----------------------------
    testCompile group: 'junit', name: 'junit', version: '4.11'
    //--------------------数据库驱动----------------------------
    compile 'org.mongodb:mongodb-driver:3.2.2'
    compile 'mysql:mysql-connector-java:5.1.38'
    //-------------------数据库连接池---------------------------
    compile 'com.zaxxer:HikariCP:2.4.5'
    //----------------------ORM------------------------------
    compile group: 'org.mybatis', name: 'mybatis', version:mybatisVersion
    compile group: 'org.mybatis', name: 'mybatis-spring', version:mybatisSpringVersion
    //-----------------------缓存----------------------------
    compile group: 'net.sf.ehcache', name: 'ehcache', version:ehcacheVersion
    //----------------------工具包----------------------------
    compile 'commons-httpclient:commons-httpclient:3.1-rc1'
    compile 'org.javassist:javassist:3.20.0-GA'
    //---------------------日志处理----------------------------
    compile 'org.slf4j:slf4j-api:1.7.21'
    compile 'ch.qos.logback:logback-core:1.1.7'
    compile 'ch.qos.logback:logback-classic:1.1.7'
    //---------------------json处理---------------------------
    compile 'com.google.code.gson:gson:2.6.2'
    //---------------------netty-----------------------------
    compile group: 'io.netty', name: 'netty-all', version:nettyVersion
    //---------------------spring----------------------------
    compile group: 'org.springframework', name: 'spring-test', version:springVersion
    compile group: 'org.springframework', name: 'spring-jdbc', version:springVersion
    compile(group: 'org.springframework', name: 'spring-context', version:springVersion) {
        exclude(module: 'commons-logging')
    }

nettyserver's People

Contributors

flyleft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nettyserver's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.