cometd_client/client/
handshake.rs

1use crate::{
2    types::{Advice, CometdError, CometdResult, ErrorKind, Message, Reconnect},
3    ArcSwapOptionExt as _, CometdClientInner,
4};
5use serde_json::json;
6
7impl CometdClientInner {
8    pub(crate) async fn handshake(&self) -> CometdResult<()> {
9        const KIND: ErrorKind = ErrorKind::Handshake;
10
11        let body = json!([{
12          "id": self.next_id(),
13          "version": "1.0",
14          "minimumVersion": "1.0",
15          "channel": "/meta/handshake",
16          "supportedConnectionTypes": [ "long-polling" ],
17          "advice": {
18            "timeout": self.timeout.as_millis(),
19            "interval": self.interval.as_millis(),
20          }
21        }])
22        .to_string();
23
24        let request_builder = self.create_request_builder(&self.handshake_endpoint);
25
26        let Message {
27            client_id,
28            supported_connection_types,
29            successful,
30            error,
31            advice,
32            ..
33        } = self
34            .send_request_and_parse_json_body::<[Message; 1]>(request_builder, body, KIND)
35            .await
36            .map(|[message]| message)?;
37
38        if successful == Some(false) {
39            Err(CometdError::wrong_response(
40                KIND,
41                Advice::reconnect(advice),
42                error.unwrap_or_default(),
43            ))
44        } else if !supported_connection_types
45            .iter()
46            .flatten()
47            .any(|connection_type| connection_type == "long-polling")
48        {
49            let msg = format!(
50                "Server doesn't support long-polling mode: `{supported_connection_types:?}`."
51            );
52
53            Err(CometdError::wrong_response(KIND, Reconnect::None, msg))
54        } else if let Some(client_id) = client_id {
55            self.client_id.store_value(client_id);
56
57            Ok(())
58        } else {
59            Err(CometdError::wrong_response(
60                KIND,
61                Reconnect::None,
62                "Missing client_id",
63            ))
64        }
65    }
66}