国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

flutter開發(fā)實戰(zhàn)-長鏈接WebSocket使用stomp協(xié)議stomp_dart_client

這篇具有很好參考價值的文章主要介紹了flutter開發(fā)實戰(zhàn)-長鏈接WebSocket使用stomp協(xié)議stomp_dart_client。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

flutter開發(fā)實戰(zhàn)-長鏈接WebSocket使用stomp協(xié)議stomp_dart_client

在app中經(jīng)常會使用長連接進(jìn)行消息通信,這里記錄一下基于websocket使用stomp協(xié)議的使用。
flutter開發(fā)實戰(zhàn)-長鏈接WebSocket使用stomp協(xié)議stomp_dart_client,flutter開發(fā)實戰(zhàn),flutter,移動開發(fā),flutter,websocket,網(wǎng)絡(luò)協(xié)議,stomp

一、stomp:流文本定向消息協(xié)議

1.1 stomp介紹

stomp,Streaming Text Orientated Message Protocol,是流文本定向消息協(xié)議,是一種為MOM(Message Oriented Middleware,面向消息的中間件)設(shè)計的簡單文本協(xié)議。
它提供了一個可互操作的連接格式,允許STOMP客戶端與任意STOMP消息代理(Broker)進(jìn)行交互,類似于OpenWire(一種二進(jìn)制協(xié)議)。

1.2 協(xié)議支持

stomp 1.0
stomp 1.1 (including heart-beating)

1.3 stomp frame(幀)

stomp frame(幀)對象包括command、headers、body

command和headers屬性始終會被定義,若頭部信息時,headers參數(shù)可為{},body也可能為空

二、flutter上使用stomp

2.1 引入庫stomp_dart_client

flutter上使用stomp時,需要在pubspec.yaml引入庫如下

# stomp協(xié)議長鏈接
  stomp_dart_client: ^0.4.4
  stomp: ^0.8.0

2.2 實現(xiàn)websocketmanager封裝stomp

// 管理長鏈接socket, stomp協(xié)議

import 'package:stomp_dart_client/stomp.dart';
import 'package:stomp_dart_client/stomp_config.dart';
import 'package:stomp_dart_client/stomp_frame.dart';

// 接收到stomp協(xié)議的frame的callback
typedef OnFrameCallback = void Function(StompFrame);

enum StompState {
  IDLE,
  CREATED,
  CONNECTING,
  CONNECTED,
  RECONNECTING,
  DISCONNECTED,
  ERROR,
}

class WebSocketStompManager {
  //私有構(gòu)造函數(shù)
  WebSocketStompManager._internal();

  //保存單例
  static WebSocketStompManager _singleton = WebSocketStompManager._internal();

  //工廠構(gòu)造函數(shù)
  factory WebSocketStompManager() => _singleton;

  // 訂閱的Subscription
  // 保存訂閱, id: dynamic
  Map _subscriptions = Map<String, dynamic>();

  // stomp的headers信息
  Map<String, String>? _headers = Map<String, String>();

  // 是否連接
  StompState _stompState = StompState.IDLE;

  // 當(dāng)前連接的Url
  String _urlString = '';

  // StompClient client
  StompClient? _client;

  // 創(chuàng)建連接
  void createConnect(String urlString, Map<String, String> headers) {
    _urlString = urlString;
    _headers = _headers;

    _client?.deactivate();
    _client = null;

    _client = StompClient(
        config: StompConfig(
      url: urlString,
      // connectionTimeout: Duration(seconds: 10),
      // stompConnectHeaders: {
      //   'upgraded': 'websocket',
      // },
      // webSocketConnectHeaders: {
      //   'upgraded': 'websocket',
      // },
      // 連接
      beforeConnect: beforeConnectCallback,
      onConnect: onConnectCallback,
      onDisconnect: onDisconnectCallback,
      onStompError: onStompErrorCallback,
      onUnhandledFrame: onUnhandledFrameCallback,
      onUnhandledMessage: onUnhandledMessageCallback,
      onUnhandledReceipt: onUnhandledReceiptCallback,
      onWebSocketError: onWebSocketErrorCallback,
      onWebSocketDone: onWebSocketDoneCallback,
      onDebugMessage: onDebugMessageCallback,
    ));
  }

