心怀不惧,才能翱翔于天际 --赵云

不管java游戏服采用何种通信协议,几乎都要有处理http请求的需求。因为现在很多游戏服都会接入第三方平台的登录、查询、验证、执行命令等操作(如游戏Web后台需查询玩家数据,修改玩家数据,封号禁言发奖等),而这第三方的请求就几乎都为http请求,因而java游戏服需要有相应的http请求处理方案。

所幸游戏服的http请求往往都是轻量级的,毕竟第三方平台的操作既不频繁也不多。因此我们在选择web连接方案时,最好是能够直接 “嵌入” java游戏服的,而不需要再建立一个web工程。

早期的时候(在JDK1.6时),都是用JDK自带的HttpServer实现的,当然现在也还可以用它,也简单好用。它的使用流程是:

第1步,创建一个HttpServer,并绑定端口和设置最大连接数;

第2步,设置HttpContext服务器监听器上下文,设置匹配URL的公共路径(如/querry)和用来处理请求的HttpHandler;

第3步,调用start方法启动即可。关闭时调用相应stop(int delaySec)。

HttpServerProvider provider = HttpServerProvider.provider();

HttpServer httpserver = null;

try{

httpserver = provider.createHttpServer(new InetSocketAddress(6688), 10);// 设置端口及最大连接数

httpserver.createContext("/querry", new HttpQuerryHandler());

httpserver.setExecutor(Executors.newCachedThreadPool()); // 设置线程池

httpserver.start();

}

catch (Exception e){

log.error("can't start http service of querry ");

}

注意,上述的HttpQuerryHandler需实现HttpHandler接口,继而实现其中的handle(HttpExchange var1)方法,如:

public class HttpQuerryHandler implements HttpHandler{

@Override

public void handle(HttpExchange httpExchange) throws IOException {

String requestMethod = httpExchange.getRequestMethod();

if (requestMethod.equalsIgnoreCase("GET")){

URI requestedUri = httpExchange.getRequestURI();

String param = requestedUri.getQuery(); //如192.168.1.5:6688/querry?user=xiaosheng996&psw=123

System.out.println("param:" + param); //user=xiaosheng996&psw=123

Headers responseHeaders = httpExchange.getResponseHeaders();

responseHeaders.set("Content-Type", "text/plain");

httpExchange.sendResponseHeaders(200, 0);

OutputStream responseBody = httpExchange.getResponseBody();

String result = "{\"ret\": \"ok\"}";

responseBody.write(result.getBytes());

responseBody.flush();

responseBody.close();

}

}

}

这样也实现了处理Http请求。在大多数Http请求不多并发又不大的情况这种已完全足够了。

Jetty是现在用得比较多的一种轻量级Servlet容器,扩展性强而非常灵活,通过引入jetty库,便能“嵌入”在java工程中,非常方便。

Jetty和Tomcat都是使用广泛的Servlet引擎,相对而言Tomcat是重量级的,它在处理少数非常繁忙的连接上更有优势,也就是说连接生命周期如果短,Tomcat的总体性能更高。而Jetty在处理高并发且长时间连接请求的场景下显得更快速高效。

Jetty的使用流程和JDK的HttpServer差不多:

第1步,创建一个Jetty Server,并设置连接器;

第2步,设置web应用上下文WebAppContext,它既可以用传统的服务配置文件的方式设定,也可以用注解的方式设定;

第3步,调用start方法启动即可。关闭时调用相应stop()方法。

在Jetty里Context是包含了在某一特定URL或Virtual Host下的一组Handler的Handler。可以这样理解,Context本身也是一种Handler,它里面包含了许多的Handler,这些Handler都只能处理某个特定URL下的请求。Jetty里的Context有ContextHandler,ServletContext和WebAppContext。

配置文件方式如下:

/**

* 构造jetty web服务

* @param descriptor 配置文件路径

* @param resourceBase 根目录,如果需要隐藏用A,否则用.

* @param maxThreads 连接线程数

* @param ports 监听的端口

* @throws Exception

*/

