关闭

基于resion实现epoll的Socket服务器

标签: socketimportcmdnullstringvariables
1089人阅读 评论(2) 收藏 举报

最近用java开发了一个游戏服务,老板要求采用Epoll模式.现在项目已做完,把实现epoll的经验和大伙共享一下:

关于epoll的介绍这里就不多说,网上一大把.

1.从resion的官网上下载resin-3.0.22版本(里面就有一个例子,我就是用这例子改改而以)

2.创建ServerProtocol类

package com.wd.dzpk.SocketServer;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger;

import com.caucho.server.connection.Connection;
import com.caucho.server.port.Protocol;
import com.caucho.util.L10N;

/**
 *
 */
public class ServerProtocol extends Protocol {
 static protected final Logger log = Logger.getLogger(ServerProtocol.class
   .getName());

 static final L10N L = new L10N(ServerProtocol.class);

 private String _protocolName = "magic8ball";

 /**
  * Construct.
  */
 public ServerProtocol() {
 }

 /**
  * Returns the protocol name.
  */
 public String getProtocolName() {
  return _protocolName;
 }

 /**
  * Sets the protocol name.
  */
 public void setProtocolName(String name) {
  _protocolName = name;
 }

 /**
  * Create a Magic8BallRequest object for the new thread.
  */
 public MyServerRequest createRequest(Connection conn) {
  return new MyServerRequest(this, conn);
 }
 

}

关键是MyServerRequest 方法(),用于初始化

3.创建MyServerRequest 类

package com.wd.dzpk.SocketServer;

/**
 *
 * TODO 创建和管理消息类
 *
 */
import java.io.IOException;

import com.caucho.server.connection.Connection;
import com.caucho.server.port.ServerRequest;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.WriteStream;
import com.wd.dzpk.util.Constant;
import com.wd.dzpk.util.Log;

/**
 * Protocol specific information for each request. An instance of this object
 * may be reused to reduce memory allocations.
 */
public class MyServerRequest implements ServerRequest {

 // 连接
 Connection _conn;

 ServerProtocol _protocol;

 Parser _parser = new Parser();

 Magic8Ball _magic8ball = new Magic8Ball();

 /**
  * 在收连接请求,交给此方法处理所有消息
  *
  * @param ServerProtocol
  * @param Connection
  * @return void
  */
 public MyServerRequest(ServerProtocol protocol, Connection conn) {
  _protocol = protocol;
  _conn = conn;
 }

 /**
  * Initialize the connection. At this point, the current thread is the
  * connection thread.
  */
 public void init() {

 }

 /**
  * Handle a new connection. The controlling Server may call handleRequest
  * again after the connection completes, so the implementation must
  * initialize any variables for each connection.
  */
 public boolean handleRequest() throws IOException {
  Log.debugLog("收到" + _conn.getRemoteHost() + "的请求");
  ReadStream readStream = _conn.getReadStream();
  WriteStream writeStream = _conn.getWriteStream();
  try {
   _parser.init(readStream, writeStream);
   AbstractCommand cmd = null;
   do {
    cmd = _parser.nextCommand();
    // 如果是第一条消息,将连接和用户ID进行绑定保存
    if (null != cmd) {
     if (cmd.getIsFirstMsg()) {
      ConObj conObj = new ConObj();
      conObj.setConn(_conn);
      conObj.setUserId(cmd.getUserId());
      // 保存到系统常量中,供全局使用
      Constant.AllConnList.add(conObj);
      Log.debugLog("收到第一条消息,将连接对象进行保存.用户ID为:"
        + cmd.getUserId());
     } else if (cmd.getIsExitMsg()) {
      // 从连接列表删除相应的连接
      for (int i = 0; i < Constant.AllConnList.size(); i++) {
       if (cmd.getUserId()
         .equals(
           ((ConObj) Constant.AllConnList
             .get(i)).userId)) {
        Constant.AllConnList.remove(i);
        // 付值为null,会关闭与客户端的连接
        cmd = null;
        break;
       }
      }
      Log.debugLog("用户ID为:" + cmd.getUserId()
        + "客户端关闭了,删除连接成功");
     }
    }
   } while (null != cmd);
  } catch (Throwable e) {
   Log.warningLog("系统出错,原因:" + e.getMessage());
  }
  return false;

 }

 /*
  * (non-Javadoc)
  *
  * @see com.caucho.server.port.ServerRequest#isWaitForRead()
  */
 public boolean isWaitForRead() {
  // TODO Auto-generated method stub
  return false;
 }

 /*
  * (non-Javadoc)
  *
  * @see com.caucho.server.port.ServerRequest#protocolCloseEvent()
  */
 public void protocolCloseEvent() {
  // TODO Auto-generated method stub

 }
}
4.配置resin-3.0.22/conf/resin.conf,在resion启动时,会自动去调用ServerProtocol类来初始化

  打开resion.conf文件,找到<server>元素.插入以下代码

<port id='' host='*' port='13000'>
      <protocol resin:type="com.wd.dzpk.SocketServer.ServerProtocol"/>
    </port>

 如下:

<server>
    <port id='' host='*' port='13000'>
      <protocol resin:type="com.wd.dzpk.SocketServer.ServerProtocol"/>
    </port>

    <!-- adds all .jar files under the resin/lib directory -->
    <class-loader>
      <tree-loader path="${resin.home}/lib"/>
      <tree-loader path="${server.root}/lib"/>
    </class-loader>

就这么简单,如果需要源码,可以发邮件给我.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1505次
    • 积分:26
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:0篇
    • 译文:0篇
    • 评论:2条
    文章存档
    最新评论