日期:2014-05-16 浏览次数:20772 次
package websocket;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;
import util.HTMLFilter;
public class ChatWebSocketServlet extends WebSocketServlet {
private static final long serialVersionUID = 1L;
private static final String GUEST_PREFIX = "Guest";
/**
* int操作的一个类,用来具有原子性的增加减少。
*/
private final AtomicInteger connectionIds = new AtomicInteger(0);
/**
* 适合小数量。不可变。线程安全,迭代器遍历速度快的集合 用来存放信息绑定辅助类
*/
private final Set<ChatMessageInbound> connections = new CopyOnWriteArraySet<ChatMessageInbound>();
@Override
protected StreamInbound createWebSocketInbound(String subProtocol) {
return new ChatMessageInbound(connectionIds.incrementAndGet());
}
/**
* 信息绑定辅助类 文件标题
*
* 作者: WangZhenChong
*/
private final class ChatMessageInbound extends MessageInbound {
/**
* 用户名称
*/
private final String nickname;
/**
* 构造方法
*
* @param id
*/
private ChatMessageInbound(int id) {
this.nickname = GUEST_PREFIX + id;
}
/**
* 建立连接的时候
*/
@Override
protected void onOpen(WsOutbound outbound) {
connections.add(this);
String message = String.format("* %s %s", nickname, "has joined.");
broadcast(message);
}
/**
* 管理连接的时候
*/
@Override
protected void onClose(int status) {
connections.remove(this);
String message = String.format("* %s %s", nickname, "has disconnected.");
broadcast(message);
}
/**
* 获得二进制文件信息的时候
*/
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
throw new UnsupportedOperationException("Binary message not supported.");
}
/**
* 获得文本信息的时候
*/
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
String filteredMessage = String.format("%s: %s", nickname, HTMLFilter.filter(message.toString()));
broadcast(filteredMessage);
}
/**
* 向每个在线用户发送信息的方法
*
* @param message
*/
private void broadcast(String message) {
for (ChatMessageInbound