package com.websocket; import java.util.HashSet; import java.util.Set; import javax.websocket.Endpoint; import javax.websocket.server.ServerApplicationConfig; import javax.websocket.server.ServerEndpointConfig; public class WebsocketConfig implements ServerApplicationConfig{ @Override public Set> getAnnotatedEndpointClasses(Set > scanned) { // TODO Auto-generated method stub System.out.println(******getAnnotatedEndpointClasses******); // Deploy all WebSocket endpoints defined by annotations in the examples // web application. Filter out all others to avoid issues when running // tests on Gump //這主要是掃描類的包,如果前綴為com.websocket.就抓住她,然後做什麼,你懂的 Set > res=new HashSet<>(); for(Class cs:scanned){ if(cs.getPackage().getName().startsWith(com.websocket.)){ res.add(cs); } } return res; } @Override public Set getEndpointConfigs( Set > scanned) { // TODO Auto-generated method stub System.out.println(******getEndpointConfigs******); Set res=new HashSet<>(); /* //使用Programmatic api的服務器地址 if (scanned.contains(EchoEndpoint.class)) { res.add(ServerEndpointConfig.Builder.create( EchoEndpoint.class, /websocket/echoProgrammatic).build()); } */ return res; } }
package com.websocket.chat; 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 util.HTMLFilter; @ServerEndpoint(value=/chat01) //用了這個之後,你的服務地址為ws://localhost:port/projectName/chat01 public class chat_1 { private static final AtomicInteger connectionIds = new AtomicInteger(0); private static final Setconnections = new CopyOnWriteArraySet (); private final String nickname; private Session session; public chat_1() { nickname = 游客ID: + 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 receive(String message) { // Never trust the client String filteredMessage = String.format(您有新消息:%s: %s, nickname, HTMLFilter.filter(message.toString())); broadcast(filteredMessage); } private static void broadcast(String msg) { for (chat_1 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); }//try }//for }//void broadcast(String msg) } /* * 你可能已經注意到我們從 javax.websocket包中引入了一些類。 @ServerEndpoint 注解是一個類層次的注解,它的功能主要是將目 前的類定義成一個websocket服務器端。注解的值將被用於監聽用戶連 接的終端訪問URL地址。 onOpen 和 onClose 方法分別被@OnOpen和@OnClose 所注解。 這兩個注解的作用不言自明:他們定義了當一個新用戶連接和斷開的時候所調 用的方法。 onMessage 方法被@OnMessage所注解。這個注解定義了當服務器接 收到客戶端發送的消息時所調用的方法。注意:這個方法可能包含一個 javax.websocket.Session可選參數(在我們的例子裡就是 session參數)。如果有這個參數,容器將會把當前發送消息客戶端的連接 Session注入進去。 */
<%@ page language=java import=java.util.* pageEncoding=ISO-8859-1%> <% String path = request.getContextPath(); String basePath = request.getScheme()+://+request.getServerName()+:+request.getServerPort()+path+/; %>
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the License); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package websocket.echo; import java.io.IOException; import javax.websocket.Endpoint; import javax.websocket.EndpointConfig; import javax.websocket.MessageHandler; import javax.websocket.RemoteEndpoint; import javax.websocket.Session; public class EchoEndpoint extends Endpoint { @Override public void onOpen(Session session, EndpointConfig endpointConfig) { RemoteEndpoint.Basic remoteEndpointBasic = session.getBasicRemote(); session.addMessageHandler(new EchoMessageHandler(remoteEndpointBasic)); } private static class EchoMessageHandler implements MessageHandler.Whole{ private final RemoteEndpoint.Basic remoteEndpointBasic; private EchoMessageHandler(RemoteEndpoint.Basic remoteEndpointBasic) { this.remoteEndpointBasic = remoteEndpointBasic; } @Override public void onMessage(String message) { try { if (remoteEndpointBasic != null) { remoteEndpointBasic.sendText(message); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }