开发环境搭建
第一步:Flutter 安装和环境搭建直接查看:Flutter 文档 [1]。
第二步:登录 LeanCloud 控制台 [2],创建 LeanCloud 应用。
在控制台 > 应用 > 设置 >域名绑定页面绑定 API 访问域名。暂时没有域名可以略过这一步,LeanCloud 也提供了短期有效的免费体验域名;或者注册 LeanCloud 国际版 [3],国际版不要求绑定域名。在控制台 > 应用 > 设置 > 应用 Keys 页面记录 AppID、AppKey 与服务器地址备用,这里的服务器地址就是 REST API 服务器地址。如果未绑定域名,控制台相同的位置可以获取到免费的共享域名。APP 初始化设置在 pubspec.yaml 中,将 LeanCloud Flutter SDK 添加到依赖项列表:

dependencies:leancloud_official_plugin:^1.0.0-beta.8//即时通信插件leancloud_storage:^0.2.9//数据存储SDK
然后运行 flutter pub get 安装 SDK。
因为 leancloud_official_plugin 是基于 Swift SDK [4] 以及 Java Unified SDK [5] 开发,所以还要安装后面两个 SDK,这样应用才能分别在 iOS 和 Android 设备运行。
需要通过 CocoaPods 安装 Swift SDK,这一步和安装 iOS 其他第三方库是一样的,在应用的 ios 目录下执行 pod update 即可。
$cdios/$podupdate#或者$podinstall--repo-update
同样的,需要配置 Gradle 来安装 Java Unified SDK,打开工程目录 android/app/build.gradle,添加如下依赖,用 Android Studio 打开工程下的 android 目录,同步更新 Gradle 即可。
dependencies{implementation'cn.leancloud:storage-android:6.5.11'implementation'cn.leancloud:realtime-android:6.5.11'implementation'io.reactivex.rxjava2:rxandroid:2.1.1'}
小 tips: 安装 SDK 期间遇到任何困难都可在 LeanCloud 社区 [6] 发帖求助。
SDK 安装成功以后,需要分别 初始化 iOS 和 Android 平台 [7]。
用户系统Demo 里面并没有内置用户系统,可以选择联系人列表中的用户名来登录聊天系统。LeanCloud 即时通信服务端中只需要传入一个唯一标识字符串既可以表示一个「用户」,对应唯一的 Client, 在应用内唯一标识自己的 ID(clientId)。
在自己的项目中,如果已经有独立的用户系统也很方便维护。或者使用 LeanStorage 提供的用户系统 [8]。
会话列表会话列表要展示当前用户所参与的会话,会话名称、会话的成员,会话的最后一条消息。还需要展示未读消息数目。
会话列表对应 Conversation 表,查询当前用户的全部会话只需要下面两行代码:
ConversationQueryquery=client.conversationQuery();awaitquery.find();
按照会话的更新时间排序:
query.orderByDescending('updatedAt');
为了展示会话的最新一条消息,查询的时候要额外加上这行代码:
//让查询结果附带一条最新消息query.includeLastMessage=true;
这样会话页面的后端数据就搞定了。下面看一下如何显示数据。
会话查询成功返回的数据格式是 Conversation 类型的 List。
conversation.name 即会话的名称conversation.members 即会话成员conversation.lastMessage 就是当前会话的最新一条消息了。未读消息数的处理
如果要在 Android 设备上运行,需要在初始化 Java SDK 的时候加上下面这行代码,表示开启未读消息数通知:
AVIMOptions.getGlobalOptions().setUnreadNotificationEnabled(true);
swift SDK 是默认支持,无需额外设置。
可以监听 onUnreadMessageCountUpdated 时间获取未读消息数通知:
client.onUnreadMessageCountUpdated=({Clientclient,Conversationconversation,}){//conversation.unreadMessageCount即该conversation的未读消息数量};
注意要在以下两处清除未读消息数:
在对话列表点击某对话进入到对话页面时用户正在某个对话页面聊天,并在这个对话中收到了消息时会话详情页面上拉加载更多历史消息
查询聊天记录的时候,先查最近的 10 条消息,然后以第一页的最早的消息作为开始,继续向前拉取消息:
List<Message>messages;try{//第一次查询成功messages=awaitconversation.queryMessage(limit:10,);}catch(e){print(e);}try{//返回的消息一定是时间增序排列,也就是最早的消息一定是第一个MessageoldMessage=messages.first;//以第一页的最早的消息作为开始,继续向前拉取消息List<Message>messages2=awaitconversation.queryMessage(startTimestamp:oldMessage.sentTimestamp,startMessageID:oldMessage.id,startClosed:true,limit:10,);}catch(e){print(e);}
修改会话名
对话的名称是会话表 Conversation 默认的属性,更新会话名称只需要执行:
awaitconversation.updateInfo(attributes:{'name':'NewName',});
图片、语音消息
LeanCloud 即时通信 SDK 提供了下面几种默认的消息类型,Demo 中只用到了文本消息,图像消息和语音消息。
TextMessage 文本消息ImageMessage 图像消息AudioMessage 音频消息VideoMessage 视频消息FileMessage 普通文件消息(.txt/.doc/.md 等各种)LocationMessage 地理位置消息注意,图片与语音消息需要先保存成 LCFile,然后再调用发消息接口发消息。
比如发送音频消息。第一步先保存音频文件为 LCFile:
LCFilefile=awaitLCFile.fromPath('message.wav',path);awaitfile.save();
第二步,再发消息:
AudioMessageaudioMessage=AudioMessage.from(binaryData:file.data,format:'wav',);awaitthis.widget.conversation.send(message:audioMessage);
还要注意 iOS 设备发送图片消息注意打开相册和相机权限,语音消息需要麦克风权限:
<key>NSMicrophoneUsageDescription</key><string>录音功能需要访问麦克风,如果不允许,你将无法在聊天过程中发送语音消息。</string><key>NSCameraUsageDescription</key><string>发送图片功能需要访问您的相机。如果不允许,你将无法在聊天过程中发送图片消息。</string><key>NSPhotoLibraryUsageDescription</key><string>发送图片功能需要访问您的相册。如果不允许,你将无法在聊天过程中发送相册中的图片。</string>
离线推送通知
当用户下线以后,收到消息的时候,往往希望能有推送提醒。最简单的一种推送设置就是在 LeanCloud控制台 > 消息 > 即时通讯 > 设置 > 离线推送设置 页面,填入:
{"alert":"您有新的消息","badge":"Increment"}
这样 iOS 设备有离线消息的时候会收到提醒。这里 badge 参数为 iOS 设备专用,用于增加应用 badge 上的数字计数。
如果想在 Android 设备上实现离线推送,要增加一步接入 Android 混合推送 [9]。
当然在实际项目中,离线消息的提醒往往会要求更加具体,比如推送中要包括消息的内容或者消息类型等。LeanCloud 也提供了其他几种定制离线推送的方法,感兴趣可以自行查阅文档 [10]。
还要注意,iOS 推送一定要正确配置 配置 APNs 推送证书 [11],并打开 Xcode 的推送开关:
AppDelegate.swift 中开启推送,要这样设置:
importFlutterimportLeanCloudimportUserNotifications@UIApplicationMain@objcclassAppDelegate:FlutterAppDelegate{overridefuncapplication(_application:UIApplication,didFinishLaunchingWithOptionslaunchOptions:[UIApplication.LaunchOptionsKey:Any]?)->Bool{do{LCApplication.logLevel=.alltryLCApplication.default.set(id:"你的APPID",key:"你的APPKey",serverURL:"服务器地址")GeneratedPluginRegistrant.register(with:self)/registerAPNstoaccesstoken,likethis:/UNUserNotificationCenter.current().getNotificationSettings{(settings)inswitchsettings.authorizationStatus{case.authorized:DispatchQueue.main.async{UIApplication.shared.registerForRemoteNotifications()}case.notDetermined:UNUserNotificationCenter.current().requestAuthorization(options:[.badge,.alert,.sound]){(granted,error)inifgranted{DispatchQueue.main.async{UIApplication.shared.registerForRemoteNotifications()}}}default:break}_=LCApplication.default.currentInstallation}returnsuper.application(application,didFinishLaunchingWithOptions:launchOptions)}catch{fatalError("\(error)")}}overridefuncapplication(_application:UIApplication,didRegisterForRemoteNotificationsWithDeviceTokendeviceToken:Data){/setAPNsdeviceTokenandTeamID./LCApplication.default.currentInstallation.set(deviceToken:deviceToken,apnsTeamId:"你的TeamId")/savetoLeanCloud./LCApplication.default.currentInstallation.save{(result)inswitchresult{case.success:breakcase.failure(error:leterror):print(error)}}}overridefuncapplication(_application:UIApplication,didFailToRegisterForRemoteNotificationsWithErrorerror:Error){//如果注册推送失败,可以检查error信息print(error)}}
投诉举报、黑名单
在 APP Store 审核过程中,因为用户可以随意发送消息,被要求对用户生成的内容要有适当的预防措施。
要求提供下面这两条内容:
A mechanism for users to flag objectionable content用户标记不良信息的机制,就是举报功能。
A mechanism for users to block abusive users用户阻止滥用用户的机制,实际就是黑名单。
实现举报功能
我的解决办法是在消息处长按弹出举报窗口。
使用 LeanCloud 存储服务,新建一张 Report 表用于记录举报信息:
//保存一条举报信息LCObjectreport=LCObject('Report');report['clientID']=Global.clientID;//举报人report['messageID']=messageID;//消息IDreport['conversationID']=this.widget.conversation.id;//会话IDreport['content']=_selectedReportList.toString();//举报内容awaitreport.save();//保存举报信息
可以在控制台查看举报内容:
实现黑名单功能
我的解决办法是,在联系人列表处单击联系人弹框提示是否加入黑名单。
黑名单实现思路是新建一张 BlackList 表,来保存每个用户的黑名单列表,使用 LeanCloud 云函数 [12] 实现屏蔽消息。在 _messageReceived [13] 这个 Hook 函数下(这个 hook 发生在消息到达 LeanCloud 云端之后),先查此条消息的发件人与收件人是否在黑名单列表,如果在黑名单列表就删除其中要求屏蔽的收件人,返回新的收件人列表。
实现起来也比较简单,把下面这个云函数粘贴在 LeanCloud 控制台 > 云引擎 >云函数在线编辑框中即可。
步骤
先点击「创建函数」,然后选择 _messageReceived 类型,粘贴下面的代码,最后点击「部署」按钮。
等待部署完成,黑名单功能就已经实现成功,将不再收到加入黑名单用户的全部消息。
//下面这个函数粘贴在LeanCloud控制台AV.Cloud.define('_messageReceived',asyncfunction(request){letfromPeer=request.params.fromPeer;lettoPeersNew=request.params.toPeers;varquery=newAV.Query('BlackList');query.equalTo('blackedList',fromPeer);query.containedIn('clientID',toPeersNew);returnquery.find().then((results)=>{if(results.length>0){varclientID=results[0].get('clientID');varindex=toPeersNew.indexOf(clientID);if(index>-1){toPeersNew.splice(index,1);}return{toPeers:toPeersNew}}return{}});})
APP 项目地址
APP 项目完整代码见 Github-FlutterRealtimeDemo [14]
APP Store 下载链接 [15]
文档LeanCloud 即时通信插件链接 [16]LeanCloud 即时通信开发文档 [17]Flutter 文档 [18]相关链接涉及外链过多,大家可以 https://pan.baidu.com/s/1t8asMUlnSUhHOkyfAayhvQ 下载直达链接文档,提取码:ibr5
[14] APP 项目完整代码:
https://url.leanapp.cn/oGnoCyB
[15] 文中应用 APP Store 下载链接:
https://url.leanapp.cn/NnCNsJo
封面改自:Volodymyr Hryshchenko@Unsplash