日期:2014-05-17 浏览次数:20852 次
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 connection : connections) { try { CharBuffer buffer = CharBuffer.wrap(message); connection.getWsOutbound().writeTextMessage(buffer); } catch (IOException ignore) { } } } } }