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

使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南

這篇具有很好參考價值的文章主要介紹了使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南

開篇

在本篇博客文章中,我們將通過OpenAI的API構(gòu)建一個簡單的對話界面,與ChatGPT進(jìn)行聊天。

近來OpenAI和ChatGPT的熱度很高,尤其是最近發(fā)布的GPT-4。這類工具的大量使用案例已經(jīng)涌現(xiàn)出來,但目前人們最常用ChatGPT的方式是通過chat.openai.com進(jìn)行聊天。我一直在使用ChatGPT來激發(fā)靈感、編寫一些Flutter代碼片段,甚至是撰寫這篇博客文章的大綱!當(dāng)然,它建議的大綱非常樂觀,因此我不得不略過一些部分,但它仍然提供了足夠的指引,讓我能夠立即開始。

然而,OpenAI的官方聊天界面體驗(yàn)并不好。它非常有限,聊天歷史記錄經(jīng)常無法正常工作。已經(jīng)有人使用Web技術(shù)構(gòu)建了更好的UI和用戶體驗(yàn)的ChatGPT客戶端應(yīng)用程序,例如TypingMind。

作為Flutter開發(fā)者,我不禁想到Flutter非常適合作為ChatGPT客戶端應(yīng)用程序的選擇!Flutter具有跨平臺能力和豐富的UI組件,是這樣一個項(xiàng)目的完美選擇。我們可以編寫一次代碼,然后將應(yīng)用程序發(fā)布在Web、iOS、Android以及桌面平臺上:Windows、macOS和Linux。

ChatGPT API

要使用OpenAI的任何API,您需要注冊并獲取API密鑰。請注意,API使用可能會產(chǎn)生費(fèi)用,您需要提供付款詳細(xì)信息。我們將使用的gpt-3.5-turbo模型相對便宜,除非您經(jīng)常使用它,否則不應(yīng)花費(fèi)太多錢。

具體來說,我們將使用Chat API(聊天完成),該API支持兩個OpenAI的模型:gpt-3.5-turbo和gpt-4。我們可以在此處找到Chat API的完整參考,其中涉及在
https://api.openai.com/v1/chat/completions 上執(zhí)行POST請求。

此時,我們可以使用http庫向Chat API發(fā)送必需的數(shù)據(jù)并解析響應(yīng)。但是,由于Dart和Flutter社區(qū)的貢獻(xiàn),已經(jīng)在pub.dev上提供了一個可用的包:dart_openai。它將為我們進(jìn)行API請求并返回解析后的響應(yīng),因此我們只需獲取響應(yīng)文本并在應(yīng)用程序中顯示即可。

以下是一個接受用戶消息并返回ChatGPT響應(yīng)的方法:

Future<String> completeChat(String message) async {
  final chatCompletion = await OpenAI.instance.chat.create(
    model: 'gpt-3.5-turbo',
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        content: message,
        role: 'user',
      ),
    ],
  );
  return chatCompletion.choices.first.message.content;
}

由于這將是一次對話,因此我們需要在請求中傳遞以前的消息,以便ChatGPT具有到目前為止整個對話的上下文,而不僅僅是用戶的最后一條消息。

class ChatMessage {
  ChatMessage(this.content, this.isUserMessage);

  final String content;
  final bool isUserMessage;
}

Future<String> completeChat(List<ChatMessage> messages) async {
  final chatCompletion = await OpenAI.instance.chat.create(
    model: 'gpt-3.5-turbo',
    messages: [
      ...previousMessages.map(
        (e) => OpenAIChatCompletionChoiceMessageModel(
          role: e.isUserMessage ? 'user' : 'assistant',
          content: e.content,
        ),
      ),
    ],
  );
  return chatCompletion.choices.first.message.content;
}

上面的方法接受用戶的最后一條消息以及對話中的所有先前消息。請注意,在API請求中,ChatGPT的響應(yīng)標(biāo)有助手的角色。

現(xiàn)在,我們把最終版本的completeChat方法放到一個ChatApi類中,以便稍后使用。

// models/chat_message.dart
class ChatMessage {
  ChatMessage(this.content, this.isUserMessage);

  final String content;
  final bool isUserMessage;
}
// api/chat_api.dart
import 'package:chatgpt_client/models/chat_message.dart';
import 'package:chatgpt_client/secrets.dart';
import 'package:dart_openai/openai.dart';

