Java Websockets Tomcat 7在现有项目中不起作用
我尝试在Tomcat6上运行的Java项目中运行websocket服务器。我已经建立了一个Tomcat7服务器,项目现在就在这个服务器上运行。 首先,我尝试运行Tomcat7的套接字示例。这条路走得很好。我把这个类复制到我的旧项目中。当我再次运行旧项目时,所有功能都像以前一样工作,但只有websocket服务器不工作 这是我从Tomcat的示例复制到旧项目中的ChatAnnotation类Java Websockets Tomcat 7在现有项目中不起作用,java,eclipse,tomcat,websocket,java-websocket,Java,Eclipse,Tomcat,Websocket,Java Websocket,我尝试在Tomcat6上运行的Java项目中运行websocket服务器。我已经建立了一个Tomcat7服务器,项目现在就在这个服务器上运行。 首先,我尝试运行Tomcat7的套接字示例。这条路走得很好。我把这个类复制到我的旧项目中。当我再次运行旧项目时,所有功能都像以前一样工作,但只有websocket服务器不工作 这是我从Tomcat的示例复制到旧项目中的ChatAnnotation类 import java.io.IOException; import java.util.Set; imp
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.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.log4j.Logger;
@ServerEndpoint(value = "/websocket/chat")
public class ChatAnnotation {
private static Logger logger = Logger.getLogger(ChatAnnotation.class);
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();
logger.info("ws instance");
}
@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, message.toString());
broadcast(filteredMessage);
}
@OnError
public void onError(Throwable t) throws Throwable {
logger.error("Chat Error: " + t.toString(), t);
}
private static void broadcast(String msg) {
for (ChatAnnotation client : connections) {
try {
synchronized (client) {
client.session.getBasicRemote().sendText(msg);
}
} catch (IOException e) {
logger.debug("Chat Error: Failed to send message to client", 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);
}
}
}
}
import java.io.IOException;
导入java.util.Set;
导入java.util.concurrent.CopyOnWriteArraySet;
导入java.util.concurrent.AtomicInteger;
导入javax.websocket.OnClose;
导入javax.websocket.OnError;
导入javax.websocket.OnMessage;
导入javax.websocket.OnOpen;
导入javax.websocket.Session;
导入javax.websocket.server.ServerEndpoint;
导入org.apache.log4j.Logger;
@ServerEndpoint(value=“/websocket/chat”)
公共类聊天室注释{
私有静态记录器=Logger.getLogger(chatnotation.class);
私有静态最终字符串GUEST\u PREFIX=“GUEST”;
私有静态最终AtomicInteger ConnectionId=新的AtomicInteger(0);
私有静态最终集连接=新CopyOnWriteArraySet();
私有最终字符串昵称;
非公开会议;
公共聊天室注释(){
昵称=来宾前缀+连接ID.getAndIncrement();
logger.info(“ws实例”);
}
@奥诺彭
公共无效开始(会话){
this.session=会话;
连接。添加(此);
String message=String.format(“*%s%s”,昵称“已加入”);
广播(讯息);
}
@一次
公共无效结束(){
连接。移除(此);
String message=String.format(“*%s%s”,昵称,“已断开连接”);
广播(讯息);
}
@OnMessage
公共无效传入(字符串消息){
//永远不要相信客户
String filteredMessage=String.format(“%s:%s”,昵称,message.toString());
广播(过滤信息);
}
@一个错误
公共无效者(可丢弃的t)抛出可丢弃的{
logger.error(“聊天错误:+t.toString(),t”);
}
专用静态无效广播(字符串消息){
用于(ChatAnnotation客户端:连接){
试一试{
已同步(客户端){
client.session.getBasicRemote().sendText(msg);
}
}捕获(IOE异常){
logger.debug(“聊天错误:无法向客户端发送消息”,e);
连接。移除(客户端);
试一试{
client.session.close();
}捕获(IOE1异常){
//忽略
}
String message=String.format(“*%s%s”,client.昵称,“已断开连接”);
广播(讯息);
}
}
}
}
我的web.xml中没有添加任何内容。在我的旧项目中也使用了tcpsockets,这是问题吗?
有人能帮我解决这个问题吗
编辑
新增类别:
import java.util.HashSet;
import java.util.Set;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import org.apache.log4j.Logger;
public class ExamplesConfig implements ServerApplicationConfig {
private static Logger log = Logger.getLogger(ChatAnnotation.class);
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();
log.info("getEndpointConfigs");
return result;
}
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
log.info("getAnnotatedEndpointClasses");
return scanned;
}
}
import java.util.HashSet;
导入java.util.Set;
导入javax.websocket.Endpoint;
导入javax.websocket.server.ServerApplicationConfig;
导入javax.websocket.server.ServerEndpointConfig;
导入org.apache.log4j.Logger;
公共类示例Config实现ServerApplicationConfig{
私有静态记录器log=Logger.getLogger(chatnotation.class);
公共集合getEndpointConfigs(集合>扫描){
log.info(“getAnnotatedEndpointClasses”);
返回扫描;
}
}
Java websocket服务器使用ServerApplicationConfig接口的返回值来部署编程端点和注释端点。
以Tomcat为例,如果更改ChatAnnotation
的包名。您必须修改websocket。示例config
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
// Deploy all WebSocket endpoints defined by annotations in the examples
// web application. Filter out all others to avoid issues when running
// tests on Gump
Set<Class<?>> results = new HashSet<>();
for (Class<?> clazz : scanned) {
String name = clazz.getPackage().getName();
boolean ok = name.startsWith("websocket.");
if (ok) {
results.add(clazz);
}
}
return scanned;
}
public Set>results=new HashSet();
用于(类别分类:扫描){
字符串名称=clazz.getPackage().getName();
布尔ok=name.startsWith(“websocket”);
如果(确定){
结果:添加(clazz);
}
}
返回扫描;
}
getAnnotatedEndpointClasses(已扫描)
仅返回包名以websocket开头的类。不匹配的类即使具有@ServerEndpoint
声明也不会部署。Java websocket服务器使用ServerApplicationConfig接口的返回值来部署编程端点和注释端点。
以Tomcat为例,如果更改ChatAnnotation
的包名。您必须修改websocket。示例config
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
// Deploy all WebSocket endpoints defined by annotations in the examples
// web application. Filter out all others to avoid issues when running
// tests on Gump
Set<Class<?>> results = new HashSet<>();
for (Class<?> clazz : scanned) {
String name = clazz.getPackage().getName();
boolean ok = name.startsWith("websocket.");
if (ok) {
results.add(clazz);
}
}
return scanned;
}
public Set>results=new HashSet();
用于(类别分类:扫描){
字符串名称=clazz.getPackage().getName();
布尔ok=name.startsWith(“websocket”);
如果(确定){
结果:添加(clazz);
}
}
返回扫描;
}
getAnnotatedEndpointClasses(扫描)
仅返回包名以websocket开头的类。不匹配的类将不会部署,即使它们具有@ServerEndpoint
声明。是否有任何类实现?(如Tomcat示例中的websocket.ExamplesConfig
class…)是的,在示例文件夹中是否有ExampleConfig类,但我发现在某些地方没有使用它。是否有任何类实现?(如Tomcat示例中的websocket.ExamplesConfig
class…)是的,在示例文件夹中有ExampleConfig类,但我没有发现在某个地方使用了它。感谢您的回复。我已经添加了一个类ExamplesConfig(见上文),但是我需要在某个地方说socket服务器必须启动或者其他什么,因为我没有添加这个类,所以您的实现不会返回