Flutter ChatGPT PART 1
Flutter ChatGPT PART 2
Flutter ChatGPT PART 3
Flutter ChatGPT PART 4
ใน part ที่ 3 นี้เราจะจะลองเล่น feature ที่ชื่อว่า SSE กันครับ ซึ่งหาใครที่นึกไม่ออกว่ามัน คืออะไรให้นึกถึงตอนที่เรา เข้าใช้งาน ChatGPT version web จะสังเกตูว่าผลลัพธ์จะไม่ได้มาทีเดียว แต่จะค่อย ๆ response กลับมาทีละกลุ่ม ๆ ซึ่งในเป็นความสารมถ ของ SSE
SSE (Server-Sent Events) คืออะไร
SSE (Server-Sent Events) คือเทคโนโลยีทางเว็บที่ใช้ในการสื่อสารแบบแบบเสิร์ฟเวอร์ส่งข้อมูลมายังเบราว์เซอร์ของผู้ใช้โดยอัตโนมัติ โดยใช้โปรโตคอล HTTP หรือ HTTPS เพื่อส่งข้อมูลผ่านการเชื่อมต่อแบบรายการเดียว และผู้ใช้จะได้รับข้อมูลในรูปแบบของอีเวนต์ (events) จากเซิร์ฟเวอร์ โดยไม่ต้องร้องขอข้อมูลเอง
SSE นั้นมีข้อได้เปรียบเสมอเมื่อเทียบกับเทคโนโลยีการสื่อสารอื่นๆ เช่นการใช้งาน WebSocket หรือการโหลดข้อมูลผ่าน Ajax โดย SSE เหมาะสำหรับการส่งข้อมูลที่ต้องการการปรับปรุงแบบเรียลไทม์ (real-time updates) เช่นข้อมูลสถานะในแอปพลิเคชัน เหตุการณ์ในระบบ การอัพเดตข้อมูลสด และอื่นๆ
เซิร์ฟเวอร์สามารถส่งข้อมูลในรูปแบบของ Event หรืออีเวนต์ได้หลากหลายรูปแบบ เช่น ข้อความ (text), ข้อมูล JSON (application/json) หรือ HTML (text/html) และผู้ใช้สามารถรับข้อมูลด้วย JavaScript ด้วยการใช้ EventSource API ที่มีอยู่ในเบราว์เซอร์
SSE with chat_gpt_sdk
class ExampleSSE extends StatefulWidget {
const ExampleSSE({Key? key}) : super(key: key);
@override
State<ExampleSSE> createState() => _ExampleSSEState();
}
class _ExampleSSEState extends State<ExampleSSE> {
///ประกาศตัวแปร [openAI]
late OpenAI openAI;
///stream controller
List<Message>? chatResponseList;
@override
void initState() {
///new instance ให้กับตัวแปร [openAI]
///[isLog] = true ให้เปิด log ตอนยิง api
openAI = OpenAI.instance.build(
token: 'your-access-toekn',
baseOption: HttpSetup(
receiveTimeout: const Duration(seconds: 20),
connectTimeout: const Duration(seconds: 20)),
enableLog: true);
super.initState();
}
void chatCompleteSSE(){
///setup request
final request = ChatCompleteText(messages: [
Map.of({"role": "user", "content": 'Hello!'})
], maxToken: 200, model: ChatModel.gpt_4);
openAI.onChatCompletionSSE(request: request).listen((it) {
///response data
debugPrint(it.choices.last.message?.content);
setState(() {
///add new value to [chatResponseList]
if(chatResponseList == null){
final mMessage = Message(message: it.choices.last.message?.content);
chatResponseList?.add(mMessage);
}
///update message value in list
if(chatResponseList != null){
///get last message in list
final mChat = chatResponseList!.last;
///remove last list
chatResponseList!.removeLast();
///update value response
mChat.message = "${mChat.message}${it.choices.last.message?.content}";
///add new message
chatResponseList!.add(mChat);
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
const Text("SSE Example"),
SizedBox(
height: 300.0,
width: double.infinity,
child: ListView.builder(
itemCount: chatResponseList?.length ?? 0,
itemBuilder: (context, index) {
return Text('${chatResponseList?[index].message}');
}),
)
],
),
);
}
}
class Message {
final String? id;
final bool isBot;
String? message;
Message({this.id, this.isBot = true, this.message});
}
เพียงเท่านี้เราก็จะได้ผลลัพธ์แบบ stream response แบบเดียวกับ ChatGPT ในเว็บแล้ว แต่ว่ามันยังขาดบางอย่างๆไป ปุ่ม stop generate นั้นเองซึ่งเจ้าปุ่มนี้เราจะมาดูวิธีทำกันใน Part หน้ากันครับ