it is not annotated with @ClientEndpoint“
这个错误的原因是:尝试将一个非@ClientEndpoint
注解的类用作WebSocket客户端,但WebSocket规范要求客户端类必须用@ClientEndpoint
标记。
具体来说,错误信息中的DocChatWebSocketController$1
是一个内部类($1
表示匿名内部类),它没有被@ClientEndpoint
注解修饰,因此无法被识别为合法的WebSocket客户端。
解决方案:定义标准的WebSocket客户端类
需要创建一个单独的类,用@ClientEndpoint
注解标记,并实现WebSocket回调方法:
使用客户端类建立连接
在你的控制器或服务中,通过WebSocketContainer
创建连接:
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import java.net.URI;public class DocChatService {private ChatdocWebSocketClient client;// 建立连接的方法public void connect() throws Exception {WebSocketContainer container = ContainerProvider.getWebSocketContainer();// 替换为实际的Chatdoc WebSocket地址URI uri = new URI("ws://chatdoc-server-domain/ws-endpoint");// 创建客户端实例并连接client = new ChatdocWebSocketClient();container.connectToServer(client, uri);}// 发送消息的方法public void send(String message) throws IOException {if (client != null) {client.sendMessage(message);}}
}
关键注意点
- 必须添加
@ClientEndpoint
注解:这是WebSocket客户端的标识,缺少则会报你遇到的错误。 - 避免使用匿名内部类:错误中的
$1
表明你可能用了匿名类作为客户端,必须定义独立的类。 - 客户端与服务端注解区分:
- 服务端用
@ServerEndpoint
- 客户端用
@ClientEndpoint
(不要混淆)
- 服务端用
按上述方式定义客户端后,即可正常建立WebSocket连接。
代码示例:
package com.yourcompany.knowledge.util;import javax.websocket.*;
import java.io.IOException;@ClientEndpoint
public class ChatdocClientEndpoint {private Session userSession;private MessageHandler.Whole<String> messageHandler;private Runnable onError;public ChatdocClientEndpoint(MessageHandler.Whole<String> messageHandler, Runnable onError) {this.messageHandler = messageHandler;this.onError = onError;}@OnOpenpublic void onOpen(Session session) {this.userSession = session;}@OnMessagepublic void onMessage(String message) {if (messageHandler != null) messageHandler.onMessage(message);}@OnErrorpublic void onError(Session session, Throwable thr) {if (onError != null) onError.run();}@OnClosepublic void onClose(Session session, CloseReason closeReason) {// 可选:处理关闭}public void sendText(String text) throws IOException {if (userSession != null && userSession.isOpen()) {userSession.getBasicRemote().sendText(text);}}public void close() throws IOException {if (userSession != null && userSession.isOpen()) {userSession.close();}}
}
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
ChatdocClientEndpoint endpoint = new ChatdocClientEndpoint(msg -> {try {clientSession.getBasicRemote().sendText(msg);} catch (IOException e) {log.error("[WS] 转发响应失败", e);sendError(clientSession, "转发响应失败: " + e.getMessage());}},() -> {log.error("[WS] chatdoc WebSocket异常");sendError(clientSession, "chatdoc WebSocket异常");}
);
Session chatdocSession = container.connectToServer(endpoint, java.net.URI.create(wsUrl));
endpoint.sendText(requestJson);