class ChatApi {
static const _model = 'gpt-3.5-turbo'; // 設(shè)置模型為"gpt-3.5-turbo"

ChatApi() { // 構(gòu)造函數(shù),設(shè)置OpenAI的apiKey和organization
OpenAI.apiKey = openAiApiKey;
OpenAI.organization = openAiOrg;
}

Future<String> completeChat(List<ChatMessage> messages) async {
// 定義方法completeChat,接收ChatMessage列表類型參數(shù)messages,并返回Future<String>類型
final chatCompletion = await OpenAI.instance.chat.create( // 調(diào)用OpenAI的chat.create方法,獲取ChatCompletionModel對象
model: _model, // 傳遞模型參數(shù)
messages: messages // 傳遞對話歷史消息參數(shù),并將ChatMessage列表轉(zhuǎn)換為OpenAIChatCompletionChoiceMessageModel列表
.map((e) => OpenAIChatCompletionChoiceMessageModel(
role: e.isUserMessage ? 'user' : 'assistant', // 指定消息發(fā)送者角色
content: e.content, // 傳遞消息文本內(nèi)容
))
.toList(),
);
return chatCompletion.choices.first.message.content; // 返回ChatCompletionModel對象中的消息內(nèi)容
}
}

請注意,在構(gòu)造函數(shù)中,我們設(shè)置了API密鑰和組織ID。如果沒有API密鑰,任何請求都將失敗。組織ID是可選的,如果您在OpenAI平臺上設(shè)置了多個組織,可以提供組織ID。

// secrets.dart
const openAiApiKey = 'YOUR_API_KEY';
const openAiOrg = 'YOUR_ORGANIZATION_ID';

為了避免將敏感信息提交到版本控制中,我們通常會將其存儲在 secrets 文件中并在 .gitignore 中添加 secrets 文件,以便在提交時忽略這些文件。在 GitHub 上的項(xiàng)目存儲庫中,通常會提供一個名為 secrets_example.dart 的文件,其中包含占位符值,供開發(fā)人員參考并創(chuàng)建自己的 secrets 文件。

API密鑰的注意事項(xiàng)

在本文中,我們正在構(gòu)建一個客戶端應(yīng)用程序。像這樣硬編碼API密鑰的應(yīng)用程序不應(yīng)該發(fā)布。由于API使用可能會產(chǎn)生費(fèi)用,您不希望暴露自己的API密鑰。

如果您想發(fā)布這樣的應(yīng)用程序,您有兩個選擇:

1.允許用戶提供自己的API密鑰開始聊天。用戶可以通過應(yīng)用程序提供他們的密鑰,您可以將其安全地存儲在本地存儲中,以在每個API請求中使用。

2.而不是直接調(diào)用聊天API,可以調(diào)用一個服務(wù)器或邊緣函數(shù),然后使用自己的令牌調(diào)用聊天API。這樣,您就不會暴露自己的API密鑰,可以控制流量,并具有其他授權(quán)和速率限制要求。如果您選擇這種方法,您可能需要考慮賺錢,因?yàn)榻?jīng)常使用應(yīng)用程序的用戶將花費(fèi)您的錢!

構(gòu)建前端界面

現(xiàn)在 Chat API 已準(zhǔn)備好使用,是時候開始構(gòu)建 UI 了。如果你從零開始,可以使用 "flutter create" 命令初始化一個 Flutter 項(xiàng)目:

flutter create my_chatgpt_client

UI將是相當(dāng)標(biāo)準(zhǔn)的,包含兩個主要的組件:消息編輯器和消息氣泡。主屏幕將是聊天中所有消息的列表(作為消息氣泡),消息編輯器在底部,我們可以在其中輸入消息。

讓我們從消息編輯器小部件開始:

// widgets/message_composer.dart

import 'package:flutter/material.dart';

class MessageComposer extends StatelessWidget {
  MessageComposer({
    required this.onSubmitted, // 回調(diào)函數(shù),當(dāng)用戶輸入文本提交時調(diào)用
    required this.awaitingResponse, // 是否正在等待 Chat API 的響應(yīng)
    super.key,
  });

  final TextEditingController _messageController = TextEditingController(); // 用于文本輸入的控制器

