聂永的博客

记录工作/学习的点点滴滴。

socketio-netty(socket.io 服务器端JAVA实现) 近期升级手记

前言

针对JAVA开发者,socketio-netty是一个socket.io的服务器端选择,又是目前兼容最新0.9+ – 1.0的JAVA服务器端实现。

http://socket.io官网来看,最近版本升级趋于缓和,几乎是没修正一个Bug,小版本就增加一次。已经是非常稳定的版本了,可以真正使用了。

貌似国内使用socket.io少之又少,可惜了,这么优秀的全功能型实时推送实现,小众范围内被知晓。

嗯,就最近当前项目修改做一些简单记载。

 

升级手记

  1. netty升级到3.4.5
    3.4.5的QueueFactory类,增加对了JAVA SE 7引入的JUC并发类LinkedTransferQueue,若是本地使用JAVA SE 6,还想要保持高性能的阻塞队列,那就需要引入Doug Lea’s jsr166y.jar并发包(下载地址),然后修改一下QueueFactory实现。我已经重新打包成jar包(这里是netty-3.4.5.Final-modify.jar)。
    QueueFactory原始代码:
    public final class QueueFactory {
    private static final boolean useUnsafe = DetectionUtil.hasUnsafe();
    private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(QueueFactory.class);
    private QueueFactory() {
    // only use static methods!
    }
    /**
    * Create a new unbound {@link BlockingQueue}
    *
    * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items
    * @return queue the {@link BlockingQueue} implementation
    */
    public static <T> BlockingQueue<T> createQueue(Class<T> itemClass) {
    // if we run in java >=7 its the best to just use the LinkedTransferQueue which
    // comes with java bundled. See #273
    if (DetectionUtil.javaVersion() >= 7) {
    return new java.util.concurrent.LinkedTransferQueue<T>();
    }
    try {
    if (useUnsafe) {
    return new LinkedTransferQueue<T>();
    }
    } catch (Throwable t) {
    // For whatever reason an exception was thrown while loading the LinkedTransferQueue
    //
    // This mostly happens because of a custom classloader or security policy that did not allow us to access the
    // com.sun.Unmisc class. So just log it and fallback to the old LegacyLinkedTransferQueue that works in all cases
    if (LOGGER.isDebugEnabled()) {
    LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t);
    }
    }
    return new LegacyLinkedTransferQueue<T>();
    }
    /**
    * Create a new unbound {@link BlockingQueue}
    *
    * @param collection the collection which should get copied to the newly created {@link BlockingQueue}
    * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items
    * @return queue the {@link BlockingQueue} implementation
    */
    public static <T> BlockingQueue<T> createQueue(Collection<? extends T> collection, Class<T> itemClass) {
    // if we run in java >=7 its the best to just use the LinkedTransferQueue which
    // comes with java bundled. See #273
    if (DetectionUtil.javaVersion() >= 7) {
    return new java.util.concurrent.LinkedTransferQueue<T>();
    }
    try {
    if (useUnsafe) {
    return new LinkedTransferQueue<T>(collection);
    }
    } catch (Throwable t) {
    // For whatever reason an exception was thrown while loading the LinkedTransferQueue
    //
    // This mostly happens because of a custom classloader or security policy that did not allow us to access the
    // com.sun.Unmisc class. So just log it and fallback to the old LegacyLinkedTransferQueue that works in all cases
    if (LOGGER.isDebugEnabled()) {
    LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t);
    }
    }
    return new LegacyLinkedTransferQueue<T>(collection);
    }
    }

    QueueFactory修改后代码:
    public final class QueueFactory {
    private static final boolean useUnsafe = DetectionUtil.hasUnsafe();
    private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(QueueFactory.class);
    private QueueFactory() {
    // only use static methods!
    }
    /**
    * Create a new unbound {@link BlockingQueue}
    *
    * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items
    * @return queue the {@link BlockingQueue} implementation
    */
    public static <T> BlockingQueue<T> createQueue(Class<T> itemClass) {
    // if we run in java >=7 its the best to just use the LinkedTransferQueue which
    // comes with java bundled. See #273
    if (DetectionUtil.javaVersion() >= 6) {
    return new jsr166y.LinkedTransferQueue<T>();
    }
    try {
    if (useUnsafe) {
    return new LinkedTransferQueue<T>();
    }
    } catch (Throwable t) {
    // For whatever reason an exception was thrown while loading the LinkedTransferQueue
    //
    // This mostly happens because of a custom classloader or security policy that did not allow us to access the
    // com.sun.Unmisc class. So just log it and fallback to the old LegacyLinkedTransferQueue that works in all cases
    if (LOGGER.isDebugEnabled()) {
    LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t);
    }
    }
    return new LegacyLinkedTransferQueue<T>();
    }
    /**
    * Create a new unbound {@link BlockingQueue}
    *
    * @param collection the collection which should get copied to the newly created {@link BlockingQueue}
    * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items
    * @return queue the {@link BlockingQueue} implementation
    */
    public static <T> BlockingQueue<T> createQueue(Collection<? extends T> collection, Class<T> itemClass) {
    // if we run in java >=7 its the best to just use the LinkedTransferQueue which
    // comes with java bundled. See #273
    if (DetectionUtil.javaVersion() >= 6) {
    return new jsr166y.LinkedTransferQueue<T>();
    }
    try {
    if (useUnsafe) {
    return new LinkedTransferQueue<T>(collection);
    }
    } catch (Throwable t) {
    // For whatever reason an exception was thrown while loading the LinkedTransferQueue
    //
    // This mostly happens because of a custom classloader or security policy that did not allow us to access the
    // com.sun.Unmisc class. So just log it and fallback to the old LegacyLinkedTransferQueue that works in all cases
    if (LOGGER.isDebugEnabled()) {
    LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t);
    }
    }
    return new LegacyLinkedTransferQueue<T>(collection);
    }
    }

  2. socket.io client 升级到 0.9.6
  3. 支持将HTML/CSS/JS等文件
    socketio.properties 增加配置项static,指定静态资源的相对路径 ,默认是static
    若浏览器请求:http://localhost:9000/style/chat.css,则此文件相对路径为 static/style/chat.css,其它文件与此类似。
    此属性便于打包,以及不再单独依赖Web容器
    项目中,直接把网页文件拷贝到/source/static目录中,运行相应的JAVA文件(ChatServer.java)
  4. 在Google Code 增加demo
    下载聊天示范,下载后解压,双击 start.bat或者start.sh,浏览 http://localhost:9000/ 即可。