  /// beforeConnect:未來	在建立連接之前將等待的異步函數(shù)。
  Future<void> beforeConnectCallback() async {
    // 在建立連接之前將等待的異步函數(shù)。
    print("beforeConnectCallback 在建立連接之前將等待的異步函數(shù)。");
    print('waiting to connect...');
    // await Future.delayed(Duration(milliseconds: 200));
    print('connecting...');
  }

  /// onClientNotCreateCallback, client未創(chuàng)建
  void onClientNotCreateCallback() {
    // client未創(chuàng)建
    print("onClientNotCreateCallback client未創(chuàng)建");
  }

  /// onConnect:函數(shù)(StompFrame)	客戶端連接成功調(diào)用的函數(shù)
  void onConnectCallback(StompFrame connectFrame) {
    // client is connected and ready
    // 如果連接成功
    print(
        "onConnectCallback 客戶端連接成功調(diào)用的函數(shù):"
            "${connectFrame.toString()},"
            "${connectFrame.command},"
            "${connectFrame.headers},"
            "${connectFrame.body}"
    );
  }

  /// onDisconnect:函數(shù)(StompFrame)	客戶端預(yù)期斷開連接時調(diào)用的函數(shù)
  void onDisconnectCallback(StompFrame p1) {
    // 客戶端預(yù)期斷開連接時調(diào)用的函數(shù)
    print("onDisconnectCallback 客戶端預(yù)期斷開連接時調(diào)用的函數(shù):${p1.toString()}");
  }

  /// onStompError:函數(shù)(StompFrame)	當(dāng) stomp 服務(wù)器發(fā)送錯誤幀時要調(diào)用的函數(shù)
  void onStompErrorCallback(StompFrame p1) {
    // 當(dāng) stomp 服務(wù)器發(fā)送錯誤幀時要調(diào)用的函數(shù)
    print("onStompErrorCallback 當(dāng) stomp 服務(wù)器發(fā)送錯誤幀時要調(diào)用的函數(shù):${p1.toString()}");
  }

  /// onUnhandledFrame:函數(shù)(StompFrame)	服務(wù)器發(fā)送無法識別的幀時調(diào)用的函數(shù)
  void onUnhandledFrameCallback(StompFrame p1) {
    // 服務(wù)器發(fā)送無法識別的幀時調(diào)用的函數(shù)
    print("onUnhandledFrameCallback 服務(wù)器發(fā)送無法識別的幀時調(diào)用的函數(shù):${p1.toString()}");
  }

  /// onUnhandledMessage:函數(shù)(StompFrame)	當(dāng)訂閱消息沒有處理程序時要調(diào)用的函數(shù)
  void onUnhandledMessageCallback(StompFrame p1) {
    // 當(dāng)訂閱消息沒有處理程序時要調(diào)用的函數(shù)
    print("onUnhandledMessageCallback 當(dāng)訂閱消息沒有處理程序時要調(diào)用的函數(shù):${p1.toString()}");
  }

  /// onUnhandledReceipt:函數(shù)(StompFrame)	當(dāng)接收消息沒有注冊觀察者時調(diào)用的函數(shù)
  void onUnhandledReceiptCallback(StompFrame p1) {
    // 當(dāng)接收消息沒有注冊觀察者時調(diào)用的函數(shù)
    print("onUnhandledReceiptCallback 當(dāng)接收消息沒有注冊觀察者時調(diào)用的函數(shù):${p1.toString()}");
  }

  /// onWebSocketError:函數(shù)(動態(tài))	當(dāng)?shù)讓?WebSocket 拋出錯誤時要調(diào)用的函數(shù)
  void onWebSocketErrorCallback(dynamic error) {
    // 當(dāng)?shù)讓?WebSocket 拋出錯誤時要調(diào)用的函數(shù)
    print(
        "onWebSocketErrorCallback 當(dāng)?shù)讓?WebSocket 拋出錯誤時要調(diào)用的函數(shù):${error.toString()}");
  }

  /// onWebSocketDone:函數(shù)()	當(dāng)?shù)讓?WebSocket 完成/斷開連接時要調(diào)用的函數(shù)
  void onWebSocketDoneCallback() {
    // 當(dāng)?shù)讓?WebSocket 完成/斷開連接時要調(diào)用的函數(shù)
    print("onWebSocketDoneCallback 當(dāng)?shù)讓?WebSocket 完成/斷開連接時要調(diào)用的函數(shù)");
  }

