SpringBoot は websocket を統合します (3) | (websocket は websocket を呼び出し、コールバックメソッドを使用してデータの相互送信を実現します)

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 トランジット実装)

おすすめ

転載: blog.csdn.net/Oaklkm/article/details/132167776