  final void Function(String) onSubmitted; // 回調(diào)函數(shù),當(dāng)用戶輸入文本提交時調(diào)用
  final bool awaitingResponse; // 是否正在等待 Chat API 的響應(yīng)

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(12), // 內(nèi)邊距
      color: Theme.of(context).colorScheme.secondaryContainer.withOpacity(0.05), // 顏色
      child: SafeArea(
        child: Row(
          children: [
            Expanded(
              child: !awaitingResponse // 如果沒有正在等待 Chat API 的響應(yīng)
                  ? TextField(
                      controller: _messageController, // 將文本控制器傳遞給 TextField 組件
                      onSubmitted: onSubmitted, // 當(dāng)用戶提交文本時調(diào)用 onSubmitted 回調(diào)函數(shù)
                      decoration: const InputDecoration(
                        hintText: 'Write your message here...', // 提示文本
                        border: InputBorder.none, // 邊框
                      ),
                    )
                  : Row(
                      mainAxisAlignment: MainAxisAlignment.center, // 將子組件水平居中
                      children: const [
                        SizedBox(
                          height: 24,
                          width: 24,
                          child: CircularProgressIndicator(), // 等待指示器
                        ),
                        Padding(
                          padding: EdgeInsets.all(16),
                          child: Text('Fetching response...'), // 正在獲取響應(yīng)
                        ),
                      ],
                    ),
            ),
            IconButton(
              onPressed: !awaitingResponse // 如果沒有正在等待 Chat API 的響應(yīng)
                  ? () => onSubmitted(_messageController.text) // 當(dāng)用戶點(diǎn)擊發(fā)送按鈕時調(diào)用 onSubmitted 回調(diào)函數(shù)
                  : null, // 禁用按鈕
              icon: const Icon(Icons.send), // 發(fā)送圖標(biāo)
            ),
          ],
        ),
      ),
    );
  }
}

消息編輯器將在文本字段被提交(例如,按下Enter鍵)或者我們點(diǎn)擊右側(cè)的發(fā)送按鈕時,調(diào)用我們傳遞給它的onSubmitted方法。我們可以使用awaitingResponse標(biāo)志隱藏文本字段并禁用發(fā)送按鈕。當(dāng)我們等待API的響應(yīng)時,我們將將此標(biāo)志設(shè)置為true以表示消息正在提交中。

消息氣泡小部件是一個簡單的容器,根據(jù)消息是用戶消息還是AI生成的消息,具有不同的背景顏色和發(fā)送者名稱:

// widgets/message_bubble.dart
import 'package:flutter/material.dart';

class MessageBubble extends StatelessWidget {
  const MessageBubble({
    required this.content,
    required this.isUserMessage,
    super.key,
  });

  final String content; // 消息內(nèi)容
  final bool isUserMessage; // 是否為用戶消息

  @override
  Widget build(BuildContext context) {
    final themeData = Theme.of(context);
    return Container(
      margin: const EdgeInsets.all(8), // 設(shè)置組件的邊距
      decoration: BoxDecoration(
        color: isUserMessage // 根據(jù)消息類型設(shè)置不同的背景顏色
            ? themeData.colorScheme.primary.withOpacity(0.4)
            : themeData.colorScheme.secondary.withOpacity(0.4),
        borderRadius: const BorderRadius.all(Radius.circular(12)), // 設(shè)置圓角邊框
      ),
      child: Padding(
        padding: const EdgeInsets.all(12), // 設(shè)置內(nèi)邊距
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Text(
                  isUserMessage ? 'You' : 'AI', // 根據(jù)消息類型顯示發(fā)送者
                  style: const TextStyle(fontWeight: FontWeight.bold),
                ),
              ],
            ),
            const SizedBox(height: 8),
            Text(content), // 顯示消息內(nèi)容
          ],
        ),
      ),
    );
  }
}

現(xiàn)在我們已經(jīng)準(zhǔn)備好了所有必要的小部件,現(xiàn)在讓我們將它們?nèi)拷M合在主頁上。下面是主聊天頁面的代碼:

// chat_page.dart
import 'package:chatgpt_client/api/chat_api.dart';
import 'package:chatgpt_client/models/chat_message.dart';
import 'package:chatgpt_client/widgets/message_bubble.dart';
import 'package:chatgpt_client/widgets/message_composer.dart';
import 'package:flutter/material.dart';

class ChatPage extends StatefulWidget {
  const ChatPage({
    required this.chatApi,
    Key? key,
  }) : super(key: key);

  final ChatApi chatApi;

  @override
  State<ChatPage> createState() => _ChatPageState();
}

