Skip to content

Commit

Permalink
Fix the 1024 bytes package spliting in Dart (#1667)
Browse files Browse the repository at this point in the history
  • Loading branch information
beastoin authored Jan 10, 2025
2 parents 7bff9b9 + 51298b6 commit 725df3c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 11 deletions.
42 changes: 36 additions & 6 deletions app/lib/backend/http/api/messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:friend_private/backend/http/shared.dart';
import 'package:friend_private/backend/schema/message.dart';
import 'package:friend_private/env/env.dart';
import 'package:friend_private/utils/logger.dart';
import 'package:friend_private/utils/other/string_utils.dart';
import 'package:http/http.dart' as http;
import 'package:instabug_flutter/instabug_flutter.dart';
import 'package:path/path.dart';
Expand Down Expand Up @@ -99,10 +100,25 @@ Stream<ServerMessageChunk> sendMessageStreamServer(String text, {String? appId})
return;
}

var messageId = "1000"; // default new message
var buffers = <String>[];
var messageId = "1000"; // Default new message
await for (var data in response.transform(utf8.decoder)) {
var lines = data.split('\n\n');
for (var line in lines.where((line) => line.isNotEmpty)) {
// Dealing w/ the package spliting by 1024 bytes in dart
// Waiting for the next package
if (line.length >= 1024) {
buffers.add(line);
continue;
}

// Merge package if needed
if (buffers.isNotEmpty) {
buffers.add(line);
line = buffers.join();
buffers.clear();
}

if (line.startsWith('think: ')) {
yield ServerMessageChunk(messageId, line.substring(7).replaceAll("__CRLF__", "\n"), MessageChunkType.think);
continue;
Expand All @@ -114,8 +130,7 @@ Stream<ServerMessageChunk> sendMessageStreamServer(String text, {String? appId})
}

if (line.startsWith('done: ')) {
var text = utf8.decode(base64.decode(line.substring(6)));
debugPrint(text);
var text = decodeBase64(line.substring(6));
yield ServerMessageChunk(messageId, text, MessageChunkType.done,
message: ServerMessage.fromJson(json.decode(text)));
continue;
Expand Down Expand Up @@ -162,10 +177,25 @@ Stream<ServerMessageChunk> sendVoiceMessageStreamServer(List<File> files) async*
return;
}

var messageId = "1000"; // default new message
var buffers = <String>[];
var messageId = "1000"; // Default new message
await for (var data in response.stream.transform(utf8.decoder)) {
var lines = data.split('\n\n');
for (var line in lines.where((line) => line.isNotEmpty)) {
// Dealing w/ the package spliting by 1024 bytes in dart
// Waiting for the next package
if (line.length >= 1024) {
buffers.add(line);
continue;
}

// Merge package if needed
if (buffers.isNotEmpty) {
buffers.add(line);
line = buffers.join();
buffers.clear();
}

if (line.startsWith('think: ')) {
yield ServerMessageChunk(messageId, line.substring(7).replaceAll("__CRLF__", "\n"), MessageChunkType.think);
continue;
Expand All @@ -177,14 +207,14 @@ Stream<ServerMessageChunk> sendVoiceMessageStreamServer(List<File> files) async*
}

if (line.startsWith('done: ')) {
var text = utf8.decode(base64.decode(line.substring(6)));
var text = decodeBase64(line.substring(6));
yield ServerMessageChunk(messageId, text, MessageChunkType.done,
message: ServerMessage.fromJson(json.decode(text)));
continue;
}

if (line.startsWith('message: ')) {
var text = utf8.decode(base64.decode(line.substring(9)));
var text = decodeBase64(line.substring(9));
yield ServerMessageChunk(messageId, text, MessageChunkType.message,
message: ServerMessage.fromJson(json.decode(text)));
continue;
Expand Down
19 changes: 14 additions & 5 deletions app/lib/utils/other/string_utils.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// string_utils.dart

import 'dart:convert';

String extractJson(String input) {
int braceCount = 0;
int startIndex = -1;
Expand Down Expand Up @@ -34,12 +36,19 @@ String extractJson(String input) {
}

String convertToHHMMSS(int seconds) {
int hours = seconds ~/ 3600;
int minutes = (seconds % 3600) ~/ 60;
int remainingSeconds = seconds % 60;
int hours = seconds ~/ 3600;
int minutes = (seconds % 3600) ~/ 60;
int remainingSeconds = seconds % 60;

String twoDigits(int n) => n.toString().padLeft(2, '0');

String twoDigits(int n) => n.toString().padLeft(2, '0');
return '${twoDigits(hours)}:${twoDigits(minutes)}:${twoDigits(remainingSeconds)}';
}

return '${twoDigits(hours)}:${twoDigits(minutes)}:${twoDigits(remainingSeconds)}';
String padBase64(String rawBase64) {
return (rawBase64.length % 4 > 0) ? rawBase64 += List.filled(4 - (rawBase64.length % 4), "_").join("") : rawBase64;
}

String decodeBase64(String data) {
return utf8.decode(base64.decode(padBase64(data)));
}

0 comments on commit 725df3c

Please sign in to comment.