基于resion实现epoll的Socket服务器

原创 2007年09月30日 15:17:00

最近用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>

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

相关文章推荐

Linux Socket 事件触发模型 epoll 示例 这里会写一个用C语言的TCP服务器的完全实现的简单程序

背景介绍 通常的网络服务器实现,是对每一个连接使用一个单独的线程或进程。对高性能应用而言,由于需要同时处理非常多的客户请求,所以这种方式并不能工作得很好,因为诸如资源使用和上下文切换所需的时间影响了...

epoll+socket实现并发服务器 Linux C(版本一)

这个是第一个版本。以后本人会逐渐完善。 #include #include #include #include #include #include #include #include #includ...

epoll+socket实现 socket并发 linux服务器 (c)

本次源代码为网络上转载的,若有侵权,请联系本人,QQ:1031893464,及时删除。 本次因为学习,参考参考别人的代码,下次才发表自己写的epoll并发服务器。 /* 实现功能:通过epoll,...

linux 下 通过epoll实现tcp服务器

  • 2014年09月22日 14:33
  • 2KB
  • 下载

《socket编程由笑嘻嘻到绝望》(epoll简单高并发服务器模型)

在网络编程中相对使用select poll 机制 ,epoll具有着很大的优势,具体优势很多文章都有讲,在这里就不再赘述了。 在下面的例子中服务直接使用命令make就可以编译,运行命令demo: ....

epoll实现消息服务器

  • 2015年12月01日 09:29
  • 4KB
  • 下载

socket编程 -- epoll模型服务端/客户端通信的实现

本例实现如下功能: 支持多客户端与一个服务端进行通信,客户端给服务端发送字符串数据,服务端将字符串中小写转为大写后发送回客户端,客户端打印输出经转换后的字符串。 例如:发送abcde,打印输出AB...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于resion实现epoll的Socket服务器
举报原因:
原因补充:

(最多只允许输入30个字)