SpringBoot は websocket を統合します (3) | (websocket は websocket を呼び出し、コールバックメソッドを使用してデータの相互送信を実現します)
第
1 章のリンク: SpringBoot 統合 WebSocket (1) | (WebSocket クライアント実装)
第 2 章リンク: SpringBoot 統合 WebSocket (2) | (WebSocket サーバー実装および WebSocket トランジット実装)
序文
ここでは主に、springboot が websocket のクライアントサーバーを実装していることと、クライアントとサーバー間のデータ交換について紹介します。以下は疑似コードですが、ビジネスロジックの削除は直接コピーして実行することはできませんが、アイデアを参考にして実装してください。
1. Websocket サーバー側の依存関係の導入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、WebSocket サービス コードの実装
1. WebSocketConfig の設定
SpringBoot が WebSocket にアクセスするときは、対応する構成を有効にする必要があります
@Configuration
@EnableWebSocket
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
2. WebSocketServer サービスの実装
springboot は外部 WebSocket インターフェイス実装を提供します
@Component
@Data
@Slf4j
@ServerEndpoint(value = "/v1/chat")
public class DocChatServer {
public final static String CHAT_ERR_MSG_FORMAT = "{\"header\":{\"code\":10001,\"message\":\"参数格式不对\",\"sId\":\"%s\",\"status\":2}}";
@Autowired
private void setOriginMessageSender() {
// 初始化注入bean 隐藏掉了
}
@OnOpen
public void OnOpen(Session session) {
log.debug("chat websocket open ");
}
@OnClose
public void OnClose() {
log.debug("chat websocket close ");
}
@OnMessage
public void OnMessage(Session session, String message) {
SearchDocParamVo param = null;
log.debug("ApiRequest = {}", message);
// 参数校验
try {
JSONObject jsonObject = JSONObject.parseObject(message);
// todo 参数校验
} catch (Exception e) {
String errMsg = String.format(CHAT_ERR_MSG_FORMAT, session.getId());
log.error("chat请求参数格式不会:{},异常:{}", errMsg, e);
send(session, errMsg);
return;
}
// todo 业务处理
List<ChatRecord.Source> sources = Lists.newArrayList();;
String prompt = "";
// 谈话接口
queryChat(session, param, prompt, sources);
}
/**
* 执行谈话
*
* @param session
* @param param
* @param prompt
* @param sources
*/
private void queryChat(Session session, SearchDocParamVo param, String prompt, List<ChatRecord.Source> sources) {
// todo 业务处理 。。。
// 消息发送
try {
boolean b = this.sendChatMessage(session, param, sources, texts);
if (!b) {
List<Text> textsTry = Lists.newArrayList();
Text build1 = Text.builder()
.role("user")
.content("请更具自己的理解回答问题:" + param.getContent())
.build();
textsTry.add(build1);
this.sendChatMessage(session, param, sources, textsTry);
}
} catch (Exception e) {
log.error("发送消息异常:{}", e.getMessage());
}
}
/**
* 收到谈话响应数据处理
*
* @param session
* @param param
* @param sources
* @param texts
* @return
*/
private boolean sendChatMessage(Session session, SearchDocParamVo param, List<ChatRecord.Source> sources, List<Text> texts) {
ChatClient4Chat planetClient4Chat = new ChatClient4Chat(websocketConfigConst);
try {
planetClient4Chat.send(param, texts, new ApiResponseObserver() {
public void onReceive(String message) {
// 收到远程websocket服务响应的数据
}
public void onError(Throwable throwable) {
log.error("收到错误:{}", throwable);
}
public void onCompleted() {
log.error("收到结束");
}
});
// 以下是业务逻辑 可忽略
for (int i = 0; i < 100; i++) {
if (planetClient4Chat.isHasCheck()) {
log.debug("has check");
return planetClient4Chat.isSuccess();
} else {
Thread.sleep(500);
}
}
} catch (Exception e) {
log.error("发送消息异常:{}", e.getMessage());
}
return true;
}
public void send(Session session, String msg) {
synchronized (session) {
if (!session.isOpen()) {
log.error("客户端连接关闭,数据不发送:{}", msg);
return;
}
try {
session.getBasicRemote().sendText(msg);
} catch (IOException ex) {
log.error("传递消息给客户端异常:{}", ex.getMessage());
}
}
}
public int getStatus(String message) {
int status = -1;
try {
//todo 业务逻辑
return choices.getStatus();
} catch (Exception e) {
log.error("数据中提取status异常:{}", e);
}
return status;
}
@OnError
public void onerror(Session session, Throwable throwable) {
log.error("chat连接异常关闭:远程主机强迫关闭了一个现有的连接:{}", throwable);
}
}
3. ChatClient4Chat接続ツールの実装
Springboot は中間接続ツールを提供しており、
3 番目の WebSocket インターフェイスに接続するための実装コードは次のとおりです。
@Slf4j
@Getter
@Setter
public class ChatClient4Chat {
private static WebsocketConfigConst websocketConfigConst;
private StringBuilder stringBuilder;
private boolean hasCheck;
private boolean success;
private Queue<String> queue;
private ChatChatServer sparkChatServer;
ChatClient4Chat(WebsocketConfigConst websocketConfigConst) {
this.websocketConfigConst = websocketConfigConst;
this.stringBuilder = new StringBuilder();
this.hasCheck = false;
this.success = true;
this.queue = new LinkedList<String>();
}
/**
* 执行聊天
*
* @param param
*/
public void send(SearchDocParamVo param, List<Text> texts, ApiResponseObserver apiResponseObserver) {
// 获取连接
ChatChatServer chatServer = (ChatChatServer ) getWebSocketClient(apiResponseObserver);
if (chatServer != null && chatServer.isOpen()) {
this.sparkChatServer = chatServer;
// 消息发送
try {
chatServer.send(SparkHand.initParam(param, texts, websocketConfigConst.type, websocketConfigConst.appid, websocketConfigConst.token));
} catch (Exception e) {
log.error("发送消息异常:{}", e.getMessage());
}
} else {
log.error("接口连接未打开");
}
}
public void close() {
// 获取连接
if (sparkChatServer != null && sparkChatServer.isOpen()) {
sparkChatServer.close();
} else {
log.error("接口连接未打开,关闭异常");
}
}
private void waitConnect() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
log.error("等待连接异常");
}
}
private WebSocketClient getWebSocketClient(ApiResponseObserver apiResponseObserver) {
WebSocketClient client = new SparkChatServer(websocketConfigConst.chaturl, apiResponseObserver);
client.connect();
waitConnect();
return client;
}
}
ApiResponseObserver は、いくつかのメソッドを指定する定義されたインターフェイスです
public interface ApiResponseObserver extends ResponseObservable<String> {
}
public interface ResponseObservable<T> {
void onReceive(T response);
void onError(Throwable throwable);
void onCompleted();
}
3. WebSocketClient はサードパーティのクライアント実装を接続します
Springboot は、サードパーティの WebSocket 接続用のクライアントを提供します。
実装コードは次のとおりです。
@Slf4j
public class SparkChatServer extends WebSocketClient {
private ApiResponseObserver apiResponseObserver;
public SparkChatServer(URI serverUri, ApiResponseObserver apiResponseObserver) {
super(serverUri);
this.apiResponseObserver = apiResponseObserver;
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
log.debug("chat 服务连接成功");
}
@Override
public void onMessage(String message) {
log.debug("收到chat数据{}", message);
apiResponseObserver.onReceive(message);
}
@Override
public void onClose(int i, String s, boolean b) {
log.debug("退出chat连接");
}
@Override
public void onError(Exception e) {
log.error("chat连接出现异常:{}", e);
}
}
要約する
この記事では、主に WebSocket クライアントとサーバーの実装を紹介し、接続ツールを介して WebSocket リクエスト パラメーターを転送して、リアルタイム同期とデータ収集をキャプチャします。実際に使用するビジネスロジックを削除し、参照できる実際のレコードを導入した疑似コードです。
第 1 章のリンク: SpringBoot 統合 WebSocket (1) | (WebSocket クライアント実装)
第 2 章リンク: SpringBoot 統合 WebSocket (2) | (WebSocket サーバー実装および WebSocket トランジット実装)