public JettyServer(String descriptor, String resourceBase, int maxThreads, int port) throws Exception {

this.port = port;

this.server = new Server(new QueuedThreadPool(maxThreads));

ServerConnector connector = new ServerConnector(server);

connector.setPort(port);

this.server.setConnectors(new ServerConnector[] { connector });

WebAppContext context = new WebAppContext();

context.setDescriptor(descriptor);

context.setResourceBase(resourceBase);

context.setClassLoader(Thread.currentThread().getContextClassLoader());

context.setConfigurationDiscovered(true);

context.setParentLoaderPriority(true);

this.server.setHandler(context);

this.server.start();

System.out.println("started JettyServer:" + this.toString()+",config path:"+context.getResourceBase());

}

配置文件:

xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

id="WebApp" version="2.5">

QuerryService

servlet.QuerryService

QuerryService

/QuerryService

处理请求的servlet类,需实现HttpServlet:

public class QuerryService extends PubDefaultServlet {

private static final long serialVersionUID = 3832841412181110307L;

@Override

protected void process(HttpServletRequest req, HttpServletResponse resp)

throws Exception {

System.out.println("enter");

}

}

PubDefaultServlet.java

/**

* servlet父类,覆盖get,post方法

*/

public abstract class PubDefaultServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

protected Logger logger = Logger.getLogger(getClass());

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

req.setCharacterEncoding("UTF-8");

resp.setCharacterEncoding("UTF-8");

resp.setContentType("text/html; charset=UTF-8");

resp.setHeader("Content-Type", "text/html; charset=UTF-8");

logger.info("service :" + req.getRequestURI() + "|" + req.getRemoteAddr() + "|" + req.getMethod() + "|"

+ req.getHeaderNames() + "|" + req.getParameterMap());

super.service(req, resp);

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

try {

process(req, resp);

} catch (Exception e) {

resp.getWriter().write(e.getMessage());

logger.error("process :" + req.getRequestURI() + "|" + req.getRemoteAddr() + "|" + req.getMethod() + "|"

+ req.getParameterMap(), e);

}

}

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doPost(req, resp);

}

protected abstract void process(HttpServletRequest req, HttpServletResponse resp) throws Exception;

}

如果不走配置,也可以用如下注解的方式

/**

* 构造jetty web服务

*

* @param serveltList servelt列表

* @param maxThreads 线程池数量

* @param ports 监听的端口

* @throws Exception

*/

public JettyServer(Set> servletClazzs, int maxThreads, int port) throws Exception {

this.port = port;

this.server = new Server(new QueuedThreadPool(maxThreads));

ServerConnector connector = new ServerConnector(server);

connector.setPort(port);

this.server.setConnectors(new ServerConnector[] { connector });

WebAppContext context = new WebAppContext();

context.setConfigurationDiscovered(false);

context.setBaseResource(Resource.newClassPathResource(""));

for (Class> clazz : servletClazzs) {

WebServletAnnotation webServlet = new WebServletAnnotation(context, clazz.getName(), null);

webServlet.apply();

}

context.setClassLoader(Thread.currentThread().getContextClassLoader());

this.server.setHandler(context);

this.server.start();

WEB_SERVERS.add(this);

}

而它的处理请求的servlet实现为:

@HttpServlet

@WebServlet(urlPatterns = "HttpRequest", description = "http请求")

public class HttpRequestServlet extends PubDefaultServlet {

private static final long serialVersionUID = 1L;

@Override

protected void process(HttpServletRequest req, HttpServletResponse resp) throws Exception {

String[] username = req.getParameterValues("username");

String[] password = req.getParameterValues("password");

String[] content = req.getParameterValues("content");

System.out.println("username:"+username[0]+"\npassword:"

+password[0]+"\ncontent:"+content[0]+"\nthreadName:"+Thread.currentThread().getName());

resp.getWriter().write("收到微信小程序的信息:["+username[0]+"|"+password[0]+"|"+content[0]+"]");

//resp.getWriter().write("{\"result\":0,\"data\":\"成功\"}");

resp.getWriter().flush();

}

}

将所有的servlet放在一个包下,然后扫描这个包,获得所有的servlet,作为参数Set> servletClazzs传入JettyServer构造函数,即可实现java游戏服内置jetty,但这种方式在后台需要一个注解处理器才能起作用,所以还得针对上面的注解编写处理器WebServletAnnotation。

处理器的实现参照以下文章:

Servlet传统配置方式和Servlet3.0使用注解的方式