  /// onDebugMessage:函數(shù)(字符串)	為內(nèi)部消息處理程序生成的調(diào)試消息調(diào)用的函數(shù)
  void onDebugMessageCallback(String p1) {
    // 為內(nèi)部消息處理程序生成的調(diào)試消息調(diào)用的函數(shù)
    print("onDebugMessageCallback 為內(nèi)部消息處理程序生成的調(diào)試消息調(diào)用的函數(shù):${p1}");
  }

  // 連接
  void connect() {
    // connect連接
    if (_client != null) {
      _client?.activate();
    } else {
      // 未創(chuàng)建client
      onClientNotCreateCallback();
    }
  }

  // Subscribe
  void subscribe(String destination, OnFrameCallback? onFrameCallback) {
    if (_client != null) {
      dynamic unsubscribeFn = _client?.subscribe(
          destination: destination,
          headers: _headers,
          callback: (frame) {
            // Received a frame for this subscription
            print(frame.body);
            if (onFrameCallback != null) {
              onFrameCallback(frame);
            }
          });
      _subscriptions.putIfAbsent(destination, () => unsubscribeFn);
    } else {
      // 未創(chuàng)建client
      onClientNotCreateCallback();
    }
  }

  // client.subscribe(...) returns a function which can be called with an optional map of headers
  void unsubscribe(String destination) {
    if (_client != null) {
      dynamic unsubscribeFn = _subscriptions[destination];
      unsubscribeFn(unsubscribeHeaders: {});
    } else {
      // 未創(chuàng)建client
      onClientNotCreateCallback();
    }
  }

  // client.subscribe(...) returns a function which can be called with an optional map of headers
  void unsubscribeAll() {
    // 退訂所有
    // 調(diào)用 Map 對象的 keys 成員 , 返回一個由 鍵 Key 組成的數(shù)組
    for (var destination in _subscriptions.keys){
      unsubscribe(destination);
    }
  }

  void send(String destination, String? message) {
    if (_client != null) {
      _client?.send(destination: destination, body: message, headers: _headers);
    } else {
      // 未創(chuàng)建client
      onClientNotCreateCallback();
    }
  }

  void disconnect() {
    if (_client != null) {
      _client?.deactivate();
    } else {
      // 未創(chuàng)建client
      onClientNotCreateCallback();
    }
  }
}

2.3 使用websocketmanager收發(fā)消息

創(chuàng)建頁面進(jìn)行消息收發(fā)

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }


  
  Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              // Here we take the value from the MyHomePage object that was created by
              // the App.build method, and use it to set our appbar title.
              title: Text(widget.title),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                _incrementCounter(model);
              },
              tooltip: 'Increment',
              child: Icon(Icons.add),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Wrap(
                    spacing: 8.0, // 主軸(水平)方向間距
                    runSpacing: 4.0, // 縱軸(垂直)方向間距
                    alignment: WrapAlignment.center, //沿主軸方向居中
                    children: [
                      TextButton(
                        onPressed: stompCreate,
                        child: Container(
                          color: Colors.black26,
                          child: Text(
                            'stomp創(chuàng)建',
                            style: Theme.of(context).textTheme.bodyMedium,
                          ),
                        ),
                      ),
                      TextButton(
                        onPressed: stompConnect,
                        child: Container(
                          color: Colors.black26,
                          child: Text(
                            'stomp連接',
                            style: Theme.of(context).textTheme.bodyMedium,
                          ),
                        ),
                      ),
                      TextButton(
                        onPressed: stompSubscribe,
                        child: Container(
                          color: Colors.black26,
                          child: Text(
                            'stomp訂閱',
                            style: Theme.of(context).textTheme.bodyMedium,
                          ),
                        ),
                      ),
                      TextButton(
                        onPressed: stompUnSubscribe,
                        child: Container(
                          color: Colors.black26,
                          child: Text(
                            'stomp退訂',
                            style: Theme.of(context).textTheme.bodyMedium,
                          ),
                        ),
                      ),
                      TextButton(
                        onPressed: stompSendMessage,
                        child: Container(
                          color: Colors.black26,
                          child: Text(
                            'stomp發(fā)送消息',
                            style: Theme.of(context).textTheme.bodyMedium,
                          ),
                        ),
                      )
                    ],
                  ),
                ],
              ),
            ),
          );
  }

  // 測試stomp長鏈接
  void stompCreate() {
    // 創(chuàng)建stompClint
    WebSocketStompManager().createConnect("ws://192.168.100.25:8080/test-endpoint/websocket", {});
  }

  void stompConnect() {
    WebSocketStompManager().connect();
  }

  void stompSubscribe() {
    WebSocketStompManager()
        .subscribe("/topic/echo", (p0) {
      print("stompSubscribe 1:$p0");
    });

    WebSocketStompManager()
        .subscribe("/topic/echo", (p0) {
      print("stompSubscribe 2:$p0");
    });
  }

  void stompUnSubscribe() {
    WebSocketStompManager().unsubscribeAll();
  }

  void stompSendMessage() {
    WebSocketStompManager().send("/app/echo", "haha message from dart");
  }
}

