====== 环信即时通讯 IM React-Native 快速入门 ====== 更新时间:2022-08-10 本文介绍如何极简集成环信即时通讯 React-Native SDK,在你的 app 中实现发送和接收单聊文本消息。 ===== 实现原理 ===== 下图展示在客户端发送和接收一对一文本消息的工作流程。 [[https://docs-im.easemob.com/_detail/ccim/web/sendandreceivemsg.png?id=ccim%3Aandroid%3Amessage2|{{https://docs-im.easemob.com/_media/ccim/web/sendandreceivemsg.png?w=800&tok=54ca33|img}}]] ===== 前提条件 ===== 集成前请确认 app 的开发和运行环境满足以下要求: 对于 iOS 平台: * MacOS 10.15.7 或以上版本 * Xcode 12.4 或以上版本,包括命令行工具 * React Native 0.63.4 或以上版本 * NodeJs 16 或以上版本,包含 npm 包管理工具 * CocoaPods 包管理工具 * Yarn 编译运行工具 * Watchman 调试工具 * 运行环境真机或模拟器 iOS 10.0 或以上版本 对于 Android 平台: * MacOS 10.15.7 或以上版本,Windows 10 或以上版本 * Android Studio 4.0 或以上版本,包括 JDK 1.8 或以上版本 * React Native 0.63.4 或以上版本 * 如果用 Macos 系统开发,需要 CocoaPods 包管理工具 * 如果用 Windows 开发,需要 Powershell 5.1 或以上版本 * NodeJs 16 或以上版本,包含 npm 包管理工具 * Yarn 编译运行工具 * Watchman 调试工具 * 运行环境真机或模拟器 Android 6.0 或以上版本 配置开发或者运行环境如果遇到问题,请参考 [[https://reactnative.dev/|RN 官网]]。 ==== 其他要求 ==== * 有效的环信即时通讯 IM 开发者账号和 App key,见 [[https://console.easemob.com/user/login|环信即时通讯云管理后台]]。 ===== 项目设置 ===== 创建一个 React Native 项目并将集成进去 - 根据开发系统和目标平台准备开发环境; - 打开终端,进入需要创建项目的目录,输入命令创建 React Native 项目: npx react-native init simple_demo cd simple_demo yarn 创建好的项目名称是 ''%%simple_demo%%''。
  1. 在终端命令行,输入以下命令添加依赖:

    yarn add react-native-chat-sdk
  2. 在目标平台执行脚本

Android: cd node_modules/react-native-chat-sdk/native_src/cpp && sh generate.sh --type rn && cd ../../../.. iOS: cd ios && pod install && cd .. ===== 实现发送和接收单聊消息 ===== 发送单聊消息前,终端用户需要先注册 Chat 账号,登录。 建议使用 ''%%visual studio code%%'' 打开文件夹 ''%%simple_demo%%'',打开文件 ''%%App.js%%'',删除全部内容,并添加如下内容: // 导入依赖库 import React, {useEffect} from 'react'; import { SafeAreaView, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native'; import { ChatClient, ChatOptions, ChatMessageChatType, ChatMessage, } from 'react-native-chat-sdk'; // 创建 app const App = () => { // 进行 app 设置 const title = 'ChatQuickstart'; const [appKey, setAppKey] = React.useState('easemob-demo#easeim'); const [username, setUsername] = React.useState('asterisk001'); const [password, setPassword] = React.useState('qwer'); const [userId, setUserId] = React.useState(''); const [content, setContent] = React.useState(''); const [logText, setWarnText] = React.useState('Show log area'); // 输出 console log 文件 useEffect(() => { logText.split('\n').forEach((value, index, array) => { if (index === 0) { console.log(value); } }); }, [logText]); // 输出 UI log 文件 const rollLog = text => { setWarnText(preLogText => { let newLogText = text; preLogText .split('\n') .filter((value, index, array) => { if (index > 8) { return false; } return true; }) .forEach((value, index, array) => { newLogText += '\n' + value; }); return newLogText; }); }; // 设置消息监听器。 const setMessageListener = () => { let msgListener = { onMessagesReceived(messages) { for (let index = 0; index < messages.length; index++) { rollLog('received msgId: ' + messages[index].msgId); } }, onCmdMessagesReceived: messages => {}, onMessagesRead: messages => {}, onGroupMessageRead: groupMessageAcks => {}, onMessagesDelivered: messages => {}, onMessagesRecalled: messages => {}, onConversationsUpdate: () => {}, onConversationRead: (from, to) => {}, }; ChatClient.getInstance().chatManager.removeAllMessageListener(); ChatClient.getInstance().chatManager.addMessageListener(msgListener); }; // SDK 初始化。 // 调用任何接口之前,请先进行初始化。 const init = () => { let o = new ChatOptions({ autoLogin: false, appKey: appKey, }); ChatClient.getInstance().removeAllConnectionListener(); ChatClient.getInstance() .init(o) .then(() => { rollLog('init success'); this.isInitialized = true; let listener = { onTokenWillExpire() { rollLog('token expire.'); }, onTokenDidExpire() { rollLog('token did expire'); }, onConnected() { rollLog('login success.'); setMessageListener(); }, onDisconnected(errorCode) { rollLog('login fail: ' + errorCode); }, }; ChatClient.getInstance().addConnectionListener(listener); }) .catch(error => { rollLog( 'init fail: ' + (error instanceof Object ? JSON.stringify(error) : error), ); }); }; // 注册账号。 const registerAccount = () => { if (this.isInitialized === false || this.isInitialized === undefined) { rollLog('Perform initialization first.'); return; } rollLog('start register account ...'); ChatClient.getInstance() .createAccount(username, password) .then(response => { rollLog(`register success: userName = ${username}, password = ******`); }) .catch(error => { rollLog('register fail: ' + JSON.stringify(error)); }); }; // 用环信即时通讯 IM 账号和密码登录。 const loginWithPassword = () => { if (this.isInitialized === false || this.isInitialized === undefined) { rollLog('Perform initialization first.'); return; } rollLog('start login ...'); ChatClient.getInstance() .login(username, password) .then(() => { rollLog('login operation success.'); }) .catch(reason => { rollLog('login fail: ' + JSON.stringify(reason)); }); }; // 登出。 const logout = () => { if (this.isInitialized === false || this.isInitialized === undefined) { rollLog('Perform initialization first.'); return; } rollLog('start logout ...'); ChatClient.getInstance() .logout() .then(() => { rollLog('logout success.'); }) .catch(reason => { rollLog('logout fail:' + JSON.stringify(reason)); }); }; // 发送一条文本消息。 const sendmsg = () => { if (this.isInitialized === false || this.isInitialized === undefined) { rollLog('Perform initialization first.'); return; } let msg = ChatMessage.createTextMessage( userId, content, ChatMessageChatType.PeerChat, ); const callback = new (class { onProgress(locaMsgId, progress) { rollLog(`send message process: ${locaMsgId}, ${progress}`); } onError(locaMsgId, error) { rollLog(`send message fail: ${locaMsgId}, ${JSON.stringify(error)}`); } onSuccess(message) { rollLog('send message success: ' + message.localMsgId); } })(); rollLog('start send message ...'); ChatClient.getInstance() .chatManager.sendMessage(msg, callback) .then(() => { rollLog('send message: ' + msg.localMsgId); }) .catch(reason => { rollLog('send fail: ' + JSON.stringify(reason)); }); }; // UI 组件渲染。 return ( {title} setAppKey(text)} value={appKey} /> INIT SDK setUsername(text)} value={username} /> setPassword(text)} value={password} /> SIGN UP SIGN IN SIGN OUT setUserId(text)} value={userId} /> setContent(text)} value={content} /> SEND TEXT {logText} {} {} ); }; // 设置 UI。 const styles = StyleSheet.create({ titleContainer: { height: 60, backgroundColor: '#6200ED', }, title: { lineHeight: 60, paddingLeft: 15, color: '#fff', fontSize: 20, fontWeight: '700', }, inputCon: { marginLeft: '5%', width: '90%', height: 60, paddingBottom: 6, borderBottomWidth: 1, borderBottomColor: '#ccc', }, inputBox: { marginTop: 15, width: '100%', fontSize: 14, fontWeight: 'bold', }, buttonCon: { marginLeft: '2%', width: '96%', flexDirection: 'row', marginTop: 20, height: 26, justifyContent: 'space-around', alignItems: 'center', }, eachBtn: { height: 40, width: '28%', lineHeight: 40, textAlign: 'center', color: '#fff', fontSize: 16, backgroundColor: '#6200ED', borderRadius: 5, }, btn2: { height: 40, width: '45%', lineHeight: 40, textAlign: 'center', color: '#fff', fontSize: 16, backgroundColor: '#6200ED', borderRadius: 5, }, logText: { padding: 10, marginTop: 10, color: '#ccc', fontSize: 14, lineHeight: 20, }, }); export default App; ==== 编译和运行项目 ==== 现在你可以开始在目标平台创建和运行项目。 编译并在 iOS 真机运行: - 连接苹果手机,设置为开发者模式; - 打开 ''%%simple_demo/ios%%'',使用 ''%%xcode%%'' 打开 ''%%simple_demo.xcworkspace%%''; - 依次点击 **Targets** > **simple_demo** > **Signing & Capabilities** 在签名选项下设置应用签名; - 点击 ''%%Build%%'' 构建并运行项目。程序构建完成后,自动安装和运行,并显示应用界面。 {{:ccim:rn:ios-1.png|}} 编译并在 iOS 模拟器中运行: - 打开 ''%%simple_demo/ios%%'',使用 ''%%xcode%%'' 打开 ''%%simple_demo.xcworkspace%%''; - 在 ''%%xcode%%'' 中,选择模拟器 ''%%iphone13%%''; - 点击 ''%%Build%%'' 构建并运行项目。程序构建完成后,自动安装和运行,并显示应用界面。 {{:ccim:rn:ios-2.png|}} 编译并在 Android 真机运行: - 在 Android Studio 中打开 ''%%simple_demo/android%%''; - 连接 Android 系统手机,设置为开发者模式,并且设置 USB 可调式; - 设置数据转发:在终端命令行输入 ''%%adb reverse tcp:8081 tcp:8081%%''; - 启动服务:执行 ''%%package.json%%'' 里面的命令:''%%"start": "react-native start"%%'',在终端中运行命令 ''%%yarn start%%'': yarn start - 程序构建完成后,自动安装和运行,并显示应用界面。 {{:ccim:rn:android-1.png|}} demo 的界面: {{:ccim:rn:main.png|}} ===== 测试你的 app ===== 参考以下代码测试注册账号,登录,发送和接收消息。 - 在真机或模拟器上输入用户名和密码,点击 **注册**。 - 点击 **登录**。 - 在另一台真机或模拟器上注册和登录一个新用户。 - 在第一台真机或模拟器上输入第二台上的用户名,编辑消息并点击 **发送**,在第二台机器上接收消息。 同时你可以在下方查看日志,检查注册,登录,发送消息是否成功。 ===== 更多操作 ===== 为了保证安全性,我们推荐使用 ''%%username + password + token%%'' 方式创建用户,token 在你的 app server 生成供客户端获取,当 token 过期时你需要重新获取。详见 [[https://docs-im.easemob.com/ccim/rest/accountsystem#获取用户_token|获取 user token]].