class _ChatPageState extends State<ChatPage> {
  final _messages = <ChatMessage>[
    ChatMessage('Hello, how can I help?', false),
  ];
  var _awaitingResponse = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Chat')),
      body: Column(
        children: [
          Expanded(
            child: ListView(
              children: [
                // 使用_spread_操作符將每個聊天消息轉(zhuǎn)換為MessageBubble widget
                ..._messages.map(
                  (msg) => MessageBubble(
                    content: msg.content,
                    isUserMessage: msg.isUserMessage,
                  ),
                ),
              ],
            ),
          ),
          // 使用MessageComposer widget顯示用戶輸入
          MessageComposer(
            onSubmitted: _onSubmitted,
            awaitingResponse: _awaitingResponse,
          ),
        ],
      ),
    );
  }

這是一個有狀態(tài)的widget,它開始時顯示消息"How can I help?",這樣我們就不會從空白聊天開始了。

最后一部分是_onSubmitted方法,當(dāng)用戶提交一條消息時,它會通過消息編輯器被調(diào)用。

// _onSubmitted方法將會在用戶輸入一條新的聊天消息后被調(diào)用
Future<void> _onSubmitted(String message) async {
  setState(() {
    // 在UI中顯示用戶剛剛輸入的消息
    _messages.add(ChatMessage(message, true));
    // 等待服務(wù)器的回復(fù)
    _awaitingResponse = true;
  });
  // 發(fā)送用戶的消息到API,等待API返回回復(fù)
  final response = await widget.chatApi.completeChat(_messages);
  setState(() {
    // 在UI中顯示API的回復(fù)
    _messages.add(ChatMessage(response, false));
    // 回復(fù)已經(jīng)接收完成,不再等待
    _awaitingResponse = false;
  });
}

當(dāng)用戶提交一條新的消息時,我們會在 setState 中將該消息添加到聊天消息中,并將 _awaitingResponse 設(shè)置為 true。這將在對話中顯示用戶的消息,并禁用消息編輯器。

接下來,我們將所有消息傳遞給聊天 API,并等待響應(yīng)。一旦我們得到了響應(yīng),我們會在 _messages 中添加它作為聊天消息,并在第二個 setState 調(diào)用中將 _awaitingResponse 設(shè)置回 false。

至此,對話流程就完成了!現(xiàn)在讓我們看看它的實(shí)際效果:

使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南

這是應(yīng)用程序的代碼和主要方法:

import 'package:chatgpt_client/api/chat_api.dart';
import 'package:chatgpt_client/chat_page.dart';
import 'package:flutter/material.dart';

void main() {
  // 運(yùn)行ChatApp
  runApp(ChatApp(chatApi: ChatApi()));
}

class ChatApp extends StatelessWidget {
  // 帶有chatApi參數(shù)的構(gòu)造函數(shù)
  const ChatApp({required this.chatApi, Key? key}) : super(key: key);

  final ChatApi chatApi; // chatApi屬性

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // MaterialApp,包含了應(yīng)用的所有基本元素
      title: 'ChatGPT Client', // 應(yīng)用的標(biāo)題
      theme: ThemeData(
        // 設(shè)置應(yīng)用的主題色
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.teal, // 主色調(diào)
          secondary: Colors.lime, // 次要色調(diào)
        ),
      ),
      home: ChatPage(chatApi: chatApi), // ChatPage是這個應(yīng)用的首頁
    );
  }
}

解析markdown

在我們之前與ChatGPT的對話中,我們問了一個跟進(jìn)問題“給我展示代碼”。

使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南

我們在回復(fù)中得到了相當(dāng)數(shù)量的Flutter代碼,但它們都是以markdown格式呈現(xiàn)的!我們將使用markdown_widget包來解決這個問題。

flutter pub add markdown_widget

在MessageBubble組件中,用MarkdownWidget替換包含消息內(nèi)容的Text組件:

MarkdownWidget(
  data: content,
  shrinkWrap: true,
)

經(jīng)過一次熱重載,我們可以看到代碼現(xiàn)在已經(jīng)被正確解析了。這很容易!

使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南

錯誤處理

如果我們從OpenAI得到了錯誤響應(yīng)怎么辦?在測試中,我遇到了一些429(Too Many Requests)異常。如果你調(diào)用API太頻繁,也可能出現(xiàn)這種錯誤,但也可能是因?yàn)镺penAI API總共接收到了太多的請求。

我們至少要處理這個錯誤并顯示一個有用的消息。下面是修改后的_onSubmitted方法:

