openim_sdk 2.5.0
openim_sdk: ^2.5.0 copied to clipboard
An instant messaging plug-in that supports Android and IOS. And the server is also all open source.
Changelog #
2.4.1 - 2026-05-01 #
2.2.1 - 2026-04-20 #
2.2.0 - 2026-04-20 #
Features #
🚀 Cross-platform multithreading via isolate_manager
- Migrate all CPU-bound helpers (
computeMd5,computePartMd5s,computeCombinedMd5,computeImageDimensions,computeImageDimensionsFromFile,computeSearchFilter,computeHistoryFilter,readFilePart) from Fluttercompute()to theisolate_manager: ^6.3.2plugin. On Web they now run in a real JS Web Worker via the generated$shared_worker.js; on native they continue running in VM Isolates. Public API signatures are unchanged. - Split worker functions into a Flutter-free file (
lib/src/utils/sdk_isolate_workers_core.dart) so dart2js can compile them. A companion native-only file (lib/src/utils/sdk_isolate_workers_io.dart) handlesdart:io-based workers (file chunking). - New coordinator
SdkWorkers(lib/src/isolate/sdk_workers.dart) manages the shared worker lifecycle and registers function → worker-name mappings. SdkMethodCall/SdkMethodResult/SdkListenerEventnow carrytoMap/fromMapand a type-tagged envelope so the L1 background-Isolate protocol is fully Map-based (future-proof for any transport).- Web build requires consumers to run
dart run isolate_manager:generate --sharedonce to produceweb/$shared_worker.js(see README for details). The example app ships the pre-built file. - L1 big-SDK-Isolate (
SdkIsolateManager) keeps usingdart:isolateinternally becauseisolate_manager's request-responsecompute()model cannot receive push listener events while idle; the public API (initialize/isActive/invoke/events/dispose) is unchanged.
1.9.1 #
- add
updateNotemethod inFavoriteManagerto update note content and refresh favorite item.
1.9.0 #
🚀 Background Isolate Architecture #
All SDK Future methods (~160 methods across 10 managers) now run in a dedicated background Isolate, keeping the UI thread completely free from database I/O, network serialization, and protobuf parsing.
- New Isolate infrastructure — Added 4 core files:
SdkIsolateManager— Singleton lifecycle manager, gates Isolate vs local execution viaisActiveSdkIsolateEntry— Background Isolate entry point, receives(RootIsolateToken, SendPort)tupleSdkMethodDispatcher— 1400+ line switch-based dispatcher routing all 10 managers' methodsSdkIsolateProtocol— Request/response envelope types for cross-Isolate communication
- All 10 managers proxied — IMManager, ConversationManager, MessageManager, GroupManager, UserManager, FriendshipManager, MomentsManager, FavoriteManager, CallManager, RedPacketManager
- Listener event forwarding — All listener callbacks (connect, message, conversation, group, friendship, user, moments, favorite, call, red packet, custom business, upload progress) are serialized across the Isolate boundary and re-dispatched on the main Isolate
- Transparent activation — Call
SdkIsolateManager.initialize()beforeinitSDKto enable; omit it to run entirely on the main thread as before
🐛 Bug Fixes #
- Fixed
isInitializedalways returningfalsein Isolate mode — Added_initializedfield to track state across Isolate boundary - Fixed
.toJson()serialization crashes — Manually fixed 55 nested.toJson()calls across 4.g.dartfiles where generated code produced incorrect output - Fixed
_currentUserIDLateInitializationError— All 5 login paths (login,loginByEmail,loginByPhone,loginByAccount,loadLoginConfig) now properly initialize_currentUserIDon every manager via_setManagersUserID() - Fixed infinite Isolate recursion — Background Isolate no longer recursively spawns itself when
SdkIsolateManager.isActiveis true inside the Isolate - Fixed
BackgroundIsolateBinaryMessengercrash — Platform channel calls (path_provider) are resolved on the main Isolate before entering the background Isolate - Fixed duplicate
ToStoreregistration — RemovedgetDatabaseInstance()as public API, added KV proxy methods (getValue/setValue/removeValue/getSpaceInfo) through the Isolate boundary - Fixed video message display issues — Video messages now show thumbnails and play correctly:
- Changed
enableHardwareAccelerationtotrueon non-Linux platforms (fixes mpv software renderer crash) - Fixed
createSnapshotto reliably capture first frame by playing with volume 0 and waiting for stream dimensions - Added try-catch to video upload branch in
_handleMediaUploadIfNeeded
- Changed
- Fixed
build.yaml— Changed from wildcardgenerate_forto explicit file list to work with analyzer 10.0.0
📦 New Models #
CallSession— Call session model withtoJson()/fromJson()supportMomentCreateReq— Moment creation request model withtoJson()/fromJson()support- Added
fromJsonfactories toSendRedPacketRequest,RedPacketDetail, andPointsTransaction
1.7.7 #
- add
changePasswordandresetPasswordmethod. - update
tostoreversion
1.7.6 #
- Red packet grab notification refactored: BusinessNotification → real IM custom message:
Grab notifications are no longer pushed as BusinessNotification "phantom messages". The backend now sends a real IM custom message (
contentType=110,description="redPacketGrabNotify") into the conversation after a successful grab, appearing as a visible grab-notification bar in chat history. - Added
RedPacketGrabNotifyMessageDatamodel: Parses the server-sent grab notification message, containingpacketID,grabberID,grabberName,grabberFaceURL,senderID,senderName,amountfields. - Removed
RedPacketGrabbedNotifymodel: Previously used for BusinessNotification-based grab events, now replaced byRedPacketGrabNotifyMessageData. - Simplified
OnRedPacketListener: RemovedonRedPacketGrabbedcallback; onlyonRedPacketExpiredandonPointsBalanceChangedremain. - Simplified
RedPacketManager.dispatchBusinessNotification: Removedred_packet_grabbedbranch; onlyred_packet_expiredandpoints_adjustedhandling remains. - Red packet & points system: Added
RedPacketManager, encapsulating send/grab/detail APIs and points balance queries. - Model expansion:
RedPacketGrabInfo/RedPacketDetail/RedPacketGrabbedNotifygainednicknameandfaceURLfields, including user avatar info in grab records. IMManagerintegration:redPacketManageradded as a standard field inIMManager, consistent with other managers;onPointsBalanceChangedcallback fires automatically on balance changes.- Refactor: Removed
OpenIM.redPacketManagershortcut, unified toOpenIM.iMManager.redPacketManager. - Offline message pull: N per-message callbacks → 1 batch callback (
msg_syncer.dart,message_manager.dart,advanced_msg_listener.dart): Aligned with Go SDKbatchNewMessagesdesign:_processPulledMsgsno longer triggersonRecvOfflineNewMessagefor each message in the same conversation one by one, now fires the newonRecvOfflineNewMessages(List<Message>)batch callback in a single call. - Empty
senderNicknamein search results (notification_dispatcher.dart,msg_syncer.dart,user_manager.dart,database_service.dart): Aligned with Go SDKUpdateMsgSenderFaceURLAndSenderNickname: when the user's own info (nickname/avatar) changes, retroactively updatessenderNickname/senderFaceUrlfor all messages in the local database. - WebSocket push messages not storing
senderFaceUrl(_msgDataToMapinmsg_syncer.dart): Map key used'senderFaceURL'(uppercase L) which mismatched the DB columnsenderFaceUrl(lowercase l), preventing avatar URLs from being written to the database. Fix: changed key to'senderFaceUrl'to align with DB schema. - Incorrect
searchLocalMessagesresults (_searchFilterWorkerinsdk_isolate.dart): Original implementation performed fuzzy keyword matching on the entirecontentJSON string, causing number searches to hit image dimensions, file path sequences, and server URL IDs. Fixed to search specific fields bycontentType, aligned with Go SDKfilterMsglogic:- Text (101): search
textElem.contentonly - @message (106): search
atTextElem.textonly - File (105): search
fileElem.fileNameonly - Merge (107): search
mergeElem.titleonly - Card (108): search
cardElem.nicknameonly - Location (109) / Custom (110): search
descriptiononly - Quote (114): search
quoteElem.textonly - Image (102) / Voice (103) / Video (104): excluded when keyword is present
- Text (101): search
1.6 #
- When Bug 1 sends an empty string,
draftTextTimeis refreshed to the current time.simpleSortusesmax(draftTextTime, latestMsgSendTime)for sorting, with the new timestamp > the latestMsgSendTime of all older sessions → skipping to the top of the session list. - Optimize logs and encapsulate logs as separate plug-ins,
aoiwe_logger. - Remove
setAppBackgroundStatusmethod. - Incremental synchronization for Conversations / Friends / Groups (aligned with Go SDK
VersionSynchronizer):MsgSyncer._syncConversationsAndSeqs(): switched togetIncrementalConversation(version-based increment). Falls back to_syncConversationsFull()whenfull=trueor on first install/reinstall.MsgSyncer._syncFriends(): switched togetIncrementalFriends, supporting delete / insert / update paths.MsgSyncer._syncJoinedGroups(): switched togetIncrementalJoinGroup; only re-fetches member lists for newly inserted groups.- All three sync channels persist new version numbers via
setVersionSyncinto thelocal_version_synctable.
1.5 #
- Fixed friend sync issues, including incorrect old data returned by friendship listeners.
1.4 #
- Aligned message/conversation sync logic with Go SDK:
MsgSyncer._syncConversationsAndSeqs(): for non-first install, fetches full server conversationseqto avoid missing newly added server conversations.MsgSyncer._syncMessages(): fixed incorrect skipping ofn_notification conversations in non-reinstall scenarios; batching now accumulates by estimated message count toSplitPullMsgNum(100)before pulling.MsgSyncer._syncMissingMessages(): gap sync now first fetches servermaxSeq, then pulls by actual interval[local+1, serverMax].MsgSyncer.handlePushMsg(): push continuity check aligned with GopushTriggerAndSync.MsgSyncer._syncHistoryByQueue(): added history sync queue to continuously pull by ranges and advanceseq.
- Fixed repeated login failure (duplicate GetIt registration):
IMManager.login(): unregisters oldloginUserinstance before registration.IMManager.logout(): unregistersloginUserto fixUserInfo already registeredon relogin.
- Aligned restart recovery strategy with Go SDK (
sending -> failed):MessageManager.recoverSendingMessages(): marks sending messages as failed after restart, aligned with GohandlerSendingMsg. - Aligned post-connect sync trigger timing:
IMManagertriggersMsgSyncer.doConnectedSync()on each successful connection and again when app returns to foreground. - Completed notification semantics and read receipt handling:
NotificationDispatcheradded handling for2102(delete message) and1703(clear conversation).2200read receipt now mapsseqback toclientMsgID. - Completed incremental sync and storage capabilities:
ImApiServiceaddedgetIncrementalJoinGroup()andgetFullJoinGroupIDs().DbSchemaaddedlocal_uploadsandlocal_version_sync; group member unique key aligned to(groupID, userID). - Fixed consistency gaps in full-ID sync for friends/groups: Added local set-diff cleanup for friends and groups.
- Aligned incremental entry points for relationships/groups/conversations: Switched from full pull to version-based incremental sync for friends, groups, and conversations.
- Completed resumable upload loop:
IMManager.uploadFile()now supports resuming uploaded parts for the sameuploadID. - Completed independent notification-seq persistence:
DbSchemaaddedlocal_notification_seqs. Notification processing paths now persist notification seq updates. - Fixed Flutter Web crash
MissingPluginException(getApplicationSupportDirectory):OpenImUtils.defaultDbPath()now useskIsWebto detect Web and avoids callinggetApplicationSupportDirectoryon Web. - Fixed group chat info synchronization issues.
- Fixed missing sender base information in messages.
- Fixed failure when removing users from blocklist.
- Optimized file upload performance.
- Fixed startup warning for
getApplicationSupportDirectory.
1.3 #
- Fixed missing group names during conversation sync:
NotificationDispatcher._syncConversations(): servergetAllConversationsdoes not returnshowName/faceURL; client now fills them via_batchFillShowNameAndFaceURL().MsgSyncer._enrichNewConversation(): added network fallback with caching for group/user names. - Fixed
userInfo == nullafter Web refresh:IMManagernow supports callingloadLoginConfig()beforerunAppto restore login state from IndexedDB. - Web file/image/video upload support: Added byte-stream upload methods:
MessageManager.createImageMessageFromBytes()MessageManager.createVideoMessageFromBytes()MessageManager.createFileMessageFromBytes()IMManager.uploadFile()adds optionalfileBytesparameter
IMManagerchanged to singleton mode: usesfactory+_internalto avoid state loss.- Unified all data models with
Equatable:Message.propsexpanded from[clientMsgID]to all 41 fields. AddedEquatableto 14 additional model classes. - Fixed message state becoming failed after switching conversations:
Default incoming cloud/push message status to
MessageStatus.succeededbefore insertion. - Fixed conversation list not showing latest message content after send:
Switched to
DatabaseService.messageToDbMap()serialization for format compatibility. - Fixed latestMsg not updating on message send:
Added
clientMsgIDfallback matching for status transitions. - Optimized first-install sync performance: Skip notification dispatch in reinstall sync.
- Fixed incorrect blocklist display:
Updated
BlacklistInfomodel to useblockUserIDinstead ofuserID. - Fixed empty
latestMsgin conversation list on first install: Optimized_syncMessages()for first install (reinstalled=true). - Fixed file upload failure (HTTP 500): Corrected multipart upload URL assembly and response header parsing.
- Fixed uploaded message loss when switching conversations:
Added
recoverSendingMessages(); sending messages are marked failed on restart. - Fixed message sync efficiency issues:
Optimized
_syncConversationsAndSeqs()aligned with Go SDK.
1.2 #
- Background refresh callback for Moments:
onMomentListUpdated:OnMomentsListeneraddsonMomentListUpdated;getMomentList()now uses local-first return, then async network fetch. - Fixed messages disappearing after re-entering conversation when send previously failed:
Updated
recoverSendingMessages()to mark sending messages as failed and updatelatestMsgstatus. - Fixed sending messages disappearing when switching conversations:
Corrected
getHistoryMessages()filtering forstartSeq=0. - Fixed inability to pull history messages:
Removed blocking check
convMaxSeq > 0ingetAdvancedHistoryMessageList.
1.1 #
loginByAccount(): added account/password login.UserManager.register(): register account via chat service.UserManager.sendVerificationCode(): send verification code for register/reset-password/login.loginByEmail/loginByPhonesupport either password or verification code.- Fixed
register()using wrong Dio instance: switched to Chat API. - Fixed Web relogin freeze after logout:
logout()no longer closes database on Web. - Fixed reconnect flag not reset:
connect()now resets_isReconnecting. - Added
LinkInfomodel,FavoriteItem.linkInfo,FavoriteItem.fromLink(),FavoriteManager.addLink()/removeLink(). NoteInfofields changed to non-null.FavoriteTypechanged to enum (breaking change).FavoriteItemadds typed content fields:message,momentInfo,momentComment,noteInfo.- Added
NoteInfomodel. - Added helper methods in
FavoriteManager:isMessageFavorited,isMomentFavorited,addMessage,addMoment, etc. - Added
isInitializedproperty. - Fixed WebSocket message decode failure on Web: detects Web and disables gzip compression.
- Fixed chat messages failing to load: removed incorrect filtering for
contentType >= 1000. - Fixed Moments API using wrong token: switched to
chatToken. - Fixed empty first load in Moments: directly returns network result when local cache is empty.
1.0 #
First official release of the pure-Dart OpenIM SDK, aligned with Go SDK (openim-sdk-core v3.8.0) core capabilities.
Core Architecture #
- WebSocket long connection with protobuf encoding/decoding, heartbeat, and auto-reconnect.
- ToStore-based local persistence with user-scoped storage isolation.
- Service lifecycle managed with GetIt dependency injection.
- HTTP REST API layer covering all openim-server endpoints.
- Unified notification dispatcher for server push events.
- Message syncer for incremental pulling and deduplication.
IMManager — SDK Management #
initSDK/unInitSDK,login/logout,uploadFile,getSdkVersion,setAppBackgroundStatus,networkStatusChanged,updateFcmToken,setAppBadge.
ConversationManager — Conversation Management #
- Fetch, pin, draft, hide, DND, burn-after-read, mark read, typing, delete/clear, search, unread stats.
MessageManager — Message Management #
- 24 creation methods, send, history, search, revoke, delete, local insert.
GroupManager — Group Management #
- Group CRUD, member management, mute, join/quit, applications.
FriendshipManager — Friendship #
- Add/delete/update, query, applications, blocklist.
UserManager — User Management #
- Login helpers, user profile, online status, client config.
Listeners (10) #
OnConnectListener,OnAdvancedMsgListener,OnConversationListener,OnFriendshipListener,OnGroupListener,OnUserListener,OnMsgSendProgressListener,OnUploadFileListener,OnCustomBusinessListener,OnListenerForService.
Performance Optimizations #
- O(1) enum lookup, batched DB queries, unified timer cleanup, lazy loading, parallelized login, set-based dedup.
Data Models #
Message,ConversationInfo,UserInfo/FriendInfo/BlacklistInfo/UserStatusInfo,GroupInfo/GroupMembersInfo/GroupApplicationInfo,FriendApplicationInfo,NotificationInfo/SearchInfo/InputStatusChangedData.
Enums (17) #
MessageType,MessageStatus,ConversationType,LoginStatus,GroupType,GroupRoleLevel,GroupStatus,GroupVerification,GroupMemberFilter,GroupAtType,AllowType,JoinSource,Relationship,ReceiveMessageOpt,IMPlatform,SDKErrorCode,WebSocketStatus.
Post-release Fixes #
- Fixed self-to-self conversations appearing in list.
- Added
OpenIMExceptionwith server error code mapping. - Fixed
getGroupMemberListreturning empty list; added realtime group-member notification DB updates. - Fixed conversation
latestMsgalways null after initial sync; reinstall sync optimization; gap sync fix. - Fixed single conversation unread count always being 0; global type-safety hardening.
- Exported
OpenImUtilsclass. - Corrected names in
MessageType.