另外,欲了解Jetty的框架原理及源码可参考,个人觉得它和Netty框架类似:

Jetty 源码分析

java jetty的classpath_java游戏服引入jetty相关推荐

  1. java jetty的classpath_java代码启动jetty

    记录下 org.eclipse.jetty jetty-server ${jetty.version} test org.eclipse.jetty jetty-webapp ${jetty.vers ...

  2. Jetty在win10上的配置,IDEA中配置Jetty,Maven中配置Jetty插件,Eclipse中配置Jetty插件及其使用,通过java代码内嵌Jetty Server

    1.下载Jetty 下载地址:http://www.eclipse.org/jetty/download.html 2.在windows上运行jetty 一.将下载的jetty解压到D:\instal ...

  3. jetty java 禁用目录列表_java – 如何禁用Jetty的WebAppContext目录列表?

    我将Jetty(版本7.4.5.v20110725)嵌入到java应用程序中.我使用Jetty的WebAppContext在./webapps/jsp/中提供JSP页面,但是如果我访问localhos ...

  4. jetty服务器上运行html页面,web项目嵌入Jetty运行的两种方式(Jetty插件和自制Jetty服务器)...

    自制Jetty服务类 这种方式可以支持websocket,如果项目中需要使用到可以试试这种. 首先pom.xml引入jetty的依赖: org.eclipse.jetty.aggregate jett ...

  5. Jetty:配置概览-怎么配置Jetty

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/liuy_98_1001/article/details/27544671 Jetty POJO配置 ...

  6. linux jetty 安装目录结构,Linux下Jetty 9安装部署

    Jetty简介 Jetty是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境.Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布. ...

  7. 基于Java的飞机大战游戏的设计与实现论文

    源码下载 http://www.byamd.xyz/hui-zong-1/ 摘 要 现如今,随着智能手机的兴起与普及,加上4G(the 4th Generation mobile communicat ...

  8. 基于Java的飞机大战游戏的设计与实现(含源文件)

    欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye 基于Java的飞机大战游戏的设计与实现 摘   要 现如今,随着智能手机的兴起与普及,加上4G( ...

  9. 基于Java的开源3D游戏引擎jMonkeyEngine

    jMonkeyEngine简介 jMonkeyEngine是一款纯Java语言编写的游戏引擎,继承了Java应用跨平台的特性,而且是开放源代码的,遵循BSD开源协议,BSD开源协议用一句简单的话概括就 ...

最新文章

  1. Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现
  2. SSH安装后提示sshd_server account 用户
  3. css中vertical-align生效
  4. MySQL时间戳(毫秒/秒)与日期格式的相互转换
  5. Android学习笔记:TabHost 和 FragmentTabHost
  6. php映射,PHP实现路由映射到指定控制器
  7. linux一键打包工具,常见压缩与打包工具
  8. Pass4side CompTIA PDI+ Beta Exam PD1-001 DEMO 免费下载
  9. android 圆形边框填充颜色,如何在android中表示多种颜色的圆形边框
  10. zabbix (二)安装
  11. Android 手动解析JSON数据
  12. 【Axure组件库】Axure移动端小程序组件库 移动端高交互元件库
  13. Python3爬虫中Selenium的用法详解
  14. 51单片机电子琴设计
  15. 台式计算机风扇一直响,为什么电脑风扇一直响
  16. php 交换机 密码,S5100系列交换机使用正确的用户名和密码进行SSH登录时提示错误的解决方法...
  17. 【一句日历】2019年8月
  18. DAEMON 中的 SPTD 和 发生sptd.sys 错误的处理办法~
  19. 视频点播开发者实战:视频水印时间线,防模糊处理
  20. mouseover、mouseenter

热门文章

  1. Latex简历制作(不借助模板)
  2. 支付宝小程序码管理生成
  3. 如何离线安装postman
  4. 2018高中计算机教学计划,上海市高中2018学年度课程计划说明
  5. 中国公路桥梁管理系统android,中国公路学报
  6. U盘中的文件无故丢失怎么办
  7. 免费使用Camtasia S-tudio录屏剪辑制作视频微课
  8. 100条最有意思的名言
  9. <delete></delete>
  10. 三自由度无人机飞手培训、PID调试、飞行教学、飞控算法验证、故障仿真平台