Future<void> _onSubmitted(String message) async {
  setState(() {
    _messages.add(ChatMessage(message, true)); // 將輸入的消息添加到對話列表
    _awaitingResponse = true; // 設(shè)置正在等待響應(yīng)標(biāo)志
  });
  try {
    final response = await widget.chatApi.completeChat(_messages); // 調(diào)用 ChatApi 的 completeChat 方法來獲取 OpenAI 的響應(yīng)
    setState(() {
      _messages.add(ChatMessage(response, false)); // 將響應(yīng)添加到對話列表
      _awaitingResponse = false; // 取消等待響應(yīng)標(biāo)志
    });
  } catch (err) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('An error occurred. Please try again.')), // 顯示錯誤信息提示條
    );
    setState(() {
      _awaitingResponse = false; // 取消等待響應(yīng)標(biāo)志
    });
  }
}

當(dāng)然,這還可以進(jìn)一步改進(jìn)。我們可以提供一個選項(xiàng),在不需要發(fā)送新消息的情況下重試響應(yīng),但也可以在 ChatApi 中自動重試請求而不顯示錯誤。

結(jié)束

總結(jié)一下,現(xiàn)在我們已經(jīng)有一個完全可用的聊天應(yīng)用程序,可以隨時在任何平臺上與ChatGPT聊天了!

在這篇文章中,我們展示了如何構(gòu)建一個基本的聊天應(yīng)用程序,通過OpenAI的聊天API與ChatGPT進(jìn)行對話。我們還添加了一些附加功能,如markdown解析和錯誤處理。

這些功能相當(dāng)基礎(chǔ),但是我們可以通過這樣的應(yīng)用程序?qū)崿F(xiàn)更多有用的功能,比如能夠復(fù)制和/或共享響應(yīng)。此外,我們可以使用本地或云數(shù)據(jù)庫來存儲對話,以便隨時訪問它們。

您可以在這里找到源代碼。

https://github.com/dartling/chatgpt_client

今天的分享就到這里,感謝你的閱讀,希望能夠幫助到你,文章創(chuàng)作不易,如果你喜歡我的分享,別忘了點(diǎn)贊轉(zhuǎn)發(fā),讓更多有需要的人看到,最后別忘記關(guān)注「前端達(dá)人」,你的支持將是我分享最大的動力,后續(xù)我會持續(xù)輸出更多內(nèi)容,敬請期待。

原文:
https://dartling.dev/building-a-chatgpt-client-app-with-flutter

作者:Christos

直接翻譯,有自行改編和添加部分,翻譯水平有限,難免有疏漏,歡迎指正文章來源地址http://www.zghlxwxcb.cn/news/detail-451779.html

