tomcat8+java7 的WebSocket聊天Demo

基于tomcat8的WebSocket聊天Demo

參考:

http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java?view=markup

需要 websocket-api

<dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
    </dependency>

ChatAnnotation.java

package jmind.ws.tomcat.java7;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import jmind.core.util.HTMLUtil;

/**
 * tomcat8 & java7
 * @author wbxie
 * 2013-11-9
 */
@ServerEndpoint(value = "/ws/chat")
public class ChatAnnotation {

    private static final String GUEST_PREFIX = "Guest";
    private static final AtomicInteger connectionIds = new AtomicInteger(0);
    private static final Set<ChatAnnotation> connections = new CopyOnWriteArraySet<ChatAnnotation>();

    private final String nickname;
    private Session session;

    public ChatAnnotation() {
        nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
    }

    @OnOpen
    public void start(Session session) {
        this.session = session;
        connections.add(this);
        String message = String.format("* %s %s", nickname, "has joined.");
        broadcast(message);
    }

    @OnClose
    public void end() {
        connections.remove(this);
        String message = String.format("* %s %s", nickname, "has disconnected.");
        broadcast(message);
    }

    @OnMessage
    public void incoming(String message) {
        // Never trust the client
        String filteredMessage = String.format("%s: %s", nickname, HTMLUtil.cleanAll(message.toString()));
        broadcast(filteredMessage);
    }

    private static void broadcast(String msg) {
        for (ChatAnnotation client : connections) {
            try {
                client.session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                connections.remove(client);
                try {
                    client.session.close();
                } catch (IOException e1) {
                    // Ignore
                }
                String message = String.format("* %s %s", client.nickname, "has been disconnected.");
                broadcast(message);
            }
        }
    }
}

    配置tomcat xml

catalina.sh

JAVA_OPTS="-server -Xmx4000M -Xms4000M -Xmn1200M -XX:PermSize=256m -XX:MaxPermSize=256m -Xss512K -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0"
JAVA_OPTS="$JAVA_OPTS -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider"

server.xml 配置

配置线程池
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="500" minSpareThreads="10"/>

配置nio

<Connector URIEncoding="UTF-8" executor="tomcatThreadPool"
  asyncTimeout="900000" maxConnections="40000"
  port="9079" protocol="org.apache.coyote.http11.Http11NioProtocol"  
  connectionTimeout="40000" acceptCount="200" maxThreads="20000"
    redirectPort="8443" />

    注 ,tomcat8 nio 最大连接数配置 使用 maxConnections 默认10000

  参考:

http://tomcat.apache.org/tomcat-8.0-doc/config/http.html

  編輯 tomcat/conf/Catalina/localhost/ROOT.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context path="" docBase="/Users/wbxie/work/workspace/chineseall/jmind-websocket/target/jmind-websocket-2.0.2-SNAPSHOT"  reloadable="false" antiJARLocking="true" antiResourceLocking="false"></Context>

epoll 在linux 下启动:

JDK 6.0 以及JDK 5.0 update 9 的 nio支持epoll (仅限 Linux 系统 ),对并发idle connection会有大幅度的性能提升,这就是很多网络服务器应用程序需要的。

启用的方法如下:

-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider

例如在 Linux 下运行的 Tomcat 使用 NIO Connector ,那么启用 epoll 对性能的提升会有帮助。

而 Tomcat 要启用这个选项的做法是在 catalina.sh 的开头加入下面这一行

CATALINA_OPTS='-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider'

  或者

JAVA_OPTS="$JAVA_OPTS -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider"

相关推荐