有时间,会聊聊更具体的实时Web一些心得,以及更为具体的示范等。

posted on 2012-05-21 17:31 nieyong 阅读(19539) 评论(5)  编辑  收藏 所属分类: socket.io

评论

# re: socketio-netty(socket.io 服务器端JAVA实现) 近期升级手记 2012-05-28 11:54 高压锅炉管

这个服务器不是很会用的  回复  更多评论   

# re: socketio-netty(socket.io 服务器端JAVA实现) 近期升级手记[未登录] 2012-05-28 21:04 steven

这里的socket服务端如何接收另一个socket发过来的数据 接收到的数据再推送到页面  回复  更多评论   

# re: socketio-netty(socket.io 服务器端JAVA实现) 近期升级手记[未登录] 2012-05-31 13:06 steven

socketio后端如何主动发消息到客户端 客户端的IOClient是已经存在的
或 是否可以通过另一个客户端socket发送数据到socketio服务端 但客户端socket的协议与浏览器的客户端协议是不一样的 请问这
个问题怎么解决 谢谢   回复  更多评论   

# re: socketio-netty(socket.io 服务器端JAVA实现) 近期升级手记 2012-06-06 11:24 nieyong

@steven

这个问题,已经在邮件组里面解决了,哈。
具体,请参考
邮件讨论组为
http://groups.google.com/group/socketio-netty
或者
https://groups.google.com/group/socketio-netty  回复  更多评论   

# re: socketio-netty(socket.io 服务器端JAVA实现) 近期升级手记 2013-05-20 11:49 勇泽

请问socketio-netty可支持的最大支持多少并发?  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

所有文章皆为原创,若转载请标明出处,谢谢~

新浪微博,欢迎关注:

导航

<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

统计

常用链接

留言簿(58)

随笔分类(130)

随笔档案(151)

个人收藏

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