到了這里,關(guān)于使用Flutter構(gòu)建ChatGPT客戶端:快速入門指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • ChatGPT桌面客戶端支持gpt4模型,附使用說明

    ChatGPT桌面客戶端支持gpt4模型,附使用說明

    #軟件核心功能: 1、支持OpenAI官方秘鑰及API2D雙秘鑰使用;如果全局魔法,可以自己用官方秘鑰;沒魔法國內(nèi)可直接使用API2D秘鑰; 2、內(nèi)置GPT4模型選項(xiàng),如果你的官方秘鑰支持可直接使用;你也可以注冊API2D秘鑰進(jìn)行使用(非推廣,這真是國內(nèi)最簡單的方式了); 3、支持連

    2024年02月07日
    瀏覽(23)
  • 【物聯(lián)網(wǎng)】EMQX(二)——docker快速搭建EMQX 和 MQTTX客戶端使用

    【物聯(lián)網(wǎng)】EMQX(二)——docker快速搭建EMQX 和 MQTTX客戶端使用

    在上一篇文章中,小編向大家介紹了物聯(lián)網(wǎng)必然會用到的消息服務(wù)器EMQ,相信大家也對EMQ有了一定的了解,那么接下來,小編從這篇文章正式開始展開對EMQ的學(xué)習(xí)教程,本章節(jié)來記錄一下如何對EMQ進(jìn)行安裝。 EMQ作為第三方中間件,可以安裝到很多種平臺上,比如macOS、window

    2024年02月03日
    瀏覽(25)
  • 【ChatGPT】如何使用Qt設(shè)計(jì)SocketIO類型的WebSocket協(xié)議客戶端

    本文第一次發(fā)布 2023年03月24日09點(diǎn)28分 Authors ChatGPT / THDMI 最近寫 Flask-SocketIO 服務(wù)端的時候,苦于不熟悉前端代碼,想試著用 QT 來寫客戶端,但不清楚該怎么描述,以致于好像一直查的都是 RAW 類型的 WebSocket 協(xié)議處理,于是一直沒找到 event 和 room 或者 namespace 處理方式。 簡單

    2023年04月21日
    瀏覽(23)
  • spring data elasticsearch使用7.x客戶端兼容es 8.x和使用ssl構(gòu)建RestHighLevelClient

    es在7.x中默認(rèn)加入elastic security組件所以java client需要使用ssl連接es server. es 8.x 中廢棄了 RestHighLevelClient ,使用新版的 java api client ,但是spring data elasticsearch還未更新到該版本.所以需要兼容es 8.x 如下是RestHighLevelClient構(gòu)建方法: spring data elasticsearch客戶端依賴(基于spring boot2.7使用最新

    2024年02月13日
    瀏覽(27)
  • 【Flutter】Dio 強(qiáng)大的Dart/Flutter HTTP客戶端

    Dio是一個強(qiáng)大的Dart/Flutter HTTP客戶端,支持全局配置、攔截器、FormData、請求取消、文件上傳/下載、超時等功能。 首先,

    2024年02月11日
    瀏覽(24)
  • flutter 客戶端日志上傳定位錯誤信息

    flutter 客戶端日志上傳定位錯誤信息

    flutter 開發(fā)的app 安裝到真機(jī)上 無法定位報(bào)錯信息,只能使用usb連接電腦 使用adb logcat來查看日志效率低下。 如果將flutter 開發(fā)的app 運(yùn)行的時候 將日志寫進(jìn)一個日志文件里面去,然后給flutter app搭建一個http服務(wù)器,后端知道對應(yīng)app的ip后,直連對應(yīng)app 獲取日志文件。 獲取本機(jī)

    2024年01月21日
    瀏覽(20)
  • netty構(gòu)建udp服務(wù)器以及發(fā)送報(bào)文到客戶端客戶端詳細(xì)案例

    netty構(gòu)建udp服務(wù)器以及發(fā)送報(bào)文到客戶端客戶端詳細(xì)案例

    目錄 一、基于netty創(chuàng)建udp服務(wù)端以及對應(yīng)通道設(shè)置關(guān)鍵 二、發(fā)送數(shù)據(jù) 三、netty中的ChannelOption常用參數(shù)說明 1、ChannelOption.SO_BACKLOG 2、ChannelOption.SO_REUSEADDR 3、ChannelOption.SO_KEEPALIVE 4、ChannelOption.SO_SNDBUF和ChannelOption.SO_RCVBUF 5、ChannelOption.SO_LINGER 6、ChannelOption.TCP_NODELAY 以上代碼中

    2024年04月09日
    瀏覽(31)
  • 快速搭建springboot websocket客戶端

    快速搭建springboot websocket客戶端

    WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進(jìn)行全雙工通訊的協(xié)議。 HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實(shí)時地進(jìn)行通訊。 HTML5 定義的 WebSocket 協(xié)議,能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實(shí)時地進(jìn)行通訊。 瀏覽器通過 JavaSc

    2024年02月06日
    瀏覽(25)
  • java代碼構(gòu)建簡單http服務(wù)器和客戶端

    java代碼構(gòu)建簡單http服務(wù)器和客戶端

    初識http a、超文本傳輸 、應(yīng)用層的面向?qū)ο蟮膮f(xié)議,概念介紹網(wǎng)上資源一大堆,關(guān)鍵是基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)。 b、一開始接觸web項(xiàng)目,都是先接觸的servlet,tomcat服務(wù)器默認(rèn)實(shí)現(xiàn)的一套http規(guī)范,提供了基礎(chǔ)服務(wù)和組件環(huán)境,直接拿到請求、構(gòu)建正文、響應(yīng)客戶端 然而

    2024年02月10日
    瀏覽(28)
  • Python網(wǎng)絡(luò)編程實(shí)戰(zhàn):構(gòu)建TCP服務(wù)器與客戶端

    Python網(wǎng)絡(luò)編程實(shí)戰(zhàn):構(gòu)建TCP服務(wù)器與客戶端 在信息化時代,網(wǎng)絡(luò)編程是軟件開發(fā)中不可或缺的一部分。Python作為一種功能強(qiáng)大的編程語言,提供了豐富的網(wǎng)絡(luò)編程庫和工具,使得開發(fā)者能夠輕松構(gòu)建各種網(wǎng)絡(luò)應(yīng)用。本文將詳細(xì)介紹如何在Python中進(jìn)行網(wǎng)絡(luò)編程,特別是如何使用

    2024年04月15日
    瀏覽(26)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包