至此實現(xiàn)了flutter開發(fā)實戰(zhàn)-長鏈接WebSocket 使用stomp協(xié)議,進(jìn)行消息發(fā)送、消息接收。

2.4 注意事項

由于stomp_dart_client不支持https,如果使用WebSocketStompManager().createConnect(“ws://192.168.100.25:8080/test-endpoint/websocket”, {});
會報告錯誤“Not support Https shceme”,所以這里要使用ws或者wss。

三、小結(jié)

至此實現(xiàn)了flutter開發(fā)實戰(zhàn)-長鏈接WebSocket 使用stomp協(xié)議,進(jìn)行消息發(fā)送、消息接收。stomp實現(xiàn)的庫stomp_dart_client來實現(xiàn)該功能。

學(xué)習(xí)記錄,每天不停進(jìn)步。文章來源地址http://www.zghlxwxcb.cn/news/detail-544779.html

到了這里,關(guān)于flutter開發(fā)實戰(zhàn)-長鏈接WebSocket使用stomp協(xié)議stomp_dart_client的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 基于STOMP協(xié)議的WebSocket消息代理和相關(guān)的安全握手處理器以及消息攔截器

    這段代碼是一個Spring配置類 WsChatConfig ,基于STOMP協(xié)議的WebSocket消息代理和相關(guān)的安全握手處理器以及消息攔截器。這個類通過實現(xiàn) WebSocketMessageBrokerConfigurer 接口來定義WebSocket通信的路由、安全握手以及消息攔截的邏輯。 核心方法詳解 configureMessageBroker(MessageBrokerRegistry confi

    2024年04月26日
    瀏覽(64)
  • Spring Boot 3 + Vue 3 整合 WebSocket (STOMP協(xié)議) 實現(xiàn)廣播和點對點實時消息

    Spring Boot 3 + Vue 3 整合 WebSocket (STOMP協(xié)議) 實現(xiàn)廣播和點對點實時消息

    ?? 作者主頁: 有來技術(shù) ?? 開源項目: youlai-mall ?? vue3-element-admin ?? youlai-boot ?? 倉庫主頁: Gitee ?? Github ?? GitCode ?? 歡迎點贊 ?? 收藏 ?留言 ?? 如有錯誤敬請糾正! WebSocket是一種在Web瀏覽器與Web服務(wù)器之間建立雙向通信的協(xié)議,而Spring Boot提供了便捷的WebSocket支持

    2024年02月02日
    瀏覽(17)
  • WebSocket(三) -- 使用websocket+stomp實現(xiàn)群聊功能

    WebSocket(三) -- 使用websocket+stomp實現(xiàn)群聊功能

    SpringBoot+websocket的實現(xiàn)其實不難,你可以使用原生的實現(xiàn),也就是websocket本身的OnOpen、OnClosed等等這樣的注解來實現(xiàn),以及對WebSocketHandler的實現(xiàn),類似于netty的那種使用方式,而且原生的還提供了對websocket的監(jiān)聽,服務(wù)端能更好的控制及統(tǒng)計(即上文實現(xiàn)的方式)。 但是,真

    2023年04月08日
    瀏覽(20)
  • java中使用sockjs、stomp完成websocket通信

    主要配置 握手?jǐn)r截(這套方案好像前端無法補充Header,就不在這里做權(quán)限校驗)這里采用的方法是直接問號拼接token,前端 new SockJS(這里帶問號),sockjs使用的是http所以沒毛病,本文使用的是OAuth2權(quán)限校驗 之后可以設(shè)置握手之后的身份注入(配置了這個可以在單對單訂閱時直接使用) 儲

    2024年02月10日
    瀏覽(24)
  • 微信小程序使用stomp.js實現(xiàn)STOMP傳輸協(xié)議的實時聊天

    微信小程序使用stomp.js實現(xiàn)STOMP傳輸協(xié)議的實時聊天

    簡介: stomp.js:uniapp開發(fā)的小程序中使用 stomp.js:官網(wǎng) stomp.js:GitHub 本來使用websocket,后端同事使用了stomp協(xié)議,導(dǎo)致前端也需要對應(yīng)修改。 如何使用 在static/js中新建stomp.js和websocket.js,然后在需要使用的頁面引入監(jiān)聽代碼+發(fā)送代碼即可 代碼如下: 位置:項目/pages/static/

    2024年02月11日
    瀏覽(61)
  • uniapp微信小程序使用stomp.js實現(xiàn)STOMP傳輸協(xié)議的實時聊天

    uniapp微信小程序使用stomp.js實現(xiàn)STOMP傳輸協(xié)議的實時聊天

    簡介: stomp.js:原生微信小程序中使用 stomp.js:官網(wǎng) stomp.js:GitHub 本來使用websocket,后端同事使用了stomp協(xié)議,導(dǎo)致前端也需要對應(yīng)修改。 如何使用 1.yarn add stompjs 2.版本 “stompjs”: “^2.3.3” 3.在static/js中新建websocket.js,然后在需要使用的頁面引入監(jiān)聽代碼+發(fā)送代碼即可 代

    2024年02月11日
    瀏覽(32)
  • flutter開發(fā)實戰(zhàn)-webview插件flutter_inappwebview使用

    flutter開發(fā)實戰(zhàn)-webview插件flutter_inappwebview使用

    flutter開發(fā)實戰(zhàn)-webview插件flutter_inappwebview使用 在開發(fā)過程中,經(jīng)常遇到需要使用WebView,Webview需要調(diào)用原生的插件來實現(xiàn)。常見的flutter的webview插件是webview_flutter,flutter_inappwebview。之前整理了一下webview_flutter,查看https://blog.csdn.net/gloryFlow/article/details/131683122 這里我們使用fl

    2024年02月07日
    瀏覽(25)
  • websocket + stomp + sockjs學(xué)習(xí)

    websocket + stomp + sockjs學(xué)習(xí)

    Spring WebSocket整合Stomp源碼詳解 PDF版本 Spring SpringBoot官方文檔資料 spring5.1.9官方文檔關(guān)于websocket的介紹 spring5.3.29官方文檔關(guān)于websocket的介紹 WebSocket入門教程示例代碼,代碼地址已fork至本地gitee,原github代碼地址,源老外的代碼地址 [WebSocket入門]手把手搭建WebSocket多人在線聊天

    2024年02月12日
    瀏覽(23)
  • WebSocket—STOMP詳解(官方原版)

    WebSocket—STOMP詳解(官方原版)

    WebSocket協(xié)議定義了兩種類型的消息(文本和二進(jìn)制),但其內(nèi)容未作定義。該協(xié)議定義了一種機(jī)制,供客戶端和服務(wù)器協(xié)商在WebSocket之上使用的子協(xié)議(即更高級別的消息傳遞協(xié)議),以定義各自可以發(fā)送何種消息、格式是什么、每個消息的內(nèi)容等等。子協(xié)議的使用是可選的

    2024年02月04日
    瀏覽(20)
  • autox.js鏈接WebSocket實戰(zhàn),需要的老鐵直接拿走

    ?昨天寫腳本的時候需要用到sockcet接口,在網(wǎng)上苦尋一番之后發(fā)現(xiàn)這個段代碼還是比較ok的,今天拿出來給大家分享一下,需要的直接取?。?/p>

    2024年04月16日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包