From 70f0582bf93f8ff8fb90b00a4b207340fe6e618c Mon Sep 17 00:00:00 2001 From: haoxiuwen Date: Sat, 28 Dec 2024 17:58:20 +0800 Subject: [PATCH 1/2] modify --- docs/document/android/demo.md | 82 - docs/document/android/easecallkit.md | 471 ---- docs/document/android/elite_sdk.md | 385 --- docs/document/android/overview.md | 260 -- docs/document/android/privatecloud.md | 35 - docs/document/applet/alipay.md | 101 - docs/document/applet/apidoc.md | 5 - docs/document/applet/baidu.md | 105 - docs/document/applet/bytedance.md | 102 - docs/document/applet/connection.md | 43 - docs/document/applet/conversation_delete.md | 6 - docs/document/applet/conversation_list.md | 6 - docs/document/applet/conversation_mark.md | 6 - docs/document/applet/conversation_overview.md | 6 - docs/document/applet/conversation_pin.md | 6 - docs/document/applet/conversation_receipt.md | 6 - docs/document/applet/error.md | 6 - docs/document/applet/group_attributes.md | 6 - docs/document/applet/group_manage.md | 6 - docs/document/applet/group_members.md | 6 - docs/document/applet/group_overview.md | 6 - docs/document/applet/initialization.md | 36 - docs/document/applet/log.md | 58 - docs/document/applet/login.md | 72 - docs/document/applet/message_delete.md | 6 - .../applet/message_deliver_only_online.md | 6 - docs/document/applet/message_modify.md | 6 - docs/document/applet/message_overview.md | 6 - docs/document/applet/message_pin.md | 6 - docs/document/applet/message_recall.md | 6 - docs/document/applet/message_receipt.md | 6 - docs/document/applet/message_retrieve.md | 6 - docs/document/applet/message_send_receive.md | 768 ------ docs/document/applet/message_translation.md | 6 - docs/document/applet/moderation.md | 6 - docs/document/applet/multi_device.md | 6 - docs/document/applet/overview.md | 37 - docs/document/applet/presence.md | 6 - docs/document/applet/push/push_extension.md | 6 - .../applet/push/push_notification_mode_dnd.md | 6 - docs/document/applet/push/push_overview.md | 44 - docs/document/applet/push/push_template.md | 6 - docs/document/applet/push/push_translation.md | 6 - docs/document/applet/push/uniapp_push.md | 169 -- docs/document/applet/qq.md | 109 - docs/document/applet/reaction.md | 6 - docs/document/applet/releasenote.md | 560 ----- docs/document/applet/room_attributes.md | 6 - docs/document/applet/room_manage.md | 6 - docs/document/applet/room_members.md | 6 - docs/document/applet/room_overview.md | 6 - docs/document/applet/serverconfig.md | 40 - docs/document/applet/thread.md | 6 - docs/document/applet/thread_message.md | 6 - docs/document/applet/uniapp.md | 151 -- docs/document/applet/uniappnativeapp.md | 105 - docs/document/applet/uniappuikit.md | 157 -- docs/document/applet/user_relationship.md | 6 - docs/document/applet/userprofile.md | 6 - docs/document/applet/wechat.md | 126 - docs/document/flutter/overview.md | 152 -- docs/document/harmonyos/overview.md | 208 -- docs/document/server-side/java_server_sdk.md | 436 ---- .../server-side/java_server_sdk_2.0.md | 289 --- docs/document/server-side/php_server_sdk.md | 150 -- docs/private/README.md | 3 - docs/private/im/README.md | 3 - docs/private/im/uc_Web_private.md | 67 - docs/private/im/uc_android_private.md | 35 - docs/private/im/uc_configure.md | 134 - docs/private/im/uc_deploy.md | 120 - docs/private/im/uc_iOS_private.md | 34 - docs/private/im/uc_lowcode.md | 97 - docs/private/im/uc_overview.md | 86 - docs/private/im/uc_private.md | 256 -- docs/private/media/README.md | 3 - docs/private/media/common_clientsdk.md | 73 - docs/private/media/common_error_code.md | 165 -- docs/private/media/common_faq.md | 112 - docs/private/media/common_introduction.md | 77 - docs/private/media/conference_android.md | 2097 ---------------- docs/private/media/conference_introduction.md | 213 -- docs/private/media/conference_ios.md | 1618 ------------ docs/private/media/conference_pcdesktop.md | 15 - docs/private/media/conference_uniapp.md | 485 ---- docs/private/media/conference_vxmini.md | 404 --- docs/private/media/conference_web.md | 1164 --------- docs/private/media/one2one_android.md | 698 ------ docs/private/media/one2one_introduction.md | 44 - docs/private/media/one2one_ios.md | 694 ------ docs/private/media/one2one_pcdesktop.md | 187 -- docs/private/media/one2one_vxmini.md | 17 - docs/private/media/one2one_web.md | 365 --- docs/private/media/overview.md | 3 - docs/private/media/rest_introduction.md | 6 - docs/private/media/rest_manage.md | 247 -- docs/private/media/rest_record.md | 305 --- docs/private/media/rest_whiteboard.md | 89 - docs/private/media/scenario_live.md | 84 - docs/private/media/scenario_meeting.md | 119 - docs/private/media/scenario_one2one.md | 44 - docs/private/media/scenario_tc-host.md | 33 - docs/private/media/scenario_tc-robmic.md | 34 - docs/private/media/scenario_tc-scene.md | 58 - docs/private/media/scenario_tc.md | 176 -- docs/private/media/whiteboard_android.md | 86 - docs/private/media/whiteboard_introduction.md | 90 - docs/private/media/whiteboard_ios.md | 127 - docs/private/media/whiteboard_pcdesktop.md | 5 - docs/private/media/whiteboard_vxmini.md | 5 - docs/private/media/whiteboard_web.md | 179 -- docs/product/GDPR.md | 93 - docs/product/README.md | 3 - docs/product/aigc/aigc_rest_api.md | 199 -- .../aigc/aigc_run_through_demo_client.md | 41 - .../aigc/aigc_run_through_demo_server.md | 290 --- .../aigc/aigc_scenario_introduction.md | 62 - docs/product/aigc/aigc_selection.md | 49 - docs/product/aigc/aigc_use.md | 80 - docs/product/circle/api_reference_android.md | 7 - docs/product/circle/api_reference_ios.md | 5 - docs/product/circle/api_reference_web.md | 5 - docs/product/circle/category_mgmt_android.md | 173 -- docs/product/circle/category_mgmt_ios.md | 121 - docs/product/circle/category_mgmt_rest.md | 699 ------ docs/product/circle/category_mgmt_web.md | 133 - docs/product/circle/channel_mgmt_android.md | 589 ----- docs/product/circle/channel_mgmt_ios.md | 397 --- docs/product/circle/channel_mgmt_rest.md | 2171 ----------------- docs/product/circle/channel_mgmt_web.md | 460 ---- .../circle/circle_errorcode_android.md | 13 - docs/product/circle/circle_errorcode_ios.md | 13 - docs/product/circle/circle_errorcode_web.md | 3 - docs/product/circle/circle_overview.md | 200 -- .../circle/circle_quickstart_android.md | 230 -- docs/product/circle/circle_quickstart_ios.md | 182 -- docs/product/circle/circle_quickstart_web.md | 178 -- docs/product/circle/server_mgmt_android.md | 550 ----- docs/product/circle/server_mgmt_ios.md | 346 --- docs/product/circle/server_mgmt_rest.md | 1354 ---------- docs/product/circle/server_mgmt_web.md | 393 --- docs/product/data_center.md | 121 - docs/product/demo_sourcecode_address.md | 37 - docs/product/easemob_app_token.md | 94 - docs/product/easemob_user_token.md | 238 -- docs/product/enable_and_configure_IM.md | 488 ---- docs/product/faq_integration_issues.md | 53 - docs/product/faq_quality_issues.md | 93 - docs/product/glossary.md | 205 -- docs/product/help.md | 31 - docs/product/introduction.md | 198 -- docs/product/limitation.md | 252 -- docs/product/limitationapi.md | 274 --- docs/product/message_statistics.md | 133 - docs/product/moderation/keyword_review.md | 133 - .../product/moderation/moderation_add_word.md | 10 - .../moderation/moderation_billing_domestic.md | 172 -- .../moderation/moderation_billing_overseas.md | 178 -- docs/product/moderation/moderation_enable.md | 37 - .../moderation/moderation_enable_03.png | Bin 84623 -> 0 bytes docs/product/moderation/moderation_history.md | 49 - .../moderation/moderation_manual_review.md | 25 - .../moderation/moderation_mechanism.md | 117 - .../product/moderation/moderation_overview.md | 54 - .../moderation/moderation_record_callback.md | 63 - .../moderation/moderation_replace_refuse.md | 3 - .../moderation/moderation_rule_config.md | 77 - .../moderation/moderation_rule_test.md | 36 - .../moderation/moderation_use_console.md | 12 - .../product/moderation/moderation_usermgmt.md | 93 - docs/product/pricing.md | 241 -- docs/product/product_chatroom_overview.md | 70 - docs/product/product_dynamics.md | 75 - docs/product/product_group_overview.md | 123 - docs/product/product_message_format.md | 401 --- docs/product/product_message_overview.md | 146 -- docs/product/product_offline_push_overview.md | 120 - docs/product/product_thread_overview.md | 39 - docs/product/product_user_attribute.md | 26 - docs/product/product_user_presence.md | 92 - .../product_user_registration_login.md | 43 - docs/product/product_user_relationship.md | 83 - docs/product/request_quality_overview.md | 98 - docs/product/security_best_practices.md | 45 - docs/product/solution_common/group_@.md | 268 -- docs/product/solution_common/message_quote.md | 361 --- .../solution_common/migrate_to_easemob.md | 119 - .../solution_common/typing_indication.md | 393 --- docs/product/uc_deploy.md | 109 - docs/product/uc_overview.md | 87 - docs/product/uc_private.md | 255 -- .../client_implementation_android.md | 307 --- .../voiceroom/client_implementation_ios.md | 276 --- docs/product/voiceroom/demo_experience.md | 19 - .../voiceroom/demo_scenario_introduction.md | 63 - .../voiceroom/run_through_demo_android.md | 33 - .../product/voiceroom/run_through_demo_ios.md | 39 - docs/push/README.md | 3 - docs/push/push_androidchannel_restriction.md | 91 - .../push_androidvendor_msgclassification.md | 285 --- docs/push/push_androidvendor_statistics.md | 180 -- docs/push/push_api_call_limitation.md | 28 - docs/push/push_apns_deliver_statistics.md | 99 - docs/push/push_billing.md | 283 --- docs/push/push_by_tag.md | 617 ----- docs/push/push_certificate_config.md | 17 - docs/push/push_createnotification.md | 70 - docs/push/push_createproduct_app.md | 58 - docs/push/push_dynamics.md | 52 - docs/push/push_dynamics_android.md | 7 - docs/push/push_dynamics_ios.md | 7 - docs/push/push_global_deployment.md | 15 - docs/push/push_integration_note_android.md | 60 - docs/push/push_integration_note_ios.md | 256 -- docs/push/push_integration_process_android.md | 141 -- docs/push/push_integration_process_ios.md | 125 - docs/push/push_notification_config.md | 711 ------ docs/push/push_overview.md | 50 - docs/push/push_send_notification.md | 503 ---- docs/push/push_statistics.md | 22 - docs/push/push_tag_mgmt.md | 37 - docs/push/push_task.md | 19 - docs/uikit/chatroomuikit/README.md | 3 - .../chatroomuikit/android/design_guide.md | 705 ------ .../android/roomfeature_common.md | 111 - .../android/roomfeature_member.md | 41 - .../android/roomfeature_message.md | 41 - .../android/roomuikit_best_practice.md | 68 - .../android/roomuikit_config_item.md | 29 - .../android/roomuikit_integrated.md | 33 - .../android/roomuikit_overview.md | 44 - .../android/roomuikit_quickstart.md | 101 - .../android/roomuikit_releasenote.md | 31 - .../chatroomuikit/android/roomuikit_run.md | 91 - .../chatroomuikit/android/roomuikit_theme.md | 38 - .../chatroomuikit/flutter/design_guide.md | 6 - .../flutter/roomfeature_common.md | 6 - .../flutter/roomfeature_member.md | 6 - .../flutter/roomfeature_message.md | 6 - .../flutter/roomuikit_best_practice.md | 149 -- .../flutter/roomuikit_config_item.md | 358 --- .../flutter/roomuikit_integrated.md | 31 - .../flutter/roomuikit_overview.md | 34 - .../flutter/roomuikit_quickstart.md | 173 -- .../flutter/roomuikit_releasenote.md | 31 - .../chatroomuikit/flutter/roomuikit_run.md | 39 - .../chatroomuikit/flutter/roomuikit_theme.md | 48 - docs/uikit/chatroomuikit/ios/README.md | 3 - docs/uikit/chatroomuikit/ios/design_guide.md | 6 - .../chatroomuikit/ios/roomfeature_common.md | 6 - .../chatroomuikit/ios/roomfeature_member.md | 6 - .../chatroomuikit/ios/roomfeature_message.md | 6 - .../ios/roomuikit_best_practice.md | 76 - .../ios/roomuikit_config_item.md | 77 - .../chatroomuikit/ios/roomuikit_customize.md | 63 - .../chatroomuikit/ios/roomuikit_integrated.md | 44 - .../chatroomuikit/ios/roomuikit_overview.md | 34 - .../chatroomuikit/ios/roomuikit_quickstart.md | 89 - .../ios/roomuikit_releasenote.md | 31 - docs/uikit/chatroomuikit/ios/roomuikit_run.md | 65 - .../chatroomuikit/ios/roomuikit_theme.md | 76 - .../react-native/design_guide.md | 6 - .../react-native/roomfeature_common.md | 6 - .../react-native/roomfeature_member.md | 6 - .../react-native/roomfeature_message.md | 6 - .../react-native/roomuikit_best_practice.md | 126 - .../react-native/roomuikit_config_item.md | 565 ----- .../react-native/roomuikit_customize.md | 123 - .../react-native/roomuikit_integrated.md | 34 - .../react-native/roomuikit_overview.md | 35 - .../react-native/roomuikit_quickstart.md | 121 - .../react-native/roomuikit_releasenote.md | 31 - .../react-native/roomuikit_run.md | 63 - .../react-native/roomuikit_theme.md | 58 - docs/uikit/chatroomuikit/web/design_guide.md | 6 - .../chatroomuikit/web/roomfeature_common.md | 6 - .../chatroomuikit/web/roomfeature_member.md | 6 - .../chatroomuikit/web/roomfeature_message.md | 6 - .../web/roomuikit_best_practice.md | 124 - .../web/roomuikit_config_item.md | 71 - .../chatroomuikit/web/roomuikit_customize.md | 128 - .../chatroomuikit/web/roomuikit_integrated.md | 55 - .../chatroomuikit/web/roomuikit_overview.md | 34 - .../chatroomuikit/web/roomuikit_quickstart.md | 166 -- .../web/roomuikit_releasenote.md | 31 - docs/uikit/chatroomuikit/web/roomuikit_run.md | 31 - .../chatroomuikit/web/roomuikit_storybook.md | 5 - .../chatroomuikit/web/roomuikit_theme.md | 42 - 288 files changed, 41106 deletions(-) delete mode 100644 docs/document/android/demo.md delete mode 100644 docs/document/android/easecallkit.md delete mode 100644 docs/document/android/elite_sdk.md delete mode 100644 docs/document/android/overview.md delete mode 100644 docs/document/android/privatecloud.md delete mode 100644 docs/document/applet/alipay.md delete mode 100644 docs/document/applet/apidoc.md delete mode 100644 docs/document/applet/baidu.md delete mode 100644 docs/document/applet/bytedance.md delete mode 100644 docs/document/applet/connection.md delete mode 100644 docs/document/applet/conversation_delete.md delete mode 100644 docs/document/applet/conversation_list.md delete mode 100644 docs/document/applet/conversation_mark.md delete mode 100644 docs/document/applet/conversation_overview.md delete mode 100644 docs/document/applet/conversation_pin.md delete mode 100644 docs/document/applet/conversation_receipt.md delete mode 100644 docs/document/applet/error.md delete mode 100644 docs/document/applet/group_attributes.md delete mode 100644 docs/document/applet/group_manage.md delete mode 100644 docs/document/applet/group_members.md delete mode 100644 docs/document/applet/group_overview.md delete mode 100644 docs/document/applet/initialization.md delete mode 100644 docs/document/applet/log.md delete mode 100644 docs/document/applet/login.md delete mode 100644 docs/document/applet/message_delete.md delete mode 100644 docs/document/applet/message_deliver_only_online.md delete mode 100644 docs/document/applet/message_modify.md delete mode 100644 docs/document/applet/message_overview.md delete mode 100644 docs/document/applet/message_pin.md delete mode 100644 docs/document/applet/message_recall.md delete mode 100644 docs/document/applet/message_receipt.md delete mode 100644 docs/document/applet/message_retrieve.md delete mode 100644 docs/document/applet/message_send_receive.md delete mode 100644 docs/document/applet/message_translation.md delete mode 100644 docs/document/applet/moderation.md delete mode 100644 docs/document/applet/multi_device.md delete mode 100644 docs/document/applet/overview.md delete mode 100644 docs/document/applet/presence.md delete mode 100644 docs/document/applet/push/push_extension.md delete mode 100644 docs/document/applet/push/push_notification_mode_dnd.md delete mode 100644 docs/document/applet/push/push_overview.md delete mode 100644 docs/document/applet/push/push_template.md delete mode 100644 docs/document/applet/push/push_translation.md delete mode 100644 docs/document/applet/push/uniapp_push.md delete mode 100644 docs/document/applet/qq.md delete mode 100644 docs/document/applet/reaction.md delete mode 100644 docs/document/applet/releasenote.md delete mode 100644 docs/document/applet/room_attributes.md delete mode 100644 docs/document/applet/room_manage.md delete mode 100644 docs/document/applet/room_members.md delete mode 100644 docs/document/applet/room_overview.md delete mode 100644 docs/document/applet/serverconfig.md delete mode 100644 docs/document/applet/thread.md delete mode 100644 docs/document/applet/thread_message.md delete mode 100644 docs/document/applet/uniapp.md delete mode 100644 docs/document/applet/uniappnativeapp.md delete mode 100644 docs/document/applet/uniappuikit.md delete mode 100644 docs/document/applet/user_relationship.md delete mode 100644 docs/document/applet/userprofile.md delete mode 100644 docs/document/applet/wechat.md delete mode 100644 docs/document/flutter/overview.md delete mode 100644 docs/document/harmonyos/overview.md delete mode 100644 docs/document/server-side/java_server_sdk.md delete mode 100644 docs/document/server-side/java_server_sdk_2.0.md delete mode 100644 docs/document/server-side/php_server_sdk.md delete mode 100644 docs/private/README.md delete mode 100644 docs/private/im/README.md delete mode 100644 docs/private/im/uc_Web_private.md delete mode 100644 docs/private/im/uc_android_private.md delete mode 100644 docs/private/im/uc_configure.md delete mode 100644 docs/private/im/uc_deploy.md delete mode 100644 docs/private/im/uc_iOS_private.md delete mode 100644 docs/private/im/uc_lowcode.md delete mode 100644 docs/private/im/uc_overview.md delete mode 100644 docs/private/im/uc_private.md delete mode 100644 docs/private/media/README.md delete mode 100644 docs/private/media/common_clientsdk.md delete mode 100644 docs/private/media/common_error_code.md delete mode 100644 docs/private/media/common_faq.md delete mode 100644 docs/private/media/common_introduction.md delete mode 100644 docs/private/media/conference_android.md delete mode 100644 docs/private/media/conference_introduction.md delete mode 100644 docs/private/media/conference_ios.md delete mode 100644 docs/private/media/conference_pcdesktop.md delete mode 100644 docs/private/media/conference_uniapp.md delete mode 100644 docs/private/media/conference_vxmini.md delete mode 100644 docs/private/media/conference_web.md delete mode 100644 docs/private/media/one2one_android.md delete mode 100644 docs/private/media/one2one_introduction.md delete mode 100644 docs/private/media/one2one_ios.md delete mode 100644 docs/private/media/one2one_pcdesktop.md delete mode 100644 docs/private/media/one2one_vxmini.md delete mode 100644 docs/private/media/one2one_web.md delete mode 100644 docs/private/media/overview.md delete mode 100644 docs/private/media/rest_introduction.md delete mode 100644 docs/private/media/rest_manage.md delete mode 100644 docs/private/media/rest_record.md delete mode 100644 docs/private/media/rest_whiteboard.md delete mode 100644 docs/private/media/scenario_live.md delete mode 100644 docs/private/media/scenario_meeting.md delete mode 100644 docs/private/media/scenario_one2one.md delete mode 100644 docs/private/media/scenario_tc-host.md delete mode 100644 docs/private/media/scenario_tc-robmic.md delete mode 100644 docs/private/media/scenario_tc-scene.md delete mode 100644 docs/private/media/scenario_tc.md delete mode 100644 docs/private/media/whiteboard_android.md delete mode 100644 docs/private/media/whiteboard_introduction.md delete mode 100644 docs/private/media/whiteboard_ios.md delete mode 100644 docs/private/media/whiteboard_pcdesktop.md delete mode 100644 docs/private/media/whiteboard_vxmini.md delete mode 100644 docs/private/media/whiteboard_web.md delete mode 100644 docs/product/GDPR.md delete mode 100644 docs/product/README.md delete mode 100644 docs/product/aigc/aigc_rest_api.md delete mode 100644 docs/product/aigc/aigc_run_through_demo_client.md delete mode 100644 docs/product/aigc/aigc_run_through_demo_server.md delete mode 100644 docs/product/aigc/aigc_scenario_introduction.md delete mode 100644 docs/product/aigc/aigc_selection.md delete mode 100644 docs/product/aigc/aigc_use.md delete mode 100644 docs/product/circle/api_reference_android.md delete mode 100644 docs/product/circle/api_reference_ios.md delete mode 100644 docs/product/circle/api_reference_web.md delete mode 100644 docs/product/circle/category_mgmt_android.md delete mode 100644 docs/product/circle/category_mgmt_ios.md delete mode 100644 docs/product/circle/category_mgmt_rest.md delete mode 100644 docs/product/circle/category_mgmt_web.md delete mode 100644 docs/product/circle/channel_mgmt_android.md delete mode 100644 docs/product/circle/channel_mgmt_ios.md delete mode 100644 docs/product/circle/channel_mgmt_rest.md delete mode 100644 docs/product/circle/channel_mgmt_web.md delete mode 100644 docs/product/circle/circle_errorcode_android.md delete mode 100644 docs/product/circle/circle_errorcode_ios.md delete mode 100644 docs/product/circle/circle_errorcode_web.md delete mode 100644 docs/product/circle/circle_overview.md delete mode 100644 docs/product/circle/circle_quickstart_android.md delete mode 100644 docs/product/circle/circle_quickstart_ios.md delete mode 100644 docs/product/circle/circle_quickstart_web.md delete mode 100644 docs/product/circle/server_mgmt_android.md delete mode 100644 docs/product/circle/server_mgmt_ios.md delete mode 100644 docs/product/circle/server_mgmt_rest.md delete mode 100644 docs/product/circle/server_mgmt_web.md delete mode 100644 docs/product/data_center.md delete mode 100644 docs/product/demo_sourcecode_address.md delete mode 100644 docs/product/easemob_app_token.md delete mode 100644 docs/product/easemob_user_token.md delete mode 100644 docs/product/enable_and_configure_IM.md delete mode 100644 docs/product/faq_integration_issues.md delete mode 100644 docs/product/faq_quality_issues.md delete mode 100644 docs/product/glossary.md delete mode 100644 docs/product/help.md delete mode 100644 docs/product/introduction.md delete mode 100644 docs/product/limitation.md delete mode 100644 docs/product/limitationapi.md delete mode 100644 docs/product/message_statistics.md delete mode 100644 docs/product/moderation/keyword_review.md delete mode 100644 docs/product/moderation/moderation_add_word.md delete mode 100644 docs/product/moderation/moderation_billing_domestic.md delete mode 100644 docs/product/moderation/moderation_billing_overseas.md delete mode 100644 docs/product/moderation/moderation_enable.md delete mode 100644 docs/product/moderation/moderation_enable_03.png delete mode 100644 docs/product/moderation/moderation_history.md delete mode 100644 docs/product/moderation/moderation_manual_review.md delete mode 100644 docs/product/moderation/moderation_mechanism.md delete mode 100644 docs/product/moderation/moderation_overview.md delete mode 100644 docs/product/moderation/moderation_record_callback.md delete mode 100644 docs/product/moderation/moderation_replace_refuse.md delete mode 100644 docs/product/moderation/moderation_rule_config.md delete mode 100644 docs/product/moderation/moderation_rule_test.md delete mode 100644 docs/product/moderation/moderation_use_console.md delete mode 100644 docs/product/moderation/moderation_usermgmt.md delete mode 100644 docs/product/pricing.md delete mode 100644 docs/product/product_chatroom_overview.md delete mode 100644 docs/product/product_dynamics.md delete mode 100644 docs/product/product_group_overview.md delete mode 100644 docs/product/product_message_format.md delete mode 100644 docs/product/product_message_overview.md delete mode 100644 docs/product/product_offline_push_overview.md delete mode 100644 docs/product/product_thread_overview.md delete mode 100644 docs/product/product_user_attribute.md delete mode 100644 docs/product/product_user_presence.md delete mode 100644 docs/product/product_user_registration_login.md delete mode 100644 docs/product/product_user_relationship.md delete mode 100644 docs/product/request_quality_overview.md delete mode 100644 docs/product/security_best_practices.md delete mode 100644 docs/product/solution_common/group_@.md delete mode 100644 docs/product/solution_common/message_quote.md delete mode 100644 docs/product/solution_common/migrate_to_easemob.md delete mode 100644 docs/product/solution_common/typing_indication.md delete mode 100644 docs/product/uc_deploy.md delete mode 100644 docs/product/uc_overview.md delete mode 100644 docs/product/uc_private.md delete mode 100644 docs/product/voiceroom/client_implementation_android.md delete mode 100644 docs/product/voiceroom/client_implementation_ios.md delete mode 100644 docs/product/voiceroom/demo_experience.md delete mode 100644 docs/product/voiceroom/demo_scenario_introduction.md delete mode 100644 docs/product/voiceroom/run_through_demo_android.md delete mode 100644 docs/product/voiceroom/run_through_demo_ios.md delete mode 100644 docs/push/README.md delete mode 100644 docs/push/push_androidchannel_restriction.md delete mode 100644 docs/push/push_androidvendor_msgclassification.md delete mode 100644 docs/push/push_androidvendor_statistics.md delete mode 100644 docs/push/push_api_call_limitation.md delete mode 100644 docs/push/push_apns_deliver_statistics.md delete mode 100644 docs/push/push_billing.md delete mode 100644 docs/push/push_by_tag.md delete mode 100644 docs/push/push_certificate_config.md delete mode 100644 docs/push/push_createnotification.md delete mode 100644 docs/push/push_createproduct_app.md delete mode 100644 docs/push/push_dynamics.md delete mode 100644 docs/push/push_dynamics_android.md delete mode 100644 docs/push/push_dynamics_ios.md delete mode 100644 docs/push/push_global_deployment.md delete mode 100644 docs/push/push_integration_note_android.md delete mode 100644 docs/push/push_integration_note_ios.md delete mode 100644 docs/push/push_integration_process_android.md delete mode 100644 docs/push/push_integration_process_ios.md delete mode 100644 docs/push/push_notification_config.md delete mode 100644 docs/push/push_overview.md delete mode 100644 docs/push/push_send_notification.md delete mode 100644 docs/push/push_statistics.md delete mode 100644 docs/push/push_tag_mgmt.md delete mode 100644 docs/push/push_task.md delete mode 100644 docs/uikit/chatroomuikit/README.md delete mode 100644 docs/uikit/chatroomuikit/android/design_guide.md delete mode 100644 docs/uikit/chatroomuikit/android/roomfeature_common.md delete mode 100644 docs/uikit/chatroomuikit/android/roomfeature_member.md delete mode 100644 docs/uikit/chatroomuikit/android/roomfeature_message.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_best_practice.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_config_item.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_integrated.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_overview.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_quickstart.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_releasenote.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_run.md delete mode 100644 docs/uikit/chatroomuikit/android/roomuikit_theme.md delete mode 100644 docs/uikit/chatroomuikit/flutter/design_guide.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomfeature_common.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomfeature_member.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomfeature_message.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_best_practice.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_config_item.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_integrated.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_overview.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_quickstart.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_releasenote.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_run.md delete mode 100644 docs/uikit/chatroomuikit/flutter/roomuikit_theme.md delete mode 100644 docs/uikit/chatroomuikit/ios/README.md delete mode 100644 docs/uikit/chatroomuikit/ios/design_guide.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomfeature_common.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomfeature_member.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomfeature_message.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_best_practice.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_config_item.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_customize.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_integrated.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_overview.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_quickstart.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_releasenote.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_run.md delete mode 100644 docs/uikit/chatroomuikit/ios/roomuikit_theme.md delete mode 100644 docs/uikit/chatroomuikit/react-native/design_guide.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomfeature_common.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomfeature_member.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomfeature_message.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_best_practice.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_config_item.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_customize.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_integrated.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_overview.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_quickstart.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_releasenote.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_run.md delete mode 100644 docs/uikit/chatroomuikit/react-native/roomuikit_theme.md delete mode 100644 docs/uikit/chatroomuikit/web/design_guide.md delete mode 100644 docs/uikit/chatroomuikit/web/roomfeature_common.md delete mode 100644 docs/uikit/chatroomuikit/web/roomfeature_member.md delete mode 100644 docs/uikit/chatroomuikit/web/roomfeature_message.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_best_practice.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_config_item.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_customize.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_integrated.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_overview.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_quickstart.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_releasenote.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_run.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_storybook.md delete mode 100644 docs/uikit/chatroomuikit/web/roomuikit_theme.md diff --git a/docs/document/android/demo.md b/docs/document/android/demo.md deleted file mode 100644 index c4f44904..00000000 --- a/docs/document/android/demo.md +++ /dev/null @@ -1,82 +0,0 @@ -# Demo(EaseIM App)介绍 - - - -环信即时通讯 IM Android 端提供示例应用可供体验。 - -1. [下载 Demo](https://www.easemob.com/download/demo)。 - -2. 输入你的手机号,获取验证码,然后输入。 - -3. 选择同意《环信服务条款》与《环信隐私协议》,然后点击 **登录** 登录 Demo。 - -![img](/images/demo/android_login.png) - -## 代码下载 - -您可以通过以下两种方式获取到源代码: -- 下载代码压缩包:[IM SDK 及 Demo 下载](https://www.easemob.com/download/im) -- 下载源代码:[GitHub 源码地址](https://github.com/easemob/easemob-demo-android) - - 4.5.0 及之前版本的 Demo 为 Java 语言。点击[这里](https://github.com/easemob/chat-android)查看 Demo 源码地址。环信已不再维护该地址的 Demo 源码。 - - 4.6.0 及之后版本的 Demo 为 Kotlin 语言。点击[这里](https://github.com/easemob/easemob-demo-android)查看 Demo 源码地址。 - -## 导入 EaseIM - -从 [IM SDK 及 Demo 下载](https://www.easemob.com/download/im) 下载 Android SDK 压缩包,然后解压。解压后在 `examples` 文件夹下,即为 EaseIM 的工程目录。 - -### 导入到 Android Studio - -打开 Android Studio,点击 `File > Open`,打开 `examples/EaseIm3.0` 根目录即可。 - -## 使用的第三方库 - -| 第三方库 | 描述 | -| :------------------- | :------------- | -| `androidx.core:core-ktx:1.10.1` | Kotlin 库。 | -| `org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3` | Kotlin 协程库。 | -| `org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3` | Kotlin 协程库。 | -| `androidx.appcompat:appcompat` | `appcompat` 库,对应以前的 `appcompat-v7` 库。 | -| `com.google.android.material:material:material` | 对应以前的 design 库。如果用到 TabLayout、CardView 等 Material Design 控件时需要添加。 | -| `androidx.constraintlayout:constraintlayout` | constraintlayout 布局。 | -| `androidx.lifecycle:lifecycle-runtime-ktx` | lifecycle 库。 | -| `androidx.lifecycle:lifecycle-viewmodel-ktx` | ViewModel 和 lifecycle 库。 | -| `com.android.support:multidex` | 工程总方法数超过 64 KB 时,需要用这个库做分包处理。 | -| `play-services-base和firebase-messaging` | 谷歌推送所需要的库,使用 FCM 推送时需要添加。 | -| `com.scwang.smartrefresh:SmartRefreshLayout` | 下拉刷新及上拉加载更多库。 | -| `androidx.swiperefreshlayout:swiperefreshlayout` | 下拉刷新库。| -| `androidx.room` | Android 数据库。 | -| `com.huawei.hms:push` | 华为推送所需要的库。 | -| `com.meizu.flyme.internet:push-internal` | 魅族推送所需要的库。 | -| `vivo_push_v4.0.4.0_504.aar` | vivo 推送所需要的库。 | -| `oppo_push_3.5.2.aar` | OPPO 推送所需要的库。 | -| `MiPush_SDK_Client_6_0_1-C_3rd.aar` | 小米推送所需要的库。 | -| `com.hihonor.mcs:push` | 7.0.61.303 荣耀推送所需要的库。 | - -## 主要模块介绍 - -| 模块 | 描述 | -| :------------------- | :----- | -| 聊天模块 | 展示如何依赖 EaseIMKit 实现聊天列表,如何扩展消息类型及如何增加扩展菜单等的逻辑。 | -| 会话列表模块 | 展示如何依赖 EaseIMKit 实现会话列表的逻辑及实现系统消息的具体逻辑。 | -| 联系人模块 | 展示如何依赖 EaseIMKit 实现联系人列表的逻辑。 | -| 聊天设置模块 | 展示 IM SDK 提供的对于群聊及聊天室的对成员及群组属性的操作。 | -| 设置模块 | 展示 IM SDK 对于新消息的设置及消息免打扰,群组等通用设置。 | -| 开发者模块 | 展示 IM SDK 提供的一些常规的开发者可以设置的功能。 | - -## 主要类介绍 - -| 模块 | 描述 | -| :------------------- | :----- | -| DemoHelper | 环信(EaseIM)全局帮助类,主要功能为初始化 IM SDK,初始化 EaseIMKit 相关及注册对话类型等。 | -| ConversationListFragment | 继承自 EaseIMKit 中的 `ChatUIKitConversationListFragment`,展示扩展条目长按事件,在列表前端添加布局及条目点击事件实现等 | -| ChatActivity及ChatFragment | ChatFragment 继承自 EaseIMKit 中的 UIKitChatFragment,展示了扩展条目长按事件,预置条目长按菜单及对重写部分长按事件功能,展示了如何重置及添加更多扩展功能,并展示了实现了头像点击事件及正在输入等事件的相应。 | -| ChatContactListFragment | 继承自 EaseIMKit 中的 ChatUIKitContactsListFragment,展示了添加头布局,添加条目长按功能及实现条目点击事件等 | -| ChatGroupDetailActivity | 实现了如下功能:添加群成员,修改群公告及群介绍,上传共享文件,进行群组管理,设置消息免打扰及解散或者退出群组等。 | - -## 部分 UI 展示 - - - - - - diff --git a/docs/document/android/easecallkit.md b/docs/document/android/easecallkit.md deleted file mode 100644 index 31fb46f5..00000000 --- a/docs/document/android/easecallkit.md +++ /dev/null @@ -1,471 +0,0 @@ -# EaseCallKit 使用指南 - - - -## 功能概述 - -`EaseCallKit` 是一套基于环信 IM 和声网音视频结合开发的音视频 UI 库,实现了一对一语音和视频通话以及多人音视频通话的功能。基于 `EaseCallKit` 可以快速实现通用音视频功能。 - -**利用 `EaseCallKit` 通话过程中,使用环信 ID 加入频道,方便音视频视图中显示用户名。如果用户不使用 `EaseCallKit` 而直接调用声网 API,也可以直接使用数字 UID 加入频道。** - -:::tip -本 UI 库只和移动端 3.8.0 及以上版本 Demo 互通。3.8.1 的 UI 库使用声网数字 uid 加入频道,而 3.8.0 使用字符串加入频道,3.8.1 版本不与 3.8.0 互通,Demo 中 EaseCallKit 使用的 token 和 UID 均由你自己生成。若你需要使用声网对应的音视频服务,需单独在声网申请。 -::: - -## 跑通 Demo - -EaseCallKit 集成在环信开源 IM Demo 中,你可以通过进入 [环信 Demo 及源码](https://www.easemob.com/download/im) 下载页面,选择 Android 端进行下载,直接下载: [Android IM 源码](https://github.com/easemob/chat-android)。 - -环境准备: - -- Android Studio 3.5 及以上版本; -- Gradle 4.6 及以上版本; -- targetSdkVersion 29; -- minSdkVersion 19; -- Java JDK 1.8 及以上版本。 - -运行 Demo: - -- 下载源码后,用 Android Studio 打开项目,连接手机,然后运行。 - -## 准备条件 - -集成该库之前,你需要满足以下条件: - -- 分别创建 [环信应用](/product/enable_and_configure_IM.html) 及 [声网应用](https://doc.shengwang.cn/doc/rtc/android/get-started/enable-service#创建声网项目); -- 已完成环信 IM 的基本功能,包括登录、好友、群组以及会话等的集成; -- 上线之前开通声网 Token 验证时,用户需要实现自己的 [App Server](https://github.com/easemob/easemob-im-app-server/tree/master/agora-app-server),用于生成 Token。具体请参见 [创建 Token 服务及使用 App Server 生成 Token](https://doc.shengwang.cn/doc/rtc/android/basic-features/token-authentication)。 - -## 快速集成 - -使用 `EaseCallKit` 库完成音视频通话的基本流程如下: - -1. `EaseCallKit` 库进行初始化并设置 `EaseCallKit` 监听; -2. 主叫方调用发起通话邀请接口,进入通话界面; -3. 被叫方收到邀请自动弹出通话邀请界面,在通话邀请界面选择接通或者拒绝; -4. 主叫或者被叫挂断通话。 - -### 导入 EaseCallKit 库 - -`EaseCallKit` 主要依赖于 `com.hyphenate:hyphenate-chat:xxx` 版本和 `io.agora.rtc:full-sdk:xxx` 版本等库; - -`EaseCallKit` 库可通过 Gradle 方式和源码两种方式集成。 - -#### Gradle 方式集成 - -- 在 `build.gradle` 中添加以下代码,重新 build 你的项目即可。 - -```gradle -implementation 'io.hyphenate:ease-call-kit:3.8.9' -``` - -:::tip -`EaseCallKit` 必须依赖环信 IM SDK (即 hyphenate-chat) ,因而在使用 `EaseCallKit` 时必须同时添加环信 IM SDK 依赖。 -::: - -#### 源码集成 - -- 下载 [EaseCallKit 源码](https://github.com/easemob/easecallkitui-android); -- 在 `build.gradle` 中增加以下内容,重新 build 你的项目即可。 - -```gradle -implementation project(':ease-call-kit') -``` - -`EaseCallKit` 中如果要修改 `hyphenate-chat` 和 `agora.rtc` 中版本号,可修改以下依赖: - -```gradle -//环信 SDK -implementation 'io.hyphenate:hyphenate-chat:3.8.0' (`hyphenate-chat` 只支持 3.8.0 及以上版本) -//声网 SDK -implementation 'io.agora.rtc:full-sdk:3.8.0' -``` - -使用 easecallkit 4.0.1 或以上版本 时,请使用声网音视频库 `io.agora.rtc:full-sdk:4.1.0`。 - -### 添加权限 - -根据场景需要,本库需要增加麦克风、相机和悬浮窗等权限: - -```xml - - - - - - - - - - - ... - - -``` - -### 添加 EaseCallKit Activity - -在清单中增加 `EaseCallKit` 中的 `EaseVideoCallActivity` 和 `EaseMultipleVideoActivity`: - -```xml -//添加 Activity - - -``` - -### 初始化 - -在环信 IM SDK 初始化完成后,可以开始初始化 `EaseCallKit`,同时增加监听回调,设置常用配置项。代码如下: - -```java -//初始化 `EaseCallUIKit`。 -EaseCallKitConfig callKitConfig = new EaseCallKitConfig(); -//设置默认头像。 -String headImage = EaseFileUtils.getModelFilePath(context,"watermark.png"); -callKitConfig.setDefaultHeadImage(headImage); -//设置振铃文件。 -String ringFile = EaseFileUtils.getModelFilePath(context,"huahai.mp3"); -callKitConfig.setRingFile(ringFile); -//设置呼叫超时时间,单位为秒。 -callKitConfig.setCallTimeOut(30 * 1000); -//设置声网的 appId。 -callKitConfig.setAgoraAppId("*****"); -Map userInfoMap = new HashMap<>(); -userInfoMap.put("***",new EaseCallUserInfo("****",null)); -callKitConfig.setUserInfoMap(userInfoMap); -EaseCallKit.getInstance().init(context,callKitConfig); -addCallkitListener(); -``` - -可设置的配置项包括以下内容: - -```java -/** - * EaseCallKit 相关的用户配置选项。 - * defaultHeadImage 用户默认头像。该参数的值为本地文件绝对路径或者 URL。 - * userInfoMap 用户相关信息。该信息为 key-value 格式,key 为用户的环信 ID,value 为 `EaseCallUserInfo`。 - * callTimeOut 呼叫超时时间,单位为毫秒,默认为 30 秒。 - * audioFile 振铃文件。该参数的值为本地文件绝对路径。 - * enableRTCToken 是否开启 RTC 验证。该功能通过声网后台控制,默认为关闭。 - */ -public class EaseCallKitConfig { - private String defaultHeadImage; - private Map userInfoMap = new HashMap<>(); - private String RingFile; - private String agoraAppId = "****"; - private long callTimeOut = 30 * 1000; - public EaseCallKitConfig(){ - ... -} -``` - -### 发起通话邀请 - -`EaseCallKit` 初始化完成后,可以发起音视频通话。 - -#### 一对一音视频通话 - -一对一通话可分为视频通话和语音通话,接口如下所示: - -```java -/** - * 发起一对一通话。 - * @param type 通话类型。该参数只能设置为 `SIGNAL_VOICE_CALL` 或 `SIGNAL_VIDEO_CALL`。 - * @param user 被叫用户 ID,即环信 ID。 - * @param ext 自定义扩展字段,描述通话扩展信息。 - */ -public void startSingleCall(final EaseCallType type, final String user,final String ext){} -``` - -#### 多人音视频通话 - -你可以从群组成员列表或者好友列表中选择,发起多人音视频邀请,具体实现可参考 demo 中的 `ConferenceInviteActivity`。 - -```java -/** - * 邀请用户加入多人通话。 - * @param users 用户 ID 列表,即环信 ID 列表。 - * @param ext 自定义扩展字段,描述通话扩展信息。 - */ -public void startInviteMultipleCall(final String[] users,final String ext){} -``` - -发起通话后的 UI 界面如下: - -![img](/images/android/sendcall.png) - -### 被叫收到通话邀请 - -主叫方发起邀请后,如果被叫方在线且当前不在通话中,会弹出邀请通话界面,被叫可以选择接听或者拒绝。 - -被叫收到邀请后会触发 `EaseCallKitListener` 中的 `onRevivedCall` 回调: - -```java -/** - * 收到通话邀请回调。 - * @param callType 通话类型。 - * @param userId 邀请方的用户 ID。 - * @param ext 自定义扩展字段,描述通话扩展信息。 - */ -void onRevivedCall(EaseCallType callType, String userId,String ext){} -``` - -收到通话邀请后的界面如下: - -![img](/images/android/called.jpeg) - -### 多人通话中邀请 - -多人通话中,当前用户可以点击通话界面右上角的邀请按钮再次向其他用户发起邀请。这种情况下,会触发 `EaseCallKitListener` 中的 `onInviteUsers` 回调: - -```java -/** - * 邀请好友进行多人通话。 - * @param context 通话上下文。 - * @param users 当前通话中已经存在的成员。 - * @param ext 自定义扩展字段,描述通话扩展信息。 - */ -public void onInviteUsers(Context context,String userId[],String ext) { -} -``` - -### 加入频道成功回调 - -用户加入通话后,当前用户以及其他与会者会收到 `EaseCallKitListener` 中的 `onRemoteUserJoinChannel` 回调。该接口自从 SDK 3.8.1 新增。 - -```java -@Override -public void onRemoteUserJoinChannel(String channelName, String userName, int uid, EaseGetUserAccountCallback callback){ - //此时,可以获取当前频道中已有用户的声网 ID 与环信 ID 的映射表,并将映射表设置到 `EaseCallKit`,同时也可以更新用户的头像和昵称。 - // callback.onUserAccount(accounts); -} -``` - -### 通话结束 - -在一对一音视频通话中,若其中一方挂断,双方的通话会自动结束,而多人音视频通话中需要主动挂断才能结束通话。通话结束后,会触发 `onEndCallWithReason` 回调: - -```java -/** - * 通话结束回调。 - * @param callType 通话类型。 - * @param reason 通话结束原因。 - * @param callTime 通话时长。 - */ -void onEndCallWithReason(EaseCallType callType, String channelName, EaseCallEndReason reason, long callTime){} - -//通话结束原因如下: -public enum EaseCallEndReason { - EaseCallEndReasonHangup(0), //正常挂断。 - EaseCallEndReasonCancel(1), //您已取消通话。 - EaseCallEndReasonRemoteCancel(2), //对方取消通话。 - EaseCallEndReasonRefuse(3),//对方拒绝接听。 - EaseCallEndReasonBusy(4), //忙线中。 - EaseCallEndReasonNoResponse(5), //您未接听。 - EaseCallEndReasonRemoteNoResponse(6), //对端无响应。 - EaseCallEndReasonHandleOnOtherDevice(7); //已在其他设备处理。 - .... -} -``` - -## 进阶功能 - -### 通话异常回调 - -通话过程中如果有异常或者错误发生,会触发 `EaseCallKitListener` 中的 `onCallError` 回调: - -```java -/** - * 通话异常回调。 - * @param type 错误类型。 - * @param errorCode 错误码。 - * @param description 错误描述。 - */ -void onCallError(EaseCallKit.EaseCallError type, int errorCode, String description){} -``` - -`EaseCallError` 异常包括业务逻辑异常、音视频异常以及 Easemob IM 异常。 - -```java -/** - * 通话错误类型。 - * - */ -public enum EaseCallError{ - PROCESS_ERROR, //业务逻辑异常。 - RTC_ERROR, //音视频异常。 - IM_ERROR //Easemob IM 异常。 -} -``` - -### 配置修改 - -`EaseCallKit` 库初始化之后,可修改有关配置,接口和示例如下: - -```java -/** - * 获取当前 `EaseCallKit` 的配置。 - * - */ -public EaseCallKitConfig getCallKitConfig(){} - -//修改默认头像。 -EaseCallKitConfig config = EaseCallKit.getInstance().getCallKitConfig(); -if(config != null){ - String Image = EaseFileUtils.getModelFilePath(context,"bryant.png"); - callKitConfig.setDefaultHeadImage(Image); -} -``` - -### 头像昵称修改 - -自 `EaseCallKit` 3.8.1 开始,新增了修改头像昵称的接口,用户可以在加入频道后,修改自己和通话中其他人的头像昵称,修改方法如下: - -```java -@Override -public void onRemoteUserJoinChannel(String channelName, String userName, int uid, EaseGetUserAccountCallback callback){ - if(userName == null || userName == ""){ - // 根据用户的 Agora ID 获取 环信 ID。url 为获取用户信息的请求 URL,请参考 [Easemob IM demo](https://www.easemob.com/download/demo)。 - getUserIdAgoraUid(uid, url, callback); - // 将获取到的用户信息设置给回调,具体实现请参考 [Easemob IM demo](https://www.easemob.com/download/demo)。 - //callback.onUserAccount(userAccounts); - }else{ - // 设置用户昵称和头像。 - setEaseCallKitUserInfo(userName); - EaseUserAccount account = new EaseUserAccount(uid,userName); - List accounts = new ArrayList<>(); - accounts.add(account); - callback.onUserAccount(accounts); - } -} -``` - -### 私有化部署 - -CallKit 4.8.2 及更高版本支持私有化部署,包括初始化和初测监听器。 - -#### 初始化 - -配置私有化 AgoraAppId。其他可配置的选项,详见本文档中的[初始化](https://doc.easemob.com/document/android/easecallkit.html#初始化)一节。 - -```kotlin -EaseCallKitConfig().apply { - …… - agoraAppId = "2d4f114e22304cee8d31ae909f3289d2" - …… - EaseCallKit.getInstance().init(context, this) -} -``` - -#### 注册监听器 - -监听 `com.hyphenate.easecallkit.base.EaseCallKitListener#onRtcEngineCreated` 事件,在 RTC 引擎创建的回调里进行私有化配置。详见 [API 参考](https://doc.shengwang.cn/api-ref/rtc/android/API/toc_network#api_irtcengine_setlocalaccesspoint)。 - -```kotlin -private val callKitListener by lazy { object :EaseCallKitListener { - …… - - override fun onRtcEngineCreated(engine: RtcEngine?) { - var configuration= LocalAccessPointConfiguration().apply { - //设置你的私有化地址 - ipList = arrayListOf().apply { add("101.111.111.111" )} - verifyDomainName = "ap.955011.agora.local" - mode = LOCAL_RPOXY_LOCAL_ONLY - } - engine?.setLocalAccessPoint(configuration) - } - - …… - - } } - -EaseCallKit.getInstance().setCallKitListener(callKitListener) -``` - -## 参考 - -### 获取声网 token - -加入音视频时,你需获取声网 token 以进行鉴权,需要在 `EaseCallKitListener` 中将 token 回调给 `EaseCallKit`。 - -如果不需要鉴权,可以直接回调 token 为 `null`,或者在设置 `callKitConfig.setEnableRTCToken(false)` 的前提下不实现该回调, 具体接口和使用如下: - -```java -/** - * 用户生成 token 回调。 - * @param userId 用户 ID,即用户的环信 ID。 - * @param channelName 频道名称。 - * @param agoraAppId 声网的 App ID。 - * @param callback 生成的 token 回调。若成功生成 token,即返回 token;若未能成功生成 token,返回错误码和错误消息。 - */ -default void onGenerateToken(String userId,String channelName,String agoraAppId,EaseCallKitTokenCallback callback){}; - -@Override -public void onGenerateToken(String userId, String channelName, String agoraAppId, EaseCallKitTokenCallback )callback{ - if(callback != null){ - // 若无需 token 鉴权,你需向 `token` 传 `null`,向 `uid` 传 `0`。 - //callback.onSetToken(null, 0); - - - // 若需要 token 鉴权,则调用你的 App Server 生成 token,然后将生成的 token 回调给 `EaseCallKit`。 - // url 为拼接参数请求 token 的 URL,可参考[官网上的 Easemob IM demo](https://www.easemob.com/download/demo)。 - getRtcToken(url, callback); - //获取到 token 及 uid 后,将其回调给 callback 即可。 - //callback.onSetToken(token, uid); - } -} -``` - -自 EaseCallKit 3.8.1 版本开始,`EaseCallKitTokenCallback` 中的 `onSetToken` 方法添加了 `uid` 参数,你可以使用数字 uid 加入声网频道。 - -```java -void onSetToken(String token, int uId); -``` - -### 离线推送 - -为保证被叫用户 App 在后台运行或离线时也能收到通话请求,用户需开启离线推送。关于如何开启离线推送,请参见 [开启 Android Push](/document/android/push/push_notification_mode_dnd.html)。开启离线推送后,用户在离线情况下收到呼叫请求时,其手机通知页面会弹出一条通知消息,用户点击该消息可唤醒 App 并进入振铃页面。 - -关于离线推送场景方案,请参见 [安卓端设置推送](/document/android/push/push_overview.html)。 - -## API 列表 - -`EaseCallKit` 中提供的 API 列表如下: - -| 方法 | 说明 | -| :---------------------- | :---------------------------- | -| init | 初始化 `EaseCallKit`。 | -| setCallKitListener | 设置监听。 | -| startSingleCall | 发起单人通话。 | -| startInviteMultipleCall | 邀请用户加入多人通话。 | -| getCallKitConfig | 获取 `EaseCallKit` 相关配置。 | - -回调模块 `EaseCallKitListener` 的 API 列表如下: - -| 事件 | 说明 | -| :---------------------- | :--------------------------------------------------------------- | -| onEndCallWithReason | 通话结束时触发该事件。 | -| onInviteUsers | 多人通话中点击邀请按钮触发该事件。 | -| onReceivedCall | 振铃时触发该事件。 | -| onGenerateToken | 获取声网 token 回调。用户将获取到的 token 回调到 `EaseCallKit`。 | -| onCallError | 通话异常时触发该回调。 | -| onInViteCallMessageSent | 通话邀请消息回调。 | -| onRemoteUserJoinChannel | 用户加入频道时触发。该方法自 `EaseCallKit` 3.8.1 版本添加。 | - -`EaseGetUserAccountCallback` 的 API 列表如下: - -| 事件 | 说明 | -| :-------------------- | :---------------------------------------------------------------------- | -| onUserAccount | 传入环信 ID 与声网 uid 的映射。 该方法自 `EaseCallKit` 3.8.1 版本添加。 | -| onSetUserAccountError | 获取用户信息失败触发。方法自 `EaseCallKit` 3.8.1 版本添加。 | diff --git a/docs/document/android/elite_sdk.md b/docs/document/android/elite_sdk.md deleted file mode 100644 index 488ce262..00000000 --- a/docs/document/android/elite_sdk.md +++ /dev/null @@ -1,385 +0,0 @@ -# 精简版 SDK - -精简版 SDK 4.2.0 支持 Android 和 iOS 平台,包含基础的单聊和聊天室功能,适用于 SDK 包体积尽量小、仅需基础收发消息功能、而无需离线推送通知等功能的情况。 - -精简版 SDK 对应用的体积增量不大,android 为 1.11 MB,iOS 为 1.09 MB。 - -要下载 Android 端精简版 SDK,点击[这里](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/SDK-mini/easemob-sdk-4.2.0-lite.zip)。 - -:::tip -精简版 SDK 无本地存储,可以升级为标准版 SDK,但标准版不能降级为精简版。 -::: - -## 功能列表 - -精简版 SDK 的功能如下表所示: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
功能模块功能功能细分/描述 接口文档 精简版 SDK标准版 SDK
消息管理发送和接收消息发送和接收消息

发送和接收消息

接收消息
发送和接收附件类型的消息
发送和接收位置消息
发送和接收透传消息
发送自定义类型消息
发送和接收合并消息
发送和接收定向消息
使用消息扩展字段
管理本地消息管理本地消息

获取本地历史消息

-

搜索消息

-

导入和插入消息

-

更新消息

-

删除消息

管理服务端消息管理服务端消息

从服务器分页获取指定会话的历史消息

-

单向删除服务端的历史消息

管理消息回执消息送达回执

消息送达回执

消息已读回执

消息已读回执

撤回消息

撤回消息

-

设置消息撤回监听

 
修改消息单聊会话中已经发送成功的文本消息进行修改

修改消息

获取消息流量统计获取消息流量统计获取消息流量统计  
翻译消息翻译

消息翻译

会话管理会话列表获取本地会话 获取本地会话
从服务器分页获取会话列表

从服务器分页获取会话列表

会话未读数获取或清零本地会话的未读数

 

-

会话未读数

置顶会话置顶会话置顶会话
删除会话单向删除服务端会话及本地会话单向删除服务端会话和本地会话及其历史消息
删除本地会话及历史消息删除本地会话及历史消息
管理用户属性设置和获取用户属性用户属性指实时消息互动用户的信息,如用户昵称、头像、邮箱、电话、性别、签名、生日等管理用户属性
管理用户关系好友列表管理和黑名单管理

添加、删除好友;

-

设置和获取好友备注;

-

从服务器获取好友列表;

-

将用户添加到或移除黑名单

-

从服务器获取黑名单列表

管理用户关系
群组管理群组为多人聊天,有稳定的成员关系。

创建、管理群组;

-

管理群成员;

-

管理群成员属性

群组管理
聊天室管理聊天室为多人聊天,没有固定的成员关系。

聊天室概述

聊天室概述  
创建和管理聊天室创建聊天室创建和管理聊天室
加入聊天室
获取聊天室详情
退出聊天室
解散聊天室
监听聊天室事件
管理聊天室成员获取聊天室成员列表管理聊天室成员
将成员移出聊天室
管理聊天室黑名单
管理聊天室白名单
管理聊天室禁言列表
开启和关闭聊天室全员禁言
管理聊天室所有者和管理员
管理聊天室基本属性获取聊天室公告管理聊天室基本属性
更新聊天室公告
修改聊天室名称
修改聊天室描述
管理聊天室自定义属性管理聊天室自定义属性管理聊天室自定义属性
进阶功能离线推送集成第三方消息推送服务离线推送
登录多个设备支持同一账号在多个设备上登录并接收消息 
多设备管理多设备登录
管理在线状态订阅管理在线状态订阅在线状态订阅
消息表情回复 Reaction对单聊和群聊中的消息通过表情回复消息表情回复
子区管理子区是群组成员的子集子区管理
消息举报开发者可以在客户端调用该接口举报违规消息消息举报
- -## 错误码 - -[Android 错误码](error.html) - - - - - - - - - - - - - - - - - diff --git a/docs/document/android/overview.md b/docs/document/android/overview.md deleted file mode 100644 index dcd70d91..00000000 --- a/docs/document/android/overview.md +++ /dev/null @@ -1,260 +0,0 @@ -# SDK 集成概述 - - - -介绍 Android 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号并取得 App key,见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -详见 [开发环境要求](quickstart.html#前提条件)。 - -## 添加权限 - -1. 找到文件 `AndroidManifest.xml` -2. SDK 最少需要添加的权限如下: - -```xml - - - - - - -``` - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。 - -初始化示例代码: - -```java -EMOptions options = new EMOptions(); -options.setAppKey("Your appkey"); -......// 其他 EMOptions 配置。 -EMClient.getInstance().init(context, options); -``` - -:::tip -需要在主进程中进行初始化。 -::: - -## 注册用户 - -目前用户注册方式有以下几种: -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```java -// 注册失败会抛出 HyphenateException。 -EMClient.getInstance().createAccount(mAccount, mPassword);// 同步方法。 -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -目前登录服务器支持手动和自动登录。手动登录有两种方式: - -- 用户 ID + 密码 -- 用户 ID + token - -手动登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `onConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -### 手动登录 - -**用户 ID + 密码** 登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合密码规则要求。 - -```java -EMClient.getInstance().login(mAccount, mPassword, new EMCallBack() { - // 登录成功回调 - @Override - public void onSuccess() { - - } - - // 登录失败回调,包含错误信息 - @Override - public void onError(int code, String error) { - - } - -}); -``` - -**用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取。详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```java -EMClient.getInstance().loginWithToken(mAccount, mToken, new EMCallBack() { - // 登录成功回调 - @Override - public void onSuccess() { - - } - - // 登录失败回调,包含错误信息 - @Override - public void onError(int code, String error) { - - } -}); -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -### 自动登录 - -初始化时可以设置是否自动登录。如果设置为自动登录,则登录成功之后,后续启动初始化的时候会自动登录。 - -自动登录时,SDK 尝试连接服务器失败后,延时随机一段时间后自动重连。 - -## 退出登录 - -同步方法: - -```java -EMClient.getInstance().logout(true); -``` - -异步方法: - -```java -EMClient.getInstance().logout(true, new EMCallBack() { - - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String message) { - - } -}); -``` - -## 连接状态相关 - -你可以通过注册连接监听确认连接状态。 - -```java -EMConnectionListener connectionListener = new EMConnectionListener() { - @Override - public void onConnected() { - - } - @Override - public void onDisconnected(int errorCode) { - - } - - @Override - public void onLogout(final int errorCode,EMLoginExtensionInfo info) { - - } - - @Override - public void onTokenWillExpire() { - - } - - @Override - public void onTokenExpired() { - - } - @Override - // 连接成功,开始从服务器拉取离线消息时触发。 - // 注意:如果本次登录服务器没有离线消息,不会触发该回调。 - public void onOfflineMessageSyncStart() { - - } - @Override - // 离线用户上线后从服务器拉取离线消息结束时触发。 - // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。 - public void onOfflineMessageSyncFinish() { - - } -}; -// 注册连接状态监听 -EMClient.getInstance().addConnectionListener(connectionListener); -// 移除连接状态监听 -EMClient.getInstance().removeConnectionListener(connectionListener); -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等引起的连接终端,SDK 会自动尝试重连。重连成功或者失败的结果分别会收到通知 `onConnected` 和 `onDisconnected`。 - -### 被动退出登录 - -你可以通过监听回调 `EMConnectionListener#onLogout(int)` 后,调用 `EMClient#logout(boolean, EMCallBack)` 进行退出并返回登录界面。 - -`EMConnectionListener#onLogout(int)` 返回的 `errorCode` 有如下: - -- `USER_LOGIN_ANOTHER_DEVICE=206`: 用户已经在其他设备登录 -- `USER_REMOVED=207`: 用户账户已经被移除 -- `USER_BIND_ANOTHER_DEVICE=213`: 用户已经绑定其他设备 -- `USER_LOGIN_TOO_MANY_DEVICES=214`: 用户登录设备超出数量限制 -- `USER_KICKED_BY_CHANGE_PASSWORD=216`: 由于密码变更被踢下线 -- `USER_KICKED_BY_OTHER_DEVICE=217`: 由于其他设备登录被踢下线 -- `USER_DEVICE_CHANGED=220`: 和上次设备不同导致下线 -- `SERVER_SERVICE_RESTRICTED=305`: Chat 功能限制 - -以上参数具体可以参考 [EMError](https://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1_e_m_error.html) 对应说明。 - -## 输出信息到日志文件 - -环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。 - -默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。 - -例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。 - -SDK 默认输出调试信息(所有日志,包括调试信息、警告和错误),如果只需输出错误日志,需要关闭调试模式。 - -```java -// 需要在 SDK 初始化后调用 -EMClient.getInstance().setDebugMode(false); -``` - -### 获取本地日志 - -打开以下目录,获取本地日志。 - -```shell -adb pull /sdcard/android/data/{应用包名}/{App Key}/core_log -``` - -获取本地日志,需要将 `{应用包名}` 替换为应用的包名,例如 `com.hyphenate.chatuidemo`;`{App Key}` 需要替换为应用的环信 App Key。 diff --git a/docs/document/android/privatecloud.md b/docs/document/android/privatecloud.md deleted file mode 100644 index 32269bbd..00000000 --- a/docs/document/android/privatecloud.md +++ /dev/null @@ -1,35 +0,0 @@ -# 私有云 SDK 集成配置 - - - -## 静态配置 IP(域名)地址 - -SDK 默认指向公有云地址,在部署私有云后,需要将地址重新指向到新的地址,以下是地址修改方法: - -```java -EMOptions emOptions = new EMOptions();//实例化 EMOptions 对象 -emOptions.setRestServer("10.10.10.10:00");//设置私有云 REST 地址(ip/域名:port) -emOptions.setIMServer("10.10.10.10");//设置私有云 IM 地址 -emOptions.setImPort(00);//设置私有云 IM 端口号 -emOptions.enableDNSConfig(false);//默认是 true,在私有云下,需要关闭(设置成 false) - -EMClient.getInstance().init(context,emOptions);//最后初始化 SDK -``` -:::tip -如果需要配置 HTTPS 只需在 REST 地址前加一个前缀。 -::: - -```java -emOptions.setRestServer("https://10.10.10.10:00");//设置私有云 REST 地址(ip:port) -``` - -## 动态配置地址 - -1. 服务器端配置 DNS 地址表 -2. 从服务器端动态获取地址 - -```java -EMOptions emOptions = new EMOptions(); -emOptions.setDnsUrl("url");//从服务器端动态获取地址 -EMClient.getInstance().init(context,emOptions);//初始化 SDK -``` \ No newline at end of file diff --git a/docs/document/applet/alipay.md b/docs/document/applet/alipay.md deleted file mode 100644 index 02194976..00000000 --- a/docs/document/applet/alipay.md +++ /dev/null @@ -1,101 +0,0 @@ -# 支付宝小程序集成介绍 - - - -### 注册环信账号 - -开发者需要在环信管理后台 [注册并创建应用](/product/enable_and_configure_IM.html#创建应用),来获取唯一 appKey,SDK 初始化时需要配置 appKey。 - -### 搭建支付宝小程序开发环境 - -首先需要下载并安装 [开发者工具](https://opendocs.alipay.com/mini/ide/download),然后按照支付宝小程序的 [接入流程](https://opendocs.alipay.com/mini/006kyi) 一步步创建一个小程序。 - -### 配置服务器域名 - -小程序在发布前,需要配置合法域名。 - -登录 [支付宝开放平台](https://open.alipay.com/platform/home.htm), 配置以下服务器域名。 - -:::tip -request 合法域名: - -1. https://a1.easemob.com -2. https://a2.easemob.com -3. https://a3.easemob.com -4. https://a4.easemob.com -5. https://a5.easemob.com -7. https://rs.chat.agora.io -8. https://rs.easemob.com - ::: - -:::tip -socket 合法域名: -wss://im-api-alipay.easemob.com/websocket -::: - -环信不同数据中心的 REST API 请求域名、WebSocket 访问域名: - -| 数据中心 | REST API 请求地址 | WebSocket 访问域名 | -| ------------- | ------------------ | -------------------------------- | -| 国内 1 区 | a1.easemob.com | im-api-alipay.easemob.com 或 im-api-alipay.easecdn.com | -| 国内 2 区 | a31.easemob.com | im-api-alipay-31.easemob.com 或 im-api-alipay-31.easecdn.com | -| 国内 VIP 区 | 请咨询商务经理 | 请咨询商务经理 | -| 客服专用 | 请咨询商务经理 | 请咨询商务经理 | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | im-api-alipay-sgp.easemob.com 或 im-api-alipay-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | im-api-alipay-61.easemob.com 或 im-api-alipay-61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | im-api-alipay-41.easemob.com 或 im-api-alipay-41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | im-api-alipay-71.easemob.com 或 im-api-alipay-71.easecdn.com | - -应用所在数据中心可以在环信用户管理后台 > **即时通讯** > **服务概览**中查看: - -![img](/images/applet/service_overview.png) - -### 说明 - -支付宝小程序:支付宝小程序在一段时间内只能保留一个 WebSocket 连接,如果当前已存在 WebSocket 连接,那么会自动关闭该连接,并重新创建一个新的 WebSocket 连接。 - -### 集成 SDK - -#### 下载 SDK - -可以通过以下两种方式获取 SDK: - -- 通过官网[下载 SDK](https://www.easemob.com/download/im) -- 从环信的[github 仓库](https://github.com/easemob/webim-weixin-xcx/tree/master/src/sdk) 中获取 SDK 中的文件 - -#### 引入 SDK - -- 开始一个全新的项目 - 1. 将下载的 SDK(src/sdk/)导入到自己的项目中。 - 2. 引入 SDK:`import IMSDK from "../sdk/Easemob-chat-miniProgram";` -- 基于 Demo 二次开发 - -将下载的代码导入开发者工具即可运行起来。 - -#### 调用示例 - -```javascript -//使用示例 -import SDK from "../sdk/connection"; // 2.0 SDK -import SDK from "../sdk/Easemob-chat-miniProgram"; // 3.0 SDK -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -//实例化 SDK 对象 -const WebIM = (wx.WebIM = SDK); -WebIM.conn = new WebIM.connection({ - appKey: "your appKey", - https: true, //是否使用 HTTPS - url: "wss://im-api-alipay.easemob.com/websocket", // socket server (3.0 SDK) - apiUrl: "https://a1.easemob.com", // rest server - heartBeatWait: 30000, //心跳间隔,单位为毫秒 - autoReconnectNumMax: 5, //自动重连次数 - useOwnUploadFun: false, // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传 URL) -}); -``` - -IM 基本功能和 Web 端一致,请参考 Web 端文档。 diff --git a/docs/document/applet/apidoc.md b/docs/document/applet/apidoc.md deleted file mode 100644 index 6e9f1a4d..00000000 --- a/docs/document/applet/apidoc.md +++ /dev/null @@ -1,5 +0,0 @@ -# 小程序 SDK API 文档 - - - -微信小程序的 IM 的 API 使用方法,与 Web Javascript 接入方式基本相同,可参照 [Web SDK API DOC](https://doc.easemob.com/jsdoc/index.html) diff --git a/docs/document/applet/baidu.md b/docs/document/applet/baidu.md deleted file mode 100644 index 5d66b553..00000000 --- a/docs/document/applet/baidu.md +++ /dev/null @@ -1,105 +0,0 @@ -# 百度小程序集成介绍 - - - -### 注册环信账号 - -开发者需要在环信管理后台 [注册并创建应用](/product/enable_and_configure_IM.html#创建应用),来获取唯一 appKey,SDK 初始化时需要配置 appKey。 - -### 搭建百度小程序开发环境 - -首先需要下载并安装 [开发者工具](https://smartprogram.baidu.com/docs/introduction/tool/),然后按照百度小程序的 [接入流程](https://smartprogram.baidu.com/docs/develop/tutorial/startdevelop/) 一步步创建一个小程序。 - -### 配置服务器域名 - -小程序在发布前,需要配置合法域名。 - -登录 [百度智能小程序官网](https://smartprogram.baidu.com/),在开发设置页面配置以下服务器域名。 - -:::tip -request 合法域名: - -1. https://a1.easemob.com -2. https://a2.easemob.com -3. https://a3.easemob.com -4. https://a4.easemob.com -5. https://a5.easemob.com -6. https://rs.chat.agora.io -7. https://rs.easemob.com -::: - -:::tip -socket 合法域名: -wss://im-api-wechat.easemob.com(3.0 IM SDK) -::: - -:::tip -为满足不同客户的业务需求,环信在多地部署了数据中心。不同数据中心的 REST API 请求域名、WebSocket 访问域名不同。请根据您所在数据中心进行配置。 -::: - -环信不同数据中心的 REST API 请求域名、WebSocket 访问域名: - -| 数据中心 | REST API 请求地址 | WebSocket 访问域名 | -| ------------- | ------------------ | -------------------------------- | -| 国内 1 区 | a1.easemob.com | im-api-wechat.easemob.com 或 im-api-wechat.easecdn.com | -| 国内 2 区 | a31.easemob.com | im-api-wechat-31.easemob.com 或 im-api-wechat-31.easecdn.com | -| 国内 VIP 区 | 请咨询商务经理 | 请咨询商务经理 | -| 客服专用 | 请咨询商务经理 | 请咨询商务经理 | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | im-api-wechat-sgp.easemob.com 或 im-api-wechat-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | im-api-wechat-61.easemob.com 或 im-api-wechat-61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | im-api-wechat-41.easemob.com 或 im-api-wechat-41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | im-api-wechat-71.easemob.com 或 im-api-wechat-71.easecdn.com | - -应用所在数据中心可以在环信用户管理后台 > **即时通讯** > **服务概览**中查看: - -![img](/images/applet/service_overview.png) - -### 说明 - -百度小程序注册主体不能为个人,必须为企业、媒体、政府等。 - -### 集成 SDK - -#### 下载 SDK - -可以通过以下两种方式获取 SDK: - -- 通过官网 [下载 SDK](https://www.easemob.com/download/im) -- 从环信的 [github 仓库](https://github.com/easemob/webim-weixin-xcx/tree/master/src/sdk) 中获取 SDK 中的文件 - -#### 引入 SDK - -- 开始一个全新的项目 - 1. 将下载的 SDK(src/sdk/)导入到自己的项目中。 - 2. 引入 SDK:`import IMSDK from "../sdk/Easemob-chat-miniProgram";` -- 基于 Demo 二次开发 - -将下载的代码导入开发者工具即可运行起来。 - -#### 调用示例 - -```javascript -//使用示例 -import SDK from "../sdk/connection"; // 2.0 SDK -import SDK from "../sdk/Easemob-chat-miniProgram"; // 3.0 SDK -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -//实例化 SDK 对象 -const WebIM = (wx.WebIM = SDK); -WebIM.conn = new WebIM.connection({ - appKey: "your appKey", - https: true, //是否使用 HTTPS - url: "wss://im-api-wechat.easemob.com/websocket", // socket server (3.0 SDK) - apiUrl: "https://a1.easemob.com", // rest server - heartBeatWait: 30000, //心跳间隔 - autoReconnectNumMax: 5, //自动重连次数 - useOwnUploadFun: false, // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传 URL) -}); -``` - -IM 基本功能和 Web 端一致,请参考 Web 端文档。 diff --git a/docs/document/applet/bytedance.md b/docs/document/applet/bytedance.md deleted file mode 100644 index 7f5e1067..00000000 --- a/docs/document/applet/bytedance.md +++ /dev/null @@ -1,102 +0,0 @@ -# 抖音小程序集成介绍 - - - -### 注册环信账号 - -开发者需要在环信管理后台 [注册并创建应用](/product/enable_and_configure_IM.html#创建应用),来获取唯一 appKey,SDK 初始化时需要配置 appKey。 - -### 搭建抖音小程序开发环境 - -首先需要下载并安装 [开发者工具](https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/developer-instrument/developer-instrument-update-and-download/),然后按照抖音小程序的 [接入流程](https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/guide/start/kick-off) 一步步创建一个小程序 - -### 配置服务器域名 - -小程序在发布前,需要配置合法域名。 - -登录抖音小程序 [开发者平台](https://microapp.bytedance.com/),选择当前小程序(如果没有需要创建一个小程序),进入 “开发管理>开发设置” 页面配置以下服务器地址。 - -:::tip -request 合法域名: - -1. https://a1.easemob.com -2. https://a2.easemob.com -3. https://a3.easemob.com -4. https://a4.easemob.com -5. https://a5.easemob.com -6. https://a1-chatfile.easemob.com -7. https://rs.chat.agora.io -8. https://rs.easemob.com -::: - -:::tip -socket 合法域名: -wss://im-api-wechat.easemob.com(3.0 IM SDK) -::: - -:::tip -为满足不同客户的业务需求,环信在多地部署了数据中心。不同数据中心的 REST API 请求域名、WebSocket 访问域名不同。请根据您所在数据中心进行配置。 -::: - -环信不同数据中心的 REST API 请求域名、WebSocket 访问域名: - -| 数据中心 | REST API 请求地址 | WebSocket 访问域名 | -| ------------- | ------------------ | -------------------------------- | -| 国内 1 区 | a1.easemob.com | im-api-wechat.easemob.com 或 im-api-wechat.easecdn.com | -| 国内 2 区 | a31.easemob.com | im-api-wechat-31.easemob.com 或 im-api-wechat-31.easecdn.com | -| 国内 VIP 区 | 请咨询商务经理 | 请咨询商务经理 | -| 客服专用 | 请咨询商务经理 | 请咨询商务经理 | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | im-api-wechat-sgp.easemob.com 或 im-api-wechat-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | im-api-wechat-61.easemob.com 或 im-api-wechat-61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | im-api-wechat-41.easemob.com 或 im-api-wechat-41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | im-api-wechat-71.easemob.com 或 im-api-wechat-71.easecdn.com | - -应用所在数据中心可以在环信用户管理后台 > **即时通讯** > **服务概览**中查看: - -![img](/images/applet/service_overview.png) - -### 集成 SDK - -#### 下载 SDK - -可以通过以下两种方式获取 SDK: - -- 通过官网 [下载 SDK](https://www.easemob.com/download/im) -- 从环信的 [github 仓库](https://github.com/easemob/webim-weixin-xcx/tree/master/src/sdk) 中获取 SDK 中的文件 - -#### 引入 SDK - -- 开始一个全新的项目 - 1. 将下载的 SDK(src/sdk/)导入到自己的项目中。 - 2. 引入 SDK:`import IMSDK from "../sdk/Easemob-chat-miniProgram";` -- 基于 Demo 二次开发 - -将下载的代码导入开发者工具即可运行起来。 - -#### 调用示例 - -```javascript -//使用示例 -import SDK from "../sdk/connection"; // 2.0 SDK -import SDK from "../sdk/Easemob-chat-miniProgram"; // 3.0 SDK -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -//实例化 SDK 对象 -const WebIM = (wx.WebIM = SDK); -WebIM.conn = new WebIM.connection({ - appKey: "your appKey", - https: true, //是否使用 HTTPS - url: "wss://im-api-wechat.easemob.com/websocket", // socket server (3.0 SDK) - apiUrl: "https://a1.easemob.com", // rest server - heartBeatWait: 30000, //心跳间隔 - autoReconnectNumMax: 5, //自动重连次数 - useOwnUploadFun: false, // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传 URL) -}); -``` - -IM 基本功能和 Web 端一致,请参考 Web 端文档。 diff --git a/docs/document/applet/connection.md b/docs/document/applet/connection.md deleted file mode 100644 index 29fef139..00000000 --- a/docs/document/applet/connection.md +++ /dev/null @@ -1,43 +0,0 @@ -# 连接 - -应用客户端成功连接到环信服务器后,才能使用环信即时通讯 SDK 的收发消息等功能。 - -你调用 `open` 方法登录后,客户端 SDK 会自动连接环信服务器。关于登录详情,请参见[登录文档](login.html)。 - -## 监听连接状态 - -```javascript -conn.addEventHandler("connectionListener", { - onConnected: () => { - console.log("连接成功"); - }, - // 自 4.8.0 版本,`onDisconnected` 事件新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。 - onDisconnected: () => { - console.log("连接断开"); - }, - onReconnecting: () => { - console.log("重连中"); - }; -}); -``` - -## 自动重连 - -登录后,SDK 在以下情况下会尝试自动重连: - -- 网络断开 - -- 网络切换 - -- 非主动调用登出 - -不过,SDK 在以下情况下会停止自动重连。你需要调用 `open` 方法登录。 - -- 用户调用了 SDK 的登出方法 `close` 主动退出登录。 -- 登录时鉴权错误,例如, token 无效(错误码 104)或已过期(错误码 108)。 -- 用户在其他的设备上更改了密码,导致此设备上自动登录失败,提示错误码 216。 -- 用户的账号被从服务器端删除,提示错误码 207。 -- 用户在另一设备登录,将当前设备上登录的用户踢出,提示错误码 206。 -- 用户登录设备数量超过限制,提示错误码 214。 -- 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限,提示错误码 8。 - diff --git a/docs/document/applet/conversation_delete.md b/docs/document/applet/conversation_delete.md deleted file mode 100644 index c30df234..00000000 --- a/docs/document/applet/conversation_delete.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/conversation_delete.html", - title: "删除会话" -} ---- \ No newline at end of file diff --git a/docs/document/applet/conversation_list.md b/docs/document/applet/conversation_list.md deleted file mode 100644 index 3c8da086..00000000 --- a/docs/document/applet/conversation_list.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/conversation_list.html", - title: "会话列表" -} ---- \ No newline at end of file diff --git a/docs/document/applet/conversation_mark.md b/docs/document/applet/conversation_mark.md deleted file mode 100644 index 244bb184..00000000 --- a/docs/document/applet/conversation_mark.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/conversation_mark.html", - title: "会话标记" -} ---- \ No newline at end of file diff --git a/docs/document/applet/conversation_overview.md b/docs/document/applet/conversation_overview.md deleted file mode 100644 index a9f6c248..00000000 --- a/docs/document/applet/conversation_overview.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/conversation_overview.html", - title: "会话介绍" -} ---- \ No newline at end of file diff --git a/docs/document/applet/conversation_pin.md b/docs/document/applet/conversation_pin.md deleted file mode 100644 index 59fa428f..00000000 --- a/docs/document/applet/conversation_pin.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/conversation_pin.html", - title: "置顶会话" -} ---- \ No newline at end of file diff --git a/docs/document/applet/conversation_receipt.md b/docs/document/applet/conversation_receipt.md deleted file mode 100644 index 74500590..00000000 --- a/docs/document/applet/conversation_receipt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/conversation_receipt.html", - title: "会话已读回执" -} ---- \ No newline at end of file diff --git a/docs/document/applet/error.md b/docs/document/applet/error.md deleted file mode 100644 index 2f5d35d6..00000000 --- a/docs/document/applet/error.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/error.html", - title: "常见错误代码" -} ---- \ No newline at end of file diff --git a/docs/document/applet/group_attributes.md b/docs/document/applet/group_attributes.md deleted file mode 100644 index 4275b581..00000000 --- a/docs/document/applet/group_attributes.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/group_attributes.html", - title: "管理群组属性" -} ---- \ No newline at end of file diff --git a/docs/document/applet/group_manage.md b/docs/document/applet/group_manage.md deleted file mode 100644 index 5386437f..00000000 --- a/docs/document/applet/group_manage.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/group_manage.html", - title: "创建和管理群组" -} ---- \ No newline at end of file diff --git a/docs/document/applet/group_members.md b/docs/document/applet/group_members.md deleted file mode 100644 index 933dba4b..00000000 --- a/docs/document/applet/group_members.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/group_members.html", - title: "管理群组成员" -} ---- \ No newline at end of file diff --git a/docs/document/applet/group_overview.md b/docs/document/applet/group_overview.md deleted file mode 100644 index fe7b1d2d..00000000 --- a/docs/document/applet/group_overview.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/product/product_group_overview.html", - title: "群组概述" -} ---- \ No newline at end of file diff --git a/docs/document/applet/initialization.md b/docs/document/applet/initialization.md deleted file mode 100644 index 3ecbc551..00000000 --- a/docs/document/applet/initialization.md +++ /dev/null @@ -1,36 +0,0 @@ -# SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -## 前提条件 - -有效的环信即时通讯 IM 开发者账号和 App key,详见[环信即时通讯云控制台的相关文档](/product/enable_and_configure_IM.html#创建应用)。 - -## SDK 初始化 - -使用 SDK 前需要进行初始化,示例代码如下: - -```javascript -const conn = new EC.connection({ - appKey: "your appKey", - url: "wss://im-api-wechat.easemob.com/websocket", - apiUrl: "https://a1.easemob.com", -}); -``` - -初始化 SDK 参数说明: - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :--------------------------------- | -| `appKey` | String | 是 | 环信即时通讯云控制台为你的应用生成的唯一标识,由应用名称(`Appname`)和组织名称(`Orgname`)组成。 | -| `isHttpDNS` | Bool | 否 | 是否开启 DNS,防止 DNS 劫持。
-(默认)`true`:开启 DNS;
- `false`:关闭 DNS。 | -| `delivery` | Bool | 否 | 是否开启送达回执:
- `true`:开启;
-(默认)`false`:关闭。 | -| `enableReportLogs` | Bool | 否 | 小程序平台是否允许上传日志:
- `true`:开启;
-(默认)`false`:关闭。 | -| `https` | Bool | 否 | 是否支持通过 HTTPS 访问即时通讯 IM:
- (默认)`true`:支持 HTTPS 和 HTTP;
-`false`:浏览器根据使用的域名自行判断。 | -| `heartBeatWait` | Int | 否 | 心跳间隔,单位为毫秒,默认为 30000。 | -| `deviceId` | String | 否 | 设备 ID,为默认随机值。 | -| `useOwnUploadFun` | Bool | 否 | 是否支持通过自己的路径将图片、文件上传到自己的服务器。
-`true`:支持,需要指定路径;
-(默认)`false`:关闭,通过消息服务器上传下载文件。 | -| `autoReconnectNumMax` | Int | 否 | 最大重连次数。 | -| `apiUrl` | String | 是 | 指定的 REST 服务器。在未开启 DNS 的情况下使用,一般适用于开发者要实现数据隔离、特别注重数据安全的场景。要获取该服务器地址,需在环信控制台的**即时通讯 > 服务概览**页面,查看**域名配置**表格中的 **Rest Api** 设置。| -| `url` | String | 是 | 指定的消息服务器。在未开启 DNS 的情况下使用,一般适用于开发者要实现数据隔离、特别注重数据安全的场景。 要获取该服务器地址,需在环信控制台的**即时通讯 > 服务概览**页面,查看**域名配置**表格中的**微信小程序**或**支付宝小程序**设置。 | - diff --git a/docs/document/applet/log.md b/docs/document/applet/log.md deleted file mode 100644 index 7de982af..00000000 --- a/docs/document/applet/log.md +++ /dev/null @@ -1,58 +0,0 @@ -# SDK 日志 - -环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。 - -## 输出信息到日志文件 - -开启日志输出: - -```javascript -logger.enableAll(); -``` -- 设置日志不输出到控制台: - -```javascript -logger.setConsoleLogVisibility(false) -``` - -- 监听 SDK 日志事件: - -```javascript -logger.onLog = (log)=>{ - console.log('im logger', log) -} -``` - -关闭日志输出: - -```javascript -logger.disableAll(); -``` - -设置日志输出等级: - -```javascript -// 0 - 5 或者 'TRACE','DEBUG','INFO','WARN','ERROR','SILENT'; -logger.setLevel(0); -``` - -设置缓存日志: - -```javascript -logger.setConfig({ - useCache: false, // 是否缓存 - maxCache: 3 * 1024 * 1024, // 最大缓存字节 -}); -// 缓存全部等级日志 -logger.setLevel(0); -``` - -下载日志: - -```javascript -logger.download(); -``` - -## 日志上报 - -自 4.8.1 版本,小程序 SDK 支持日志上报功能, 即将日志会上传到环信服务器。该功能默认关闭,如有需要, 在初始化时,可将 `enableReportLogs` 参数设置为 `true`,然后联系商务开通日志上报功能。 \ No newline at end of file diff --git a/docs/document/applet/login.md b/docs/document/applet/login.md deleted file mode 100644 index 9aab07e2..00000000 --- a/docs/document/applet/login.md +++ /dev/null @@ -1,72 +0,0 @@ -# 登录 - -初始化 IM SDK 后,你需要首先调用接口登录。登录成功后,才能使用 IM 的功能。 - -## 用户注册 - -用户注册支持以下方式: - -- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。 - -示例代码如下: - -```javascript -conn.registerUser({ - username: "user1", - password: "xxx", -}); -``` - -- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。 - -除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建正式环境下和测试环境下的用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。 - -## 登录方式 - -1. **用户 ID + token** 是更加安全的登录方式。 - -测试环境下,你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户后,环信服务器会自动为这些用户分配用户 Token,详见[测试环境下创建用户的介绍](/product/enable_and_configure_IM.html#测试环境)。 - -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 - -```javascript -conn - .open({ - user: "username", - accessToken: "token", - }) - .then(() => { - console.log("login success"); - }) - .catch((reason) => { - console.log("login fail", reason); - }); -``` -2. **用户 ID + 密码** 登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合[密码规则要求](/document/server-side/account_system.html#开放注册单个用户)。 - -```javascript -conn - .open({ - user: "username", - pwd: "password", - }) - .then(() => { - console.log("login success"); - }) - .catch((reason) => { - console.log("login fail", reason); - }); -``` - -## 退出登录 - -```javascript -conn.close(); -``` - -## 多设备登录 - -除了单端单设备登录,环信即时通讯 IM 支持同一账号在多端的多个设备上登录。多设备登录时,若同端设备数量超过限制,新登录的设备会将之前登录的设备踢下线。 - -关于多设备登录场景中的设备数量限制、互踢策略以及信息同步,详见[多设备登录文档](multi_device.html)。 - diff --git a/docs/document/applet/message_delete.md b/docs/document/applet/message_delete.md deleted file mode 100644 index db9961af..00000000 --- a/docs/document/applet/message_delete.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_delete.html", - title: "删除消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_deliver_only_online.md b/docs/document/applet/message_deliver_only_online.md deleted file mode 100644 index 8d882bdd..00000000 --- a/docs/document/applet/message_deliver_only_online.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_deliver_only_online.html", - title: "消息只投在线用户" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_modify.md b/docs/document/applet/message_modify.md deleted file mode 100644 index 1e5f696e..00000000 --- a/docs/document/applet/message_modify.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_modify.html", - title: "修改消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_overview.md b/docs/document/applet/message_overview.md deleted file mode 100644 index 727d11dd..00000000 --- a/docs/document/applet/message_overview.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/product/product_message_overview.html", - title: "消息概述" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_pin.md b/docs/document/applet/message_pin.md deleted file mode 100644 index 935be35f..00000000 --- a/docs/document/applet/message_pin.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_pin.html", - title: "置顶消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_recall.md b/docs/document/applet/message_recall.md deleted file mode 100644 index 485074cb..00000000 --- a/docs/document/applet/message_recall.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_recall.html", - title: "撤回消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_receipt.md b/docs/document/applet/message_receipt.md deleted file mode 100644 index bc410842..00000000 --- a/docs/document/applet/message_receipt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_receipt.html", - title: "消息回执" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_retrieve.md b/docs/document/applet/message_retrieve.md deleted file mode 100644 index 7e9c5eb1..00000000 --- a/docs/document/applet/message_retrieve.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_retrieve.html", - title: "获取历史消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/message_send_receive.md b/docs/document/applet/message_send_receive.md deleted file mode 100644 index 672b17ae..00000000 --- a/docs/document/applet/message_send_receive.md +++ /dev/null @@ -1,768 +0,0 @@ -# 发送和接收消息 - - - -环信即时通讯 IM 的小程序 SDK 可以实现文本、图片、音频、视频和文件等类型的消息的发送和接收。 - -- 对于单聊,环信即时通信 IM 默认支持陌生人之间发送消息,即无需添加好友即可聊天。若仅允许好友之间发送单聊消息,你需要[开启好友关系检查](/product/enable_and_configure_IM.html#好友关系检查)。 - -- 对于群组和聊天室,用户每次只能向所属的单个群组和聊天室发送消息。 - -单聊、群组聊天和聊天室的消息发送控制,详见[消息发送控制](/product/product_message_overview.html#消息发送控制)文档。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 SDK 初始化,详见 [初始化文档](initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 - -## 发送和接收文本消息 - -1. 使用 `Message` 类创建并发送文本消息。 - -默认情况下,SDK 对单个用户发送消息的频率未做限制。如果你联系了环信商务设置了该限制,一旦在单聊、群聊或聊天室中单个用户的消息发送频率超过设定的上限,SDK 会上报错误,即错误码 509 `MESSAGE_CURRENT_LIMITING`。 - -```javascript -// 发送文本消息。 -function sendTextMessage() { - let option = { - // 消息类型。 - type: "txt", - // 消息内容。 - msg: "message content", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - // 会话类型:单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`,默认为单聊。 - chatType: "singleChat", - }; - // 创建文本消息。 - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该文本消息。 - conn.send(msg).then((res)=>{ - console.log("Send message success",res); - }).catch((e)=>{ - console.log("Send message fail",e); - }); -} -``` - -2. 你可以通过 `addEventHandler` 注册监听器监听消息事件。你可以添加多个事件。当不再监听事件时,请确保删除监听器。 - -当消息到达时,接收方会收到 `onTextMessage` 回调。每个回调包含一条或多条消息。你可以遍历消息列表,并可以解析和展示回调中的消息。 - -对于聊天室消息,你可以通过消息的 `broadcast` 属性判断该消息是否为[通过 REST API 发送的聊天室全局广播消息](/document/server-side/message_chatroom.html#发送聊天室全局广播消息)。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - onTextMessage: function (message) {}, - -}); -``` - -## 发送和接收附件消息 - -语音、图片、视频和文件消息本质上是附件消息。发送和接收附件消息的流程如下: - -1. 创建和发送附件类型消息。SDK 将附件上传到环信服务器,获取消息的基本信息以及服务器上附件文件的路径。 - - 对于图片消息来说,环信服务器会自动生成图片缩略图;而对于视频消息来说,视频的首帧为缩略图。 - -2. 接收附件消息。 - - 接收方可以自行下载语音、图片、图片缩略图、视频和文件。 - -对于消息附件,你也可以将附件上传到自己的服务器,而不是环信服务器,然后发送消息。这种情况下,需要在 SDK 初始化时将 [`Connection` 类中的 `useOwnUploadFun` 参数](https://doc.easemob.com/jsdoc/classes/Connection.Connection-1.html)设置为 `true`。例如,对于图片消息,上传附件后,调用 `sendPrivateUrlImg` 方法传入图片的 URL 发送图片消息。 - -```javascript -function sendPrivateUrlImg() { - let option = { - chatType: "singleChat", - // 消息类型。 - type: "img", - // 图片文件的 URL 地址。 - url: "img url", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - }; - // 创建一条图片消息。 - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该图片消息。 - conn.send(msg); -} -``` - -### 发送和接收语音消息 - -在发送语音消息前,你应该在 app 级别实现录音,提供录制的语音文件的 URI 和时长(单位为秒)。 - -1. 创建和发送语音消息。 - -```javascript -/** - * @param {Object} tempFilePath - 要上传的文件的小程序临时文件路径。 - * @param {Object} duration - 语音时长,单位为秒。 - */ -function sendPrivateAudio(tempFilePath, duration) { - var str = WebIM.config.appkey.split("#"); - var token = WebIM.conn.context.accessToken; - var domain = WebIM.conn.apiUrl; - wx.uploadFile({ - url: domain + "/" + str[0] + "/" + str[1] + "/chatfiles", - filePath: tempFilePath, - name: "file", - header: { - Authorization: "Bearer " + token - }, - success(res) { - var dataObj = JSON.parse(res.data); - var option = { - type: "audio", - chatType: "singleChat", - filename: tempFilePath, - // 消息接收方:单聊为对端用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - body: { - //文件 URL。 - url: dataObj.uri + "/" + dataObj.entities[0].uuid, - //文件类型。 - type: "audio", - //文件名。 - filename: tempFilePath, - // 音频文件时长,单位为秒。 - length: Math.ceil(duration / 1000), - }, - }; - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该语音消息。 - conn - .send(msg) - .then((res) => { - // 语音消息成功发送。 - console.log("Success"); - }) - .catch((e) => { - // 语音消息发送失败。 - console.log("Fail", e); - }); - }, - }); -} -``` - -2. 接收方收到 `onAudioMessage` 回调,根据消息 `url` 字段获取语音文件的服务器地址,从而获取语音文件。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - // 当前用户收到语音消息。 - onAudioMessage: function (message) { - // 语音文件在服务器的地址。 - console.log(message.url); - }, -}); - -``` - -### 发送和接收图片消息 - -发送和接收图片消息的流程如下: - -1. 创建和发送图片消息。 - -```javascript -function sendImage() { - var me = this; - wx.chooseImage({ - count: 1, - sizeType: ["original", "compressed"], - sourceType: ["album"], - success(res) { - me.sendPrivateImg(res); - }, - }); -} - -function sendPrivateImg(res) { - var me = this; - var tempFilePaths = res.tempFilePaths; - var token = WebIM.conn.context.accessToken; - wx.getImageInfo({ - src: res.tempFilePaths[0], - success(res) { - var allowType = { - jpg: true, - gif: true, - png: true, - bmp: true, - }; - var str = WebIM.config.appkey.split("#"); - var width = res.width; - var height = res.height; - var index = res.path.lastIndexOf("."); - var filetype = (~index && res.path.slice(index + 1)) || ""; - var domain = wx.WebIM.conn.apiUrl + "/"; - if (filetype.toLowerCase() in allowType) { - wx.uploadFile({ - url: domain + str[0] + "/" + str[1] + "/chatfiles", - filePath: tempFilePaths[0], - name: "file", - header: { - Authorization: "Bearer " + token - }, - success(res) { - if (res.statusCode === 400) { - // 图片上传阿里云检验不合法 - var errData = JSON.parse(res.data); - if (errData.error === "content improper") { - wx.showToast({ - title: "图片不合法", - }); - return false; - } - } - var data = res.data; - var dataObj = JSON.parse(data); - var option = { - type: "img", - chatType: "singleChat", - width: width, - height: height, - url: dataObj.uri + "/" + dataObj.entities[0].uuid, - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - }; - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该图片消息。 - conn - .send(msg) - .then((res) => { - // 图片消息成功发送。 - console.log("Success"); - }) - .catch((e) => { - // 图片消息发送失败。 - console.log("Fail"); - }); - }, - }); - } - }, - }); -} -``` - -2. 接收方收到 `onImageMessage` 回调,根据消息 `url` 字段获取图片文件的服务器地址,从而获取图片文件。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - onImageMessage: function (message) {}, -}); -``` - -### 发送和接收视频消息 - -在发送视频消息之前,应在 app 级别实现视频捕获以及捕获文件的上传。 - -1. 创建和发送视频消息。 - -```javascript -function sendPrivateVideo(){ - var me = this; - var token = WebIM.conn.context.accessToken - wx.chooseVideo({ - sourceType: ["album", "camera"], - maxDuration: 30, - camera: "back", - success(res){ - var tempFilePaths = res.tempFilePath; - var str = WebIM.config.appkey.split("#"); - var domain = wx.WebIM.conn.apiUrl + '/' - wx.uploadFile({ - url: domain + str[0] + "/" + str[1] + "/chatfiles", - filePath: tempFilePaths, - name: "file", - header: { - Authorization: "Bearer " + token - }, - success(res){ - var data = res.data; - var dataObj = JSON.parse(data); - var option = { - // 消息类型。 - type: "video", - // 会话类型:单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。 - chatType: "singleChat", - // 文件名。 - filename: "filename", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - body: { - //文件 URL。 - url:dataObj.uri + "/" + dataObj.entities[0].uuid, - //文件类型。 - type: "video", - //文件名称。 - filename: "filename", - }, - } - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该视频消息。 - WebIM.conn.send(msg).then((res)=>{ - // 视频消息成功发送。 - console.log("Success"); - }).catch((e)=>{ - // 视频消息发送失败。 - console.log("Fail"); - }); - } - }); - } - }); - }, -``` - - -2. 接收方收到 `onVideoMessage` 回调,根据消息 `url` 字段获取视频文件的服务器地址,从而获取视频文件。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - // 当前用户收到视频消息。 - onVideoMessage: function (message) { - // 视频文件在服务器的地址。 - console.log(message.url); - // 视频首帧缩略图文件在服务器的地址。 - console.log(message.thumb); - }, -}); -``` - -### 发送和接收文件消息 - -发送文件消息前,应先选择文件。微信小程序仅支持从客户端会话选择文件。 - -1. 创建和发送文件消息。 - -```javascript -// 发送文件消息。 -function sendFileMessage() { - const me = this; - // 微信小程序仅支持从客户端会话选择文件。 - wx.chooseMessageFile({ - // 可选择的最大文件数。 - count: 1, - success(res) { - const domain = wx.WebIM.conn.apiUrl + "/"; - const [orgName, appName] = WebIM.config.appkey.split("#"); - const token = WebIM.conn.context.accessToken; - const tempFiles = res.tempFiles[0]; - const fileName = tempFiles.name; - const fileSize = tempFiles.size; - const filePath = tempFiles.path; - const index = fileName.lastIndexOf("."); - const filetype = (~index && fileName.slice(index + 1)) || ""; - - // 上传文件到服务器。 - wx.uploadFile({ - url: domain + orgName + "/" + appName + "/chatfiles", - filePath: filePath, - name: "file", - header: { - Authorization: "Bearer " + token - }, - success(res) { - // 获取返回数据。 - let data = res.data; - let dataObj = JSON.parse(data); - let option = { - // 消息类型。 - type: "file", - // 单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。 - chatType: "singleChat", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "userId", - body: { - // 文件 URL。 - url: dataObj.uri + "/" + dataObj.entities[0].uuid, - // 文件类型。 - type: filetype, - // 文件名称。 - filename: fileName, - // 文件大小。 - file_length: fileSize - } - }; - - // 创建消息。 - const msg = WebIM.message.create(option); - // 发送消息。 - conn - .send(msg) - .then((res) => { - console.log(res, "send file message success"); - }) - .catch((e) => { - console.log(e, "send file message error"); - }); - } - }); - } - }); - } -``` - -2. 接收方收到 `onFileMessage` 回调,根据消息 `url` 字段获取文件的服务器地址,从而获取文件。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - // 当前用户收到文件消息。 - onFileMessage: function (message) { - // 文件在服务器的地址。 - console.log(message.url); - }, -}); - -``` - -## 发送和接收位置消息 - -发送和接收位置消息的流程如下: - -1. 创建和发送位置消息。 - -发送位置时,需要集成第三方的地图服务,获取到位置点的经纬度信息。 -```javascript -const sendLocMsg = () => { - let option = { - chatType: "singleChat", - type: "loc", - to: "username", - addr: "四通桥东", - buildingName: "数码大厦", - lat: 40, // 纬度 - lng: 116, // 经度 - }; - let msg = WebIM.message.create(option); - conn.send(msg).then((res)=>{ - console.log("Send message success",res); - }).catch((e)=>{ - console.log("Send message fail",e); - }); -}; -``` - -2. 接收方收到 `onLocationMessage` 回调,需要将该位置的经纬度,借由第三方的地图服务,将位置在地图上显示出来。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - onLocationMessage: function (message) {}, -}); -``` - -## 发送和接收透传消息 - -透传消息是通知指定用户采取特定操作的命令消息。接收方自己处理透传消息。 - -:::tip -透传消息发送后,不支持撤回。 -::: - -1. 创建和发送透传消息。 - -```javascript -function sendCMDMessage() { - let option = { - // 消息类型。 - type: "cmd", - // 会话类型:单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。 - chatType: "singleChat", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - // 自定义动作。对于透传消息,该字段必填。 - action: "action", - // 消息扩展信息。 - ext: { key: "extends messages" }, - }; - // 创建一条透传消息。 - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该透传消息。 - conn - .send(msg) - .then((res) => { - // 消息成功发送回调。 - console.log("Success"); - }) - .catch((e) => { - // 消息发送失败回调。 - console.log("Fail"); - }); -} -``` - -2. 接收方通过 `onCmdMessage` 回调接收透传消息。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - onCmdMessage: function (message) {}, -}); -``` - - -## 发送和接收自定义消息 - -自定义消息为用户自定义的键值对,包括消息类型和消息内容。 -发送和接收自定义消息的流程如下: - -1. 创建和发送自定义消息。 - -```javascript -function sendCustomMsg() { - // 设置自定义事件。 - let customEvent = "customEvent"; - // 通过键值对设置自定义消息内容。 - let customExts = {}; - let option = { - // 消息类型。 - type: "custom", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "username", - // 会话类型:单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。 - chatType: "singleChat", - customEvent, - // key 和 value 只支持字符串类型,否则客户端无法解析。 - customExts, - // 消息扩展字段,不能设置为空,即设置为 "ext:null" 会出错。 - ext: {}, - }; - // 创建一条自定义消息。 - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该自定义消息。 - conn - .send(msg) - .then((res) => { - // 消息成功发送回调。 - console.log("Success"); - }) - .catch((e) => { - // 消息发送失败回调。 - console.log("Fail"); - }); -} -``` - -2. 接收方通过 `onCustomMessage` 回调接收自定义消息。 - -```javascript -// 使用 `addEventHandler` 监听回调事件 -conn.addEventHandler("eventName", { - onCustomMessage: function (message) {}, -}); -``` - -## 发送和接收合并消息 - -为了方便消息互动,即时通讯 IM 自 4.2.0 版本开始支持将多个消息合并在一起进行转发。你可以采取以下步骤进行消息的合并转发: - -1. 利用原始消息列表创建一条合并消息。 -2. 发送合并消息。 -3. 对端收到合并消息后进行解析,获取原始消息列表。 - -:::tip - -该功能在 uniapp 中暂不支持运行到原生手机端。 - -::: -#### 创建和发送合并消息 - -你可以调用 `message.create` 方法创建一条合并消息,然后调用 `connection.send` 方法发送该条消息。 - -创建合并消息时,需要设置以下参数: - -| 属性 | 类型 | 描述 | -| :--------------------- | :---------------------------------------------- | :----------------------- | -| `chatType` | ChatType | 会话类型。 | -| `type` | 'combine' | 消息类型。 | -| `to` | String | 消息接收方。该字段的设置取决于会话类型:
- 单聊:对方用户 ID;
- 群聊:群组 ID;
- 子区会话:子区 ID;
- 聊天室聊天:聊天室 ID。 | -| `title` | String | 合并消息的标题。 | -| `summary` | String | 合并消息的概要。 | -| `compatibleText` | String | 合并消息的兼容文本。
兼容文本起向下兼容不支持消息合并转发的版本的作用。当支持合并消息的 SDK 向不支持合并消息的低版本 SDK 发送消息时,低版本的 SDK 会将该属性解析为文本消息的消息内容。 | -| `messageList` | MessagesType[] | 合并消息的消息列表。该列表最多包含 300 个消息。 | -| `onFileUploadComplete` | (data: { url: string; secret: string;}) => void | 合并消息文件上传完成的回调。 | -| `onFileUploadError` | (error: any) => void | 合并消息文件上传失败的回调。 | - -:::tip -1. 合并转发支持嵌套,最多支持 10 层嵌套,每层最多 300 条消息。 -2. 只有成功发送或接收的消息才能合并转发。 -::: - -示例代码如下: - -```javascript -let option = { - chatType: "singleChat", - type: "combine", - to: "userId", - compatibleText: "SDK 版本低,请升级", - title: "聊天记录", - summary: "hi", - messageList: [ - { - type: "txt", - chatType: "singleChat", - // ... - }, - ], - onFileUploadComplete: (data) => { - option.url = data.url; - }, -}; -let msg = WebIM.message.create(option); -conn.send - .send(msg) - .then((res) => { - console.log("发送成功", res); - }) - .catch((err) => { - console.log("发送失败", err); - }); -``` - -#### 接收和解析合并消息 - -接收合并消息与接收普通消息的操作相同,唯一不同是对于合并消息来说,消息接收事件为 `onCombineMessage`。 - -对于不支持合并转发消息的 SDK 版本,该类消息会被解析为文本消息,消息内容为 `compatibleText` 携带的内容,其他字段会被忽略。 - -合并消息实际上是一种附件消息。收到合并消息后,你可以调用 `downloadAndParseCombineMessage` 方法下载合并消息附件并解析出原始消息列表。 - -```javascript -connection - .downloadAndParseCombineMessage({ - url: msg.url, - secret: msg.secret, - }) - .then((res) => { - console.log("合并消息解析后的消息列表", res); - }); -``` - -## 发送和接收定向消息 - -发送定向消息是指向群组或聊天室的单个或多个指定的成员发送消息,其他成员不会收到该消息。 - -该功能适用于文本消息、图片消息和音视频消息等全类型消息,最多可向群组或聊天室的 20 个成员发送定向消息。 - -:::tip -1. 仅 SDK 4.2.0 及以上版本支持。 -2. 定向消息不写入服务端会话列表,不计入服务端会话的未读消息数。 -3. 群组定向消息的漫游功能默认关闭,使用前需联系商务开通。 -4. 聊天室定向消息的漫游功能默认关闭,使用前需联系商务开通聊天室消息漫游和定向消息漫游功能。 -::: - -发送定向消息的流程与发送普通消息相似,唯一区别是需要设置定向消息的接收方。 - -下面以文本消息为例介绍如何发送定向消息,示例代码如下: - -```javascript -// 发送定向文本消息。 -function sendTextMessage() { - let option = { - // 消息类型。 - type: "txt", - // 消息内容。 - msg: "message content", - // 消息接收方所在群组或聊天室的 ID。 - to: "groupId", - // 会话类型:群聊和聊天室分别为 `groupChat` 和 `chatRoom`。 - chatType: "groupChat", - // 消息的接收方列表。最多可传 20 个接收方的用户 ID。若不设置该字段或传入数组类型之外的值,如字符串,则消息发送给群组或聊天室的所有成员。 - receiverList: ['uId1','uId2'], - }; - // 创建文本消息。 - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该文本消息。 - conn.send(msg).then((res)=>{ - console.log("Send message success",res); - }).catch((e)=>{ - console.log("Send message fail",e); - }); -} -``` - -接收定向消息与接收普通消息的操作相同,详见各类消息的接收描述。 - -## 使用消息扩展 - -如果上述类型的消息无法满足要求,你可以使用消息扩展为消息添加属性。这种情况可用于更复杂的消息传递场景,例如消息中需要携带被回复的消息内容或者是图文消息等场景。 - -```javascript -function sendTextMessage() { - let option = { - type: "txt", - msg: "message content", - to: "username", - chatType: "singleChat", - // 设置消息扩展信息。扩展字段为可选,若带有该字段,值不能为空,即 "ext:null" 会出错。 - ext: { - key1: "Self-defined value1", - key2: { - key3: "Self-defined value3", - }, - }, - }; - let msg = WebIM.message.create(option); - // 调用 `send` 方法发送该扩展消息。 - conn - .send(msg) - .then((res) => { - console.log("send private text Success"); - }) - .catch((e) => { - console.log("Send private text error"); - }); -} -``` - -## 更多 - -### 设置聊天室消息优先级 - -针对聊天室消息并发量较大的场景,即时通讯服务提供消息分级功能。你可以通过设置消息优先级,将消息划分为高、普通和低三种级别。你可以在创建消息时,将指定消息类型,或指定成员的所有消息设置为高优先级,确保此类消息优先送达。这种方式可以确保在聊天室内消息并发量较大或消息发送频率过高的情况下,服务器首先丢弃低优先级消息,将资源留给高优先级消息,确保重要消息(如打赏、公告等)优先送达,以此提升重要消息的可靠性。请注意,该功能并不保证高优先级消息必达。在聊天室内消息并发量过大的情况下,为保证用户实时互动的流畅性,即使是高优先级消息仍然会被丢弃。 - -对于聊天室消息,可设置消息优先级,包括高、普通和低优先级。示例代码如下: - -```javascript -// 发送文本消息。 -function sendTextMessage() { - let option = { - type: "txt", - msg: "message content", - // 聊天室消息的优先级。如果不设置,默认值为 `normal`,即“普通”优先级。 - priority: "high" - to: "chat room ID", - chatType: "chatRoom", - }; - let msg = WebIM.message.create(option); - conn.send(msg).then(()=>{ - console.log("Send message success"); - }).catch((e)=>{ - console.log("Send message fail"); - }); -} -``` - -### 发送消息前的内容审核 - -- 内容审核关注消息 body - -[内容审核服务会关注消息 body 中指定字段的内容,不同类型的消息审核不同的字段](/product/moderation/moderation_mechanism.html),若创建消息时在这些字段中传入了很多业务信息,可能会影响审核效果。因此,创建消息时需要注意内容审核的字段不涉及业务信息,建议业务信息放在扩展字段中。 - -- 设置发送方收到内容审核替换后的内容 - -若初始化时打开了 `EMOptions#useReplacedMessageContents` 开关,发送文本消息时如果被内容审核(Moderation)进行了内容替换,发送方会收到替换后的内容。若该开关为关闭状态,则发送方不会收到替换后的内容。 \ No newline at end of file diff --git a/docs/document/applet/message_translation.md b/docs/document/applet/message_translation.md deleted file mode 100644 index 830f57d7..00000000 --- a/docs/document/applet/message_translation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/message_translation.html", - title: "翻译消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/moderation.md b/docs/document/applet/moderation.md deleted file mode 100644 index e5d5d987..00000000 --- a/docs/document/applet/moderation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/moderation.html", - title: "消息审核(举报)" -} ---- \ No newline at end of file diff --git a/docs/document/applet/multi_device.md b/docs/document/applet/multi_device.md deleted file mode 100644 index b90fa030..00000000 --- a/docs/document/applet/multi_device.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/multi_device.html", - title: "在多个设备上登录" -} ---- \ No newline at end of file diff --git a/docs/document/applet/overview.md b/docs/document/applet/overview.md deleted file mode 100644 index a75c72b2..00000000 --- a/docs/document/applet/overview.md +++ /dev/null @@ -1,37 +0,0 @@ -# 环信小程序全平台解决方案 - - - -环信小程序 SDK 为各端小程序开发提供一套完整的技术解决方案,在各端小程序的开发环境下,集成 IM 相关的功能更加便捷、高效。让您的小程序快速获得安全稳定的 IM 能力,集成简单,使用方便,帮助您快速拓展业务,赢得先机。 - -:::tip -SDK 目前支持微信、QQ、百度小程序、抖音、uni-app 编译的原生 Android 以及 iOS。 -::: - -## 体验小程序 - -扫描下方小程序二维码,或者微信搜索 **环信即时通讯云** 即可快速体验环信小程序 Demo 在线版本: - -![img](/images/applet/applet-demo.png) - -点击链接,扫描二维码,即可快速体验环信 Uniapp 编译生成的移动端原生应用: - -- 安卓: [https://www.pgyer.com/h4XF](https://www.pgyer.com/h4XF) -- iOS: [https://www.pgyer.com/9ISC](https://www.pgyer.com/9ISC) - -:::tip - -- 小程序 Demo 只包含部分 IM 功能,详细参考 **功能说明** -- 各小程序 Demo 源码可在官网 [下载页](https://www.easemob.com/download/im) 获取 -- Uni-app Demo Git 源码地址:[https://github.com/easemob/webim-uniapp-demo](https://github.com/easemob/webim-uniapp-demo) - ::: - -## 功能说明 - -环信小程序 Web IM 在微信生态系统进行优化,功能与微信对接更为流畅: - -- 支持账户注册登录 -- 支持 IM 基本功能收发文本、图片、语音、视频、音频、文件、透传、扩展消息等 -- 支持 群组、聊天室功能 -- 支持个人设置 -- 支持多人音视频功能(群组中可以进行多人音视频) diff --git a/docs/document/applet/presence.md b/docs/document/applet/presence.md deleted file mode 100644 index e61ea19c..00000000 --- a/docs/document/applet/presence.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/presence.html", - title: "在线状态订阅" -} ---- \ No newline at end of file diff --git a/docs/document/applet/push/push_extension.md b/docs/document/applet/push/push_extension.md deleted file mode 100644 index 1a73a098..00000000 --- a/docs/document/applet/push/push_extension.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/push/push_extension.html", - title: "设置推送扩展功能" -} ---- diff --git a/docs/document/applet/push/push_notification_mode_dnd.md b/docs/document/applet/push/push_notification_mode_dnd.md deleted file mode 100644 index 980925b6..00000000 --- a/docs/document/applet/push/push_notification_mode_dnd.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/push/push_notification_mode_dnd.html", - title: "设置推送扩展功能" -} ---- \ No newline at end of file diff --git a/docs/document/applet/push/push_overview.md b/docs/document/applet/push/push_overview.md deleted file mode 100644 index 45fe702a..00000000 --- a/docs/document/applet/push/push_overview.md +++ /dev/null @@ -1,44 +0,0 @@ -# 离线推送概述 - - - -即时通讯 IM 支持集成第三方消息推送服务,为开发者提供低延时、高送达、高并发、不侵犯用户个人数据的离线消息推送服务。 - -客户端断开连接或应用进程被关闭等原因导致用户离线时,即时通讯 IM 会通过第三方消息推送服务向该离线用户的设备推送消息通知。当用户再次上线时,服务器会将离线期间的消息发送给用户(这里角标表示的是离线消息数,并不是实际的未读消息数)。例如,当你离线时,有用户向你发送了消息,你手机的通知中心会弹出消息通知,当你再次打开 app 并登录成功,即时通讯 IM SDK 会主动拉取你不在线时的消息。 - -除了满足用户离线条件外,要使用第三方离线推送,用户还需在环信控制台配置推送证书信息,例如,对于华为推送,需配置**证书名称**和**推送密钥**,并调用客户端 Applet SDK 提供的 `uploadPushToken` 方法向环信服务器上传 device token。 - -**以下两种情况,即时通讯 IM 不会发送离线推送通知:** - -1. 若应用在后台运行,则用户仍为在线状态,即时通讯 IM 不会向用户推送消息通知。 - -2. 应用在后台运行或手机锁屏等情况,若客户端未断开与服务器的连接,则即时通讯 IM 不会收到离线推送通知。 - -**多设备离线推送策略** - -多设备登录时,可在[环信即时通讯控制台](https://console.easemob.com/user/login)的**证书管理**页面配置推送策略,该策略配置对所有推送通道生效: - -- 所有设备离线时,才发送推送消息; -- 任一设备离线时,都发送推送消息。 - -**注意**:多端登录时若有设备被踢下线,即使接入了 IM 离线推送,也收不到离线推送消息。 - -![image](/images/android/push/push_multidevice_policy.png) - -## Applet 端可设置的功能 - -**环信 IM Applet SDK 本身不支持离线推送,只支持对移动端离线推送进行如下配置**: - -- 设置推送通知,包括推送通知方式和免打扰模式: - - 设置 app 的推送通知; - - 获取 app 的推送通知设置; - - 设置会话的推送通知; - - 获取一个或多个会话的推送通知设置; - - 清除会话的推送通知方式的设置。 -- 设置推送翻译。 -- 设置推送模板。 -- 设置推送扩展功能:包括强制推送和发送静默消息。 - -其中,**推送高级功能包括设置推送通知方式、免打扰模式和自定义推送模板**。使用前,你需要在 [环信即时通讯控制台](https://console.easemob.com/user/login)的**即时通讯 > 功能配置 > 功能配置总览**页面激活。如需关闭推送高级功能必须联系商务,因为该操作会删除所有相关配置。 - -![image](/images/web/push_web_enable_push.png) diff --git a/docs/document/applet/push/push_template.md b/docs/document/applet/push/push_template.md deleted file mode 100644 index f5c2e007..00000000 --- a/docs/document/applet/push/push_template.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/push/push_template.html", - title: "设置推送模板" -} ---- \ No newline at end of file diff --git a/docs/document/applet/push/push_translation.md b/docs/document/applet/push/push_translation.md deleted file mode 100644 index d5d2a56a..00000000 --- a/docs/document/applet/push/push_translation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/push/push_translation.html", - title: "设置推送翻译" -} ---- diff --git a/docs/document/applet/push/uniapp_push.md b/docs/document/applet/push/uniapp_push.md deleted file mode 100644 index ddd61171..00000000 --- a/docs/document/applet/push/uniapp_push.md +++ /dev/null @@ -1,169 +0,0 @@ -# Uni-app 离线推送 - -环信 uni-app 原生推送插件集成了第三方离线消息推送服务, 为开发者提供低延时、高送达、高并发、不侵犯用户个人数据的离线消息推送服务。当客户端断开连接或应用进程被关闭等原因导致用户离线时,即时通讯 IM 会通过第三方消息推送服务向该离线用户的设备推送消息通知。 - -目前支持的手机厂商推送服务包括:华为、荣耀、小米、OPPO、vivo ,魅族和 APNs。 - -## 前提条件 - -1. 已开启环信即时通讯服务,详见 [开启和配置即时通讯服务](/product/enable_and_configure_IM.html)。 -2. 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -3. 你已在 [环信即时通讯控制台](https://console.easemob.com/user/login)的**即时通讯 > 功能配置 > 功能配置总览**页面激活推送高级功能。高级功能激活后,你可以设置推送通知方式、免打扰模式和自定义推送模板。**如需关闭推送高级功能必须联系商务,因为该操作会删除所有相关配置。** -4. 各推送使用的条件: - - 小米推送:在小米设备上可用; - - 华为推送:在华为设备上可用; - - 魅族推送:在魅族设备上可用; - - OPPO 推送:在 OPPO 设备上可用; - - vivo 推送:在 vivo 设备上可用; - - 荣耀 推送:在荣耀设备上可用; - - APNS 推送:在苹果设备上可用。 - -插件内部会按照以上顺序检测设备的推送支持情况。如果未设置第三方推送或者不满足使用第三方推送的条件,环信 IM SDK 会通过一些保活手段尽可能的保持与环信服务器的长连接,以确保消息及时送达。 - -## 实现流程 - -### 步骤一 上传推送证书至环信即时通讯控制台 - -1. 在第三方推送服务后台注册应用,获取应用信息,开启推送服务。 - -2. 在[环信即时通讯云控制台](https://console.easemob.com/user/login)配置获取到的应用信息,上传推送证书,实现第三方推送服务与环信即时通讯 IM 的通信。 - -:::tip -更多详情,参见 [Android 离线推送](/document/android/push/push_fcm.html)和 [APNs 离线推送](/document/ios/push/push_apns.html)。 -::: - -### 步骤二 配置 uni-app 应用支持推送插件 - -1. 新建 uni-app 工程,并引入[环信 uni-app 推送插件](https://downloadsdk.easemob.com/downloads/WEB_SDK/EMPushUniPlugin_V1.0.0.zip)。 - -在你的 uni-app 应用根目录下新建 `nativeplugins` 文件夹,然后将下载的插件放置于 `nativeplugins` 文件夹下。如下图所示: - - ![img](/images/applet/push_tip.png) - -:::tip -华为注册厂商推送服务时,包含 `agconnect-services.json` 文件。你需下载该文件,并将其放至你的 uni-app 应用根目录下的 `nativeplugins/EMPushUniPlugin/android/assets` 文件夹下。 -::: - -2. 配置 uni-app 项目支持推送。选择 **App模块配置**,勾选 **Push(消息推送)**。 - - ![img](/images/applet/push_tip1.png) - -:::tip -不要勾选 **uniPush 1.0** 或者 **uniPush 2.0**。 -::: - -3. 添加 `EMPushUniPlugin` 原生插件, 并配置需要推送的第三方厂商应用信息。 - -![img](/images/applet/push_tip2.png) - -:::tip -请配置第三方厂商推送相关信息。 -::: - -![img](/images/applet/push_tip3.png) - -4. 生成自定义基座。 - -自定义基座是 uni-app 应用运行的底层原生环境。当应用程序使用了原生层插件(如推送插件等),这些插件需要在原生环境中执行,这时就必须打包自定义基座。 - -:::tip -- 配置原生插件,必须打包自定义基座进行测试。 -- 打包自定义基座时,需要提供安卓/苹果平台签名证书。安卓平台签名证书是开发者后续更新升级已发布 APK 的凭证。开发者需要自行生成证书文件并保管,具体请参考[Android 平台签名证书(.keystore)生成指南](https://ask.dcloud.net.cn/article/35777)和[iOS 证书(.p12)和描述文件(.mobileprovision)申请](https://ask.dcloud.net.cn/article/152)。 -::: - -- 制作自定义调试基座: - -![img](/images/applet/push_tip4.png) - -- 配置 Android 基座打包信息: - -![img](/images/applet/push_tip5.png) - -- 配置 iOS 基座打包信息: - -![img](/images/applet/push_tip6.png) - -### 步骤三 集成 EMPushUniPlugin 插件 - -:::tip -SDK 4.9.1 及以上版本支持 uni-app 推送。 -::: - -1. 安装并引入环信 uni-app SDK。 - -```javascript -// 安装环信 SDK -npm install easemob-websdk -// 在 App.vue 文件中引入 SDK -import websdk from "easemob-websdk/uniApp/Easemob-chat"; -``` - -2. 初始化 IM SDK 并集成推送插件。 - -```javascript -// 初始化 IM SDK -const conn = websdk.connection({ - appKey: 'xxxxx', // 你的环信 app Key - isFixedDeviceId: true // 推荐使用固定的设备 ID, SDK 会默认从本地缓存中获取设备ID -}); - -// #ifdef APP-PLUS -// 引入 EMPushUniPlugin 推送插件 -const EMPushUniPlugin = uni.requireNativePlugin('EMPushUniPlugin'); - -// 配置推送插件 -const pushOption = { - // @ts-ignore - emPush: EMPushUniPlugin, - // 配置需要推送的证书名称 - config: { - MICertificateName: 'xxxxxx', // 小米推送证书名称 - OPPOCertificateName: 'xxxxxx', // oppo 推送证书名称 - HMSCertificateName: 'xxxxxx', // 华为推送证书名称 - VIVOCertificateName: 'xxxxxx',// vivo 推送证书名称 - HONORCertificateName: 'xxxxxx',// 荣耀推送证书名称 - MEIZUCertificateName: 'xxxxxx', // 魅族推送证书名称 - APNsCertificateName: 'xxxxxx', // APNs推送证书名称 - } -} - -// 调用 IM SDK 方法,注册推送插件 -conn.usePlugin({ - pushOption, - 'push' // 为固定值 -}) -// #endif - -// 如果退出 IM 登录、多设备互踢时, 需要解绑 device token, 可以调用该方法 -const unbindPushToken = () => { - conn.unbindPushToken() -} - -// 在 uniapp onLaunch 事件中初始化推送插件 -onLaunch(() => { - // #ifdef APP-PLUS - EMPushUniPlugin.initPushModule(); - // #endif -}); - -``` - -### 步骤四 测试离线推送 - -消息接收方登录 IM 账户后,SDK 会自动上传对应的推送证书, 杀死应用,收到离线消息,能够接收到推送消息。 - -## 常见问题 - -1. 即时通讯 IM 在哪些情况不会发送离线推送通知? - -- 若应用在后台运行,则用户仍为在线状态,即时通讯 IM 不会向用户推送消息通知。 - -- 应用在后台运行或手机锁屏等情况,若客户端未断开与服务器的连接,则即时通讯 IM 不会收到离线推送通知。 - -2. 即时通讯 IM 是否支持多设备离线推送? - -你可在[环信即时通讯控制台](https://console.easemob.com/user/login)的**证书管理**页面配置多设备推送策略。该策略配置对所有推送通道生效: - -- 所有设备离线时,才发送推送消息; -- 任一设备离线时,都发送推送消息。 - diff --git a/docs/document/applet/qq.md b/docs/document/applet/qq.md deleted file mode 100644 index 8d7c85e7..00000000 --- a/docs/document/applet/qq.md +++ /dev/null @@ -1,109 +0,0 @@ -# QQ 小程序集成介绍 - - - -## 前提条件 - -### 注册环信账号 - -开发者需要在环信管理后台 [注册并创建应用](/product/enable_and_configure_IM.html#创建应用),来获取唯一 appKey,SDK 初始化时需要配置 appKey。 - -## 实现步骤 - -### 搭建 QQ 小程序开发环境 - -首先需要下载并安装 [开发者工具](https://q.qq.com/wiki/tools/devtool/),然后按照 QQ 小程序的 [接入流程](https://q.qq.com/wiki/#_2-注册开发者平台) 一步步创建一个小程序 - -### 配置服务器域名 - -小程序在发布前,需要配置合法域名。 - -登录 QQ 小程序 [开发者平台](https://q.qq.com/),进入 “开发 > 开发设置” 页面配置以下服务器地址。 - -:::tip -request 合法域名: - -1. https://a1.easemob.com -2. https://a2.easemob.com -3. https://a3.easemob.com -4. https://a4.easemob.com -5. https://a5.easemob.com -6. https://rs.chat.agora.io -7. https://rs.easemob.com -::: - -:::tip -socket 合法域名: -wss://im-api-wechat.easemob.com(3.0 IM SDK) -::: - -:::tip -为满足不同客户的业务需求,环信在多地部署了数据中心。不同数据中心的 REST API 请求域名、WebSocket 访问域名不同。请根据您所在数据中心进行配置。 -::: - -环信不同数据中心的 REST API 请求域名、WebSocket 访问域名: - -| 数据中心 | REST API 请求地址 | WebSocket 访问域名 | -| ------------- | ------------------ | -------------------------------- | -| 国内 1 区 | a1.easemob.com | im-api-wechat.easemob.com 或 im-api-wechat.easecdn.com | -| 国内 2 区 | a31.easemob.com | im-api-wechat-31.easemob.com 或 im-api-wechat-31.easecdn.com | -| 国内 VIP 区 | 请咨询商务经理 | 请咨询商务经理 | -| 客服专用 | 请咨询商务经理 | 请咨询商务经理 | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | im-api-wechat-sgp.easemob.com 或 im-api-wechat-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | im-api-wechat-61.easemob.com 或 im-api-wechat-61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | im-api-wechat-41.easemob.com 或 im-api-wechat-41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | im-api-wechat-71.easemob.com 或 im-api-wechat-71.easecdn.com | - -应用所在数据中心可以在环信用户管理后台 > **即时通讯** > **服务概览**中查看: - -![img](/images/applet/service_overview.png) - -### 说明 - -QQ、微信小程序: 1.7.0 及以上版本,最多可以同时存在 5 个 WebSocket 连接,需开发者控制好连接数量,超出此限制 SDK 将不能连接上服务器。 - -### 集成 SDK - -#### 下载 SDK - -可以通过以下两种方式获取 SDK: - -- 通过官网 [下载 SDK](https://www.easemob.com/download/im) -- 从环信的 [github 仓库](https://github.com/easemob/webim-weixin-xcx/tree/master/src/sdk) 中获取 SDK 中的文件 - -#### 引入 SDK - -- 开始一个全新的项目 - 1. 将下载的 SDK(src/sdk/)导入到自己的项目中。 - 2. 引入 SDK:`import IMSDK from "../sdk/Easemob-chat-miniProgram";` -- 基于 Demo 二次开发 - -将下载的代码导入开发者工具即可运行起来。 - -#### 调用示例 - -```javascript -// 使用示例 -import SDK from "../sdk/connection"; // 2.0 SDK -import SDK from "../sdk/Easemob-chat-miniProgram"; // 3.0 SDK -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -// 实例化 SDK 对象 -const WebIM = (wx.WebIM = SDK); -WebIM.conn = new WebIM.connection({ - appKey: "your appKey", - https: true, //是否使用HTTPS - url: "wss://im-api-wechat.easemob.com/websocket", // socket server (3.0 SDK) - apiUrl: "https://a1.easemob.com", // rest server - heartBeatWait: 30000, //心跳间隔 - autoReconnectNumMax: 5, //自动重连次数 - useOwnUploadFun: false, // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传 URL) -}); -``` - -IM 基本功能和 Web 端一致,请参考 Web 端文档。 diff --git a/docs/document/applet/reaction.md b/docs/document/applet/reaction.md deleted file mode 100644 index 51048e60..00000000 --- a/docs/document/applet/reaction.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/reaction.html", - title: "消息表情回复 Reaction" -} ---- \ No newline at end of file diff --git a/docs/document/applet/releasenote.md b/docs/document/applet/releasenote.md deleted file mode 100644 index 301ff53d..00000000 --- a/docs/document/applet/releasenote.md +++ /dev/null @@ -1,560 +0,0 @@ -# 小程序 SDK 更新日志 - - - -## 版本 V4.11.0 Dev 2024-12-3(开发版) - -### 新增特性 - -- [IM SDK] 新增[拉取服务器漫游消息](message_retrieve.html#从服务器获取指定会话的消息)时会读取服务端的消息已读和送达状态。该功能只适用于单聊消息,默认关闭,如果需要,请联系环信商务开通。 -- [IM SDK] 聊天室禁言回调 `muteMember` 新增 `muteTimestamp` 参数,表示禁言过期时间。 -- [IM SDK] 群组/聊天室禁言事件 `muteMember` 新增 `userId` 字段,表示被禁言的成员。 -- [IM SDK] uniapp SDK 支持鸿蒙系统。 - -### 优化 - -[IM SDK] SDK 的 message 对象中新增 `parseDownloadResponse`、`download` 方法。目前,SDK 的 utils 对象和 message 对象中均包含 `parseDownloadResponse`、`download` 方法。 - -### 修复 - -[IM SDK] 修复消息置顶事件 `onMessagePinEvent` 中的 `conversationId` 参数值错误的问题。 - -## 版本 V4.10.0 2024-10-11(开发版) - -### 新增特性 - -- 聊天室公告修改事件中增加公告内容:`updateAnnouncement` 事件中增加 `announcement` 字段,表示更新的公告。 -- 新增两个[错误码](error.html): - - `WEBIM_USER_ALREADY_LOGIN` 208:用户已登录。单设备登录时,若调用登录方法 `open` 时用户已经登录,会触发该错误。 - - `MESSAGE_SEND_TIMEOUT` 512:发送消息超时。例如,发消息时连接断开,会提示该错误。 -- 新增 `onShow` 方法,小程序或 uniapp 在 `onShow` 生命周期中执行该方法,可优化重连速度。 - -### 优化 - -调整了登录方法的 `open().then` 与连接成功事件 `onConnected` 的触发时机。优化后,调用登录方法 `open` 后,先触发连接成功与否的事件 `onConnected` 或 `onDisconnected`,然后再触发登录 `open().then` 或者 `open().catch`,以确保连接完全建立后再进行后续处理。之前版本为调用登录方法,先触发登录回调,然后触发连接事件,导致需要等待连接成功事件 `onConnected` 触发后才能发送消息。同时,优化后,鉴权失败等登录错误会在 `open.catch` 中抛出。 - -## 版本 V4.9.2 2024-09-20(开发版) - -### 新增特性 - -- [IM SDK] `removeHistoryMessages` 方法[支持单向删除服务端的聊天室消息](message_delete.html#单向删除服务端的历史消息)。 - -## 版本 V4.9.1 Dev 2024-09-06(开发版) - -### 新增特性 - -- [IM SDK] uni-app SDK 支持 [uni-app 推送插件](/document/applet/push/uniapp_push.html)。 - -### 修复 - -- [IM SDK] 修复一些类型问题。 - -## 版本 V4.8.1 Dev 2024-07-17(开发版) - -### 新增特性 - -- [IM SDK] 新增[日志上报](initialization.html#日志上报)功能, 即将日志会上传到环信的服务器。该功能默认关闭,如有需要, 可联系商务开通。 - -## 版本 V4.8.0 Dev 2024-07-01(开发版) - -### 新增特性 - -- [IM SDK] [`onDisconnected` 事件](initialization.html#连接状态相关)新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。 -- [IM SDK] 新增[设备登录时允许携带自定义消息,并将其传递给被踢的设备](multi_device.html#设置登录设备的扩展信息): - - `setLoginInfoCustomExt`:设置登录设备的扩展信息。 - - `onDisconnected`:多设备登录场景下,若当前设备被新登录设备踢下线,被踢设备收到的事件中会携带新设备的扩展信息。 -- [IM SDK] 支持[加入聊天室时携带扩展信息、是否退出之前加入的全部聊天室](room_manage.html#加入聊天室): - - `joinChatRoom` 方法新增 `ext` 和 `leaveOtherRooms` 参数,支持设置加入聊天室时携带的扩展信息,并指定是否退出所有其他聊天室。 - - `ChatroomEvent` 新增 `ext` 扩展字段,当用户加入聊天室携带了扩展信息时,聊天室内其他人可以在用户加入聊天室的回调中,获取到扩展信息。 -- [IM SDK] 新增 `ConnectionParameters#isFixedDeviceId` 初始化参数,默认为 `true`,[使用固定的设备 ID](multi_device.html)。之前,每个 SDK 实例连接时,SDK 默认均使用不同的随机字符串作为设备标识。 -- [IM SDK] `destroyChatRoom` 方法[支持聊天室所有者解散聊天室](room_manage.html#解散聊天室)。 - -## 版本 V4.7.0 Dev 2024-04-30(开发版) - -### 新增特性 - -- [IM SDK] 新增 `getJoinedChatRooms` 方法,用于[获取当前用户加入的聊天室列表](room_manage.html#获取当前用户加入的聊天室列表)。 -- [IM SDK] [撤回消息](message_recall.html#实现方法)接口 `recallMessage` 中新增 `ext` 参数,支持传入自定义字符串,设置扩展信息。 -- [IM SDK] SDK logger 中新增 `setConsoleLogVisibility` 方法,用于[设置日志是否输出到控制台](initialization.html#输出信息到日志文件)。 - -### 修复 - -- [IM SDK] 修复消息 `allowGroupAck` 状态错误问题。 - -## 版本 V4.6.0 Dev 2024-04-02(开发版) - -### 新增特性 - -- [IM SDK] 新增[置顶消息功能](message_pin.html)。 - - `pinMessage`: 置顶消息。 - - `unpinMessage`: 取消置顶消息。 - - `getServerPinnedMessages`:从服务器获取指定会话的置顶消息。 - - `onMessagePinEvent`: 当用户在群组或聊天室会话进行置顶操作时,群组或聊天室中的其他成员会收到该回调。 -- [IM SDK] 消息修改回调 `onModifiedMessage` 中支持返回[通过 RESTful API 修改的自定义消息](/document/server-side/message_modify_text_custom.html)。 -- [IM SDK] 支持[获取聊天室漫游消息](message_retrieve.html#从服务器获取指定会话的消息)。 - -### 优化 - -- [IM SDK] 优化 Token 登录时的错误提示信息,使错误提示更精细。 - -### 修复 - -- [IM SDK] 修复消息 `onlineState` 状态错误问题。 - -## 版本 V4.5.1 Dev 2024-02-22(开发版) - -### 优化 - -- [IM SDK] 统一消息附件的 URL 格式。 - -### 修复 - -- [IM SDK] 修复 uni-app SDK 运行到 iOS 平台发送群组定向消息报错的问题。 - -## 版本 V4.5.0 Dev 2024-01-30(开发版) - -### 新增特性 - -- [IM SDK] [聊天室和群组成员进出事件增加成员人数 `memberCount` 字段](room_manage.html#实时更新聊天室成员人数)。 -- [IM SDK] 新增 [deleteAllMessagesAndConversations](message_delete.html#单向清空服务端的聊天记录) 方法, 用于清空当前用户的聊天记录,包括消息和会话。 -- [IM SDK] 新增 [getSelfIdsOnOtherPlatform](multi_device.html#获取当前用户的其他登录设备的登录-id-列表) 方法, 可以获取当前用户其他登录设备的登录 ID 列表,实现对指定设备发送消息。 -- [IM SDK] 新增 [useReplacedMessageContents](message_send_receive.html#发送和接收文本消息) 开关。开启后,发送消息时如果被内容审核进行了内容替换,发送方可以获取替换后的内容。 - -### 优化 - -- [IM SDK] 抖音小程序重连缓慢。 -- [IM SDK] 格式化会话列表中最近一条自定义消息的 `customExts` 字段。 -- [IM SDK] 重复拉消息问题。 - -### 修复 - -- [IM SDK] 修复 `onMessage` 回调消息顺序异常问题。 - -## 版本 V4.4.0 Dev 2023-12-22(开发版) - -### 新增特性 - -- [IM SDK] 新增[会话标记功能](conversation_mark.html)。 - - `addConversationMark`:[标记会话](conversation_mark.html#标记会话)。 - - `removeConversationMark`:[取消标记会话](conversation_mark.html#取消标记会话)。 - - `getServerConversationsByFilter`:[根据会话标记从服务器分页查询会话列表](conversation_mark.html#根据会话标记从服务器分页查询会话列表)。 - - `onMultiDeviceEvent#markConversation/unMarkConversation`:[多设备场景下的会话标记事件](multi_device.html#实现方法)。当前用户在一台登录设备上更新了会话标记,包括添加和移除会话标记,其他登录设备会收到该事件。 -- [IM SDK] 增加 `onMessage` 回调。在收到文本、图片、视频、语音、地理位置和文件等消息时,批量将消息回调给应用。 - -### 修复 - -- [IM SDK] SDK 类型修正。 - -## 版本 V4.3.0 Dev 2023-11-17 - -### 新增特性 - -- [IM SDK] 新增[好友备注功能](user_relationship.html#设置好友备注)。 -- [IM SDK] 消息结构新增 `broadcast` 字段, 用于判断该消息是否为聊天室全局广播消息。可通过[调用 REST API 发送聊天室全局广播消息](/document/server-side/message_chatroom.html#发送聊天室全局广播消息)。 - -### 优化 - -- [IM SDK] Token 登录增加即将过期及已过期的回调,即 Token 已过期或有效期过半时也触发 `onTokenExpired` 和 `onTokenWillExpire` 回调。 - -### 修复 - -- [IM SDK] 修复会话列表最后一条消息中获取不到 `reaction` 的问题。 - -## 版本 V4.2.1 Dev 2023-09-27 - -### 新增特性 - -- [IM SDK] 用户申请加群被拒绝的回调 `joinPublicGroupDeclined` 中增加申请人的用户 ID。 - -## 版本 V4.2.0 Dev 2023-07-27 - -### 新增特性 - -- [IM SDK] 新增[合并转发消息功能](message_send_receive.html#发送和接收合并消息)。 -- [IM SDK] 新增[消息修改功能](message_modify.html)。 -- [IM SDK] 新增[在群组或聊天室会话中发送定向消息](message_send_receive.html#发送和接收定向消息)。通过在构建消息的方法 `create` 中添加 `receiverList` 参数实现该特性。 - -### 修复 - -修复发送不必要的消息送达回执的问题。 - -## 版本 V4.1.6 Dev 2023-04-17 - -### 新增特性 - -- [IM SDK] `getHistoryMessages` 方法的 `searchOptions` 中新增 `from`、`msgTypes`、`startTime` 和 `endTime` 参数,允许用户按消息发送方、消息类型或时间段从服务端拉取历史消息。 -- [IM SDK] 新增错误码 511,即 MESSAGE_SIZE_LIMIT,若[消息体大小超过限制](message_overview.html#消息类型)时提示用户。 - -## 版本 V4.1.4 Dev 2023-03-16 - -### 新增特性 - -- [IM SDK] 新增 [群成员自定义属性功能](group_members.html#管理群成员自定义属性)并增加[自定义属性更新事件](group_manage.html#监听群组事件)实现群成员设置和获取在群组中的昵称和头像等属性。 -- [IM SDK] 在消息创建参数中新增 `deliverOnlineOnly` 字段实现发消息只投递给在线用户。若开启了该功能,用户离线时消息不投递。 -- [IM Demo] 新增群成员昵称修改与展示功能。 - -### 优化 - -[IM SDK] 优化聊天室进入和退出实现,提升性能。 - -### 修复 - -- [IM SDK] 修复 TypeScript 代码的一些类型错误。 -- [IM SDK] 修复 `getHistoryMessages` 方法无法捕获错误的问题。 - -## 版本 V4.1.3 Dev 2023-02-21 - -#### 新增特性 - -- [IM SDK] 在 `getConversationlist` 方法中新增分页参数 `pageNum` 和 `pageSize`,支持[分页方法获取会话列表](conversation_list.html#从服务器分页获取会话列表)。 -- [IM SDK] 新增[群组创建事件 `create`](group_manage.html#监听群组事件)。群组创建后,群主的其他设备会收到该事件。 - -#### 优化 - -- [IM SDK] 缩减 MiniCore 的大小。 -- [IM SDK] 优化重连逻辑。 - -#### 修复 - -- [IM SDK] 修复 TypeScript 代码的一些类型错误。 -- [IM SDK] 修复 `getConversationlist` 方法的返回值缺少 `customExts` 字段的问题。 -- [IM SDK] 修复设置 `useOwnUploadFun` 允许用户自己上传图片时图片消息中的 `size` 字段不生效的问题。 - -## 版本 V4.1.2 Dev 2022-11-08 - -### 新增特性 - -- [IM SDK] [创建群组方法 `createGroup`](group_manage.html#创建群组) 和[修改群信息方法 `modifyGroup`](group_attributes.html#修改群组信息) 新增 `ext` 字段支持群扩展信息。 -- [IM SDK] 群组通知事件增加[群组信息修改事件 `updateInfo`](group_manage.html#监听群组事件)。 -- [IM SDK] 新增[聊天室消息优先级](#设置聊天室消息优先级)。 -- [IM SDK] 支持同时[对多个群组成员禁言和解除禁言](group_members.html#管理群组禁言)。 - -## 版本 V4.1.1 Dev 2022-9-26 - -### 修复 - -修复聊天室自定义属性功能中的问题。 - -## 版本 V4.1.0 Dev 2022-9-16 - -### 新增特性 - -- [IM SDK] 新增[聊天室自定义属性功能](room_attributes.html)。 -- [IM SDK] 新增 `onLog` 方法,实现用户日志回调。 -- [IM SDK] `getJoinedGroups` 方法中新增 `needAffiliations` 和 `needRole` 参数支持获取群组成员数和用户自己的角色。 - -### 优化 - -- 增加内嵌文档。 -- 优化重连逻辑。 - -### 修复 - -[IM SDK] 修复 IM Uniapp 在手机上运行时上报 `addEventListener` 方法相关错误的问题。 - -## 版本 V4.0.9 2022-7-29 - -### 新增特性 - -- [IM SDK] 优化协议,减少数据量。 -- [IM SDK] SDK 内部在群组聊天室部分 API 请求时增加 `resourceId`,增加操作的多设备通知提醒。 -- [IM SDK] [getJoinedGroups](/document/web/group_manage.html#获取群组列表) 方法中增加请求参数支持返回群组成员人数和自己的角色。 - -## 版本 V4.0.8 2022-6-17 - -### 新增特性 - -- [IM SDK] 新增群组事件回调 [onGroupEvent](https://doc.easemob.com/jsdoc/interfaces/Types.EventHandlerType.EventHandlerType.html#onGroupEvent) 和聊天室事件回调 [onChatroomEvent](https://doc.easemob.com/jsdoc/interfaces/Types.EventHandlerType.EventHandlerType.html#onChatroomEvent)。原回调可继续使用; -- [IM SDK] 新增群聊消息限流错误码 [MESSAGE_CURRENT_LIMITING](/document/web/error.html) -- [IM SDK] 邀请加入群聊回调 `onGroupChange` 返回中新增 群名称 参数值。 - -### 优化 - -- [IM SDK] 支持批量查询群组详情 [getGroupInfo](/document/web/group_manage.html#获取群组详情信息)。 - -## 版本 V4.0.7 2022-5-25 - -### 新增特性: - -- [IM SDK] 新增消息子区(message thread)功能; -- [IM SDK] 新增 [getConversationList](/document/web/conversation_list.html) 方法解析会话中的最新一条消息; - -### 优化: - -- [IM SDK] 消息事件监听器中新增 onlineState 字段标记离线消息。 - -## 版本 V4.0.5 2022-5-16 - -### 新增特性: - -- [IM SDK] 新增举报 API 用于内容审核; -- [IM SDK] 新增推送设置 API,支持不同的推送配置; -- [IM SDK] 增加数据上报功能; -- [IM SDK] 新增获取加入的群组支持分页 API; - -### 优化: - -- [IM SDK] 创建群组时,支持设置群组人数; -- [IM SDK] 接收到的图片消息增加缩略图 URL; - -### 修复: - -- [IM SDK] 解决切换账号群组消息有缓存的 BUG。 - -## 版本 V4.0.4 2022-4-19 - -:::tip -仅 V4.0.4 及以下版本支持私有化部署。 -::: - -### 新增特性: - -- [IM SDK] 增加用户在线状态(Presence)订阅功能。 -- [IM SDK] 增加自动翻译接口。除了按需翻译,IM 实现自动翻译。 - -### 优化: - -- [IM SDK] 小程序不需要 isHttpDNS 参数。 - -### 修复: - -- [IM SDK] 修复 Uni_SDK 无法运行到浏览器问题。 -- [IM SDK] 修复创建群组时无法修改群简介问题。 -- [IM SDK] 修复 SSR 兼容性。 - -## 版本:v4.0.3 2022-1-19 - -- [IM SDK] 'fetchGroupSharedFileList' 支持分页。 -- [IM SDK] 默认关闭 DNS。 - -## 版本:v4.0.2 2022-1-14 - -- [IM SDK] 增加删除会话 API。 -- [IM SDK] 位置消息增加 “buildingName” 字段。 -- [IM SDK] 增加非好友发消息失败 error。 -- [IM SDK] 增加因全局禁言发消息失败 error。 -- [IM SDK] 增加支持钉钉小程序。 -- [IM SDK] 修复不回调 “onChannelMessage” 事件 bug。 -- [IM SDK] 修复其他已知错误。 - -## 版本:v4.0.1 2021-12-10 - -- [IM SDK] 修复类型错误。 -- [IM SDK] 修复收不到 delivery ack。 -- [IM SDK] 修复群公告不能设为空。 -- [IM SDK] 修复聊天中禁言报错。 -- [IM SDK] 更新部分函数命名与注释。 -- [IM SDK] 增加部分错误码。 - -## 版本:v4.0.0 2021-10-22 - -- [IM SDK] 支持 typescript -- [IM SDK] 发送消息、好友操作支持 Promise -- [IM SDK] 支持使用 agora token 登录 -- [IM SDK] 增加新的事件监听方式 eventHandler -- [IM SDK] 增加新的构造消息 API -- [IM SDK] 优化部分 API,减少不必要参数,增加错误提示。 -- [IM SDK] 修复部分已知 bug - -## 版本:v3.6.3 2021-07-30 - -- [IM SDK] 增加下载文件验证 secret 功能 -- [IM SDK] 增加发送消息被自定义拦截的错误类型 -- [IM SDK] 优化漫游消息 api, 增加 start 参数,指定开始拉取消息的位置 -- [IM SDK] 修复百度小程序兼容问题 -- [IM SDK] 登录上报区分不同小程序 - -## 版本:v3.6.2 2021-07-08 - -- [IM SDK] 修复 ios14.5 以上小程序如果使用插件导致 SDK 登录不成功 - -## 版本:v3.6.0 2021-06-30 - -- [IM SDK] 更新 dnsconfig -- [IM SDK] 启用 dns 的情况下使用动态端口 -- [IM SDK] 优化输出日志 -- [IM SDK] 修复重连问题 - -## 版本:v3.5.1 2021-04-14 - -- [IM SDK] 增加用户属性功能 [用户属性](https://docs-im.easemob.com/im/web/basics/profile) -- [IM SDK] 增加修改推送昵称 API -- [IM SDK] 申请加群 joinGroup 方法增加请求信息参数 message -- [IM SDK] 修复退出聊天室没有清除缓存消息 - -## 版本:v3.5.0 2021-03-01 - -- [IM SDK] 登陆接口去掉 apiUrl 参数 -- [IM SDK] 默认关闭日志采集 -- [IM SDK] 修复未登录状态发消息报错 -- [IM SDK] 修复大型聊天室消息堵塞 - -## 版本:v3.4.2 2021-01-09 - -- [IM SDK] 增加获取会话列表功能 -- [IM SDK] 增加 channel ack 消息 -- [IM SDK] 修复由 uniapp 生成 h5 时登陆报错 -- [IM SDK] 修复部分已知 bug - -## 版本:v3.4.0 2020-12-10 - -- [IM SDK] 增加支持支付宝小程序 -- [IM SDK] 增加移动端上传推送 token api -- [IM SDK] 撤回消息、已读消息增加 from、to 字段 -- [IM SDK] CMD、自定义消息增加 type 字段 -- [音视频 SDK] 支持 uniapp 生成的原生客户端 - -## 版本:v3.3.2 2020-10-19 - -- [IM SDK] 增加支持设置固定 deviceId -- [IM SDK] 修改 getGroup 方法去掉参数 -- [IM SDK] 修复拉历史消息 bug -- [IM SDK] 修复发送附件消息对 3.3.0 之前 api 的兼容问题 -- [IM SDK] 修复使用 uniapp 打包的 app,退到后台回来时 websocket 无法连接的问题 -- [小程序 demo] 增加支持发视频消息 -- [小程序 demo] 增加提示注册失败原因:用户名超出 64 字节 -- [小程序 demo] 增加支持会话列表显示陌生人会话 - -## 版本:v3.3.0 2020-09-16 - -- [IM SDK] 增加支持 promise -- [IM SDK] 增加 onContactInvited、onContactDeleted、onContactAdded、onContactRefuse、onContactAgreed 好友相关的回调 -- [IM SDK] 增加 addContact、deleteContact、acceptInvitation、declineInvitation 代替原 subscribe、removeRoster、subscribed、unsubscribed 好友操作 API -- [IM SDK] 增加状态码 40,在 onError 中 type 为 40 会回调出因为 socket 断开导致发送失败的消息 -- [IM SDK] 修改默认的 resource,以便区分 web 端和小程序端的用户 -- [IM SDK] 修改 getChatRooms 获取聊天室 API,去掉 apiUrl 参数 -- [IM SDK] 修改 构造 cmd 消息 API, 去掉 msg 参数 -- [IM SDK] 优化构造消息 API,使用 chatType 来区分消息类型(单聊/群聊/聊天室) -- [IM SDK] 修复发送位置消息成功后并不执行 success 回调 -- [IM SDK] 增加容错处理 - -## 版本:v3.2.2 2020-08-25 - -- [IM SDK] 创建群组时增加被邀请人是否需要同意的参数 -- [IM SDK] onError 回调增加 error message - -## 版本:v3.2.1 2020-07-28 - -- [IM SDK] 修改创建聊天室 api,不需要传 owner 参数 -- [demo] 修复小程序收到好友申请,如果发起方不在线,那么收到方拒绝后发起方收不到回调 -- [demo] 修复 iOS 小程序在音视频会议后,发送单聊消息不显示,必须退出单聊窗口再进入才会显示 -- [demo] 修复小程序音视频通话过程中关闭美颜,美颜图标和字体,只有字体置灰 -- [demo] 增加小程序音视频时显示时长 - -## 版本:v3.2.0 2020-07-09 - -- [IM SDK] 增加创建聊天室、查询\修改聊天室详情、查询\设置\移除管理员 -- [IM SDK] 修复对消息扩展类型解析错误 -- [IM SDK] 修复发送图片、文件消息时,直接发送 url 时下载不成功 -- [IM SDK] 修改对于被禁言、拉黑等导致的发送消息失败,将从 fail 回调出去,不再从全局的 onError 回调 - -## 版本:v3.1.6 2020-07-03 - -- [音视频 SDK] 增加 joinRoom API -- [demo] 部分机型在视频会议时被来电打断后,无法继续推拉流,此时自动退出会议。 - -## 版本:v3.1.4 2020-06-11 - -- [IM SDK] 支持附件下载重定向 -- [IM SDK] 支持图片检测违规抛出单独的异常 -- [IM SDK] 增加分页获取聊天室成员 api -- [IM SDK] 修复收消息有延迟情况 -- [音视频 SDK] 增加断网重连 - -## 版本:v3.1.2 2020-05-14 - -- [IM SDK] 增加上传修改群/聊天室公告、获取群/聊天室公告、上传/下载/删除群/聊天室文件、获取群/聊天室文件列表, 增加上传修改群/聊天室公告、获取群/聊天室公告、上传/下载/删除群/聊天室文件、获取群/聊天室文件列表 -- [IM SDK] 修改重连间隔 -- [IM SDK] 去掉对上传文件大小的限制, 由服务端来限制 -- [IM SDK] 修复拉历史消息 bug -- [IM SDK] 修复自定义消息没有 time - -## 版本:v3.1.1 2020-04-28 - -- [demo] 适配 v3.1.1 IM SDK -- [IM SDK] 更新私有协议, 与 web 端统一 -- [IM SDK] 增加漫游消息 api -- [IM SDK] 增加聊天室禁言、解除禁言、获取禁言列表、加入黑名单、移除黑名单、获取黑明单列表等 api -- [IM SDK] 增加聊天室、群组一键禁言、白名单等 api -- [IM SDK] 增加发送自定义消息 -- [IM SDK] 增加群组回执 -- [音视频 SDK] 兼容 v3.1.1 IM SDK -- [音视频 SDK] 增加关闭摄像头的回调事件 -- [音视频 SDK] 修复不能销毁会议 - -## 版本:v1.3.1 2020-02-16 - -- [demo] 调整音视频最大码率为 300 - -## 版本:v1.3.0 2020-02-10 - -- [demo] 增加音视频会议功能。 -- [sdk] 增加音视频 SDK src/emedia/emedia_for_miniProgram.js。 - -## 版本:v1.2.0 2019-06-24 - -- [demo] 增加消息状态,比如断网时发的消息显示失败。 -- [demo] 增加 socket 连接成功的提示。 -- [demo] 修改了语音消息播放时再下载。 -- [demo] 修复聊天页面切后台,再切前台收到的离线消息有重复。 -- [demo] 由 rest1 迁移到 rest2 后开始校验 token,导致附件消息收不到。 -- [demo] 语音发送成功后点击听取后,语音依然闪烁动画。 -- [demo] 联系人分类为#,显示问题。 -- [sdk] 增加 onSocketConnected 事件 – socket 连接成功。 -- [sdk] onError 增加 type='sendMsgError' - 发送消息失败。 -- [sdk] sdk 重连时关闭上次创建的的 socket,而不是所有的 socket。 - -## 版本:v1.1.1 2019-04-10 - -- [sdk] 增加重连机制 -- [demo] 实时更新联系人列表 -- [bug] 修复进入群组时,群组名称错误 -- [bug] 修复可以同时播放多条语音 -- [bug] 群组聊天页显示问题 - -## 版本:v1.1.0 2019-03-22 - -- [sdk] [demo] 增加 token 登录 -- [demo] 新版 demo,修改 ui -- [demo] 增加搜索功能 -- [demo] 增加联系人按字母排序 -- [demo] 增加最近聊天按时间排序 -- [demo] 增加群组消息提醒 -- [demo] 增加测滑删除功能 -- [demo] 增加聊天历史分页 -- [demo] 增加用户名不区分大小写 -- [demo] 增加接收文件消息提示 -- [demo] 适配 iphone X,以及 XS max 等机型 -- [demo] 主页面由联系人页改为聊天页 -- [bug] 修改 A 给好友 B 发语音消息,B 没有显示语音的未读消息数 -- [bug] iOS 聊天界点击输入框进行输入时历史消息展示不合理 -- [bug] iOS 端小程序收到消息时,会话界面来消息的提醒有时会没有提醒,只显示消息数 -- [bug] 语音消息时长为 0 - -## 版本:v1.0.5 2018-09-12 - -新功能: - -- [sdk]开放注册 -- [sdk]登录 -- [sdk]退出登录 -- [sdk]监听 IM 链接状态 -- [sdk]消息发送(文字、图片、语音等) -- [sdk]接收消息 -- [sdk]获取用户会话和聊天记录 -- [sdk]添加好友 -- [sdk]删除好友 -- [sdk]同意添加好友请求 -- [sdk]拒绝添加好友请求 -- [sdk]获取用户好友列表 -- [sdk]收发群组消息 -- [sdk]创建群组 -- [sdk]添加群组成员 -- [sdk]退出群组 -- [sdk]解散群组 -- [sdk]获取完整的群成员列表 -- [sdk]获取群组列表 -- [sdk]获取群组详情 -- [demo]获取未读消息数 -- [demo]用户未读消息数清空 -- [demo]清空用户会话和聊天记录 diff --git a/docs/document/applet/room_attributes.md b/docs/document/applet/room_attributes.md deleted file mode 100644 index f7996db0..00000000 --- a/docs/document/applet/room_attributes.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/room_attributes.html", - title: "管理聊天室属性" -} ---- \ No newline at end of file diff --git a/docs/document/applet/room_manage.md b/docs/document/applet/room_manage.md deleted file mode 100644 index 134aa91f..00000000 --- a/docs/document/applet/room_manage.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/room_manage.html", - title: "创建和管理聊天室" -} ---- \ No newline at end of file diff --git a/docs/document/applet/room_members.md b/docs/document/applet/room_members.md deleted file mode 100644 index 89c61b25..00000000 --- a/docs/document/applet/room_members.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/room_members.html", - title: "管理聊天室成员" -} ---- \ No newline at end of file diff --git a/docs/document/applet/room_overview.md b/docs/document/applet/room_overview.md deleted file mode 100644 index 637089d3..00000000 --- a/docs/document/applet/room_overview.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/product/product_chatroom_overview.html", - title: "聊天室概述" -} ---- \ No newline at end of file diff --git a/docs/document/applet/serverconfig.md b/docs/document/applet/serverconfig.md deleted file mode 100644 index 54dbf9bb..00000000 --- a/docs/document/applet/serverconfig.md +++ /dev/null @@ -1,40 +0,0 @@ -# 如何配置服务器域名 - - - -微信小程序在生产环境下如果没有配置合法域名,是不能正常访问的,那就需要把服务器域名添加到微信小程序后台管理系统的服务器域名白名单里面。 那么接下来本文就来介绍一下配置小程序添加合法域名的步骤方法,具体步骤如下所示。 - -1. 打开 [微信公众平台官网](https://mp.weixin.qq.com/),登录微信小程序账号,然后进入微信小程序管理主界面; -2. 在微信小程序主界面的左侧菜单栏里面找到 “开发” 模块。 - -![img](/images/applet/config1.png) - -3. 在 “开发” 模块,点击 “开发管理”,找到 “开发设置” 选项,下拉找到 “服务器域名” 模块。 - -![img](/images/applet/config2.png) - -4. 首次设置服务器域名的话,会有一个 “开始配置” 按钮,点击进入。 - -![img](/images/applet/config3.png) - -5. 进入配置服务器信息之前需要先进行身份确认,需要管理员扫码进行身份认证。 - -![img](/images/applet/config4.png) - -6. 管理员身份认证之后,就进入到 “配置服务器信息” 模块,设置第二个选项 “socket合法域名” 里面的域名即可。 - -![img](/images/applet/config5.png) - -7. 登陆环信后台获取 socket 域名,进入即时通讯-服务概览页,即可看到如图的域名展示。 - -:::tip -抖音小程序、QQ 小程序、百度小程序、uniapp 全平台等同微信小程序的域名一致,使用微信小程序栏的域名即可。 -::: - -![img](/images/applet/config6.png) - -8. 填写完域名信息之后,点击下面 “保存并提及” 按钮即可设置完成。 - -![img](/images/applet/config7.png) - -9. 设置完成小程序服务器域名之后,如果想修改服务器域名或者删除服务器域名,依然在 “开发” 模块进入,然后进入服务器域名设置部分进行操作设置即可。 \ No newline at end of file diff --git a/docs/document/applet/thread.md b/docs/document/applet/thread.md deleted file mode 100644 index ba9be00c..00000000 --- a/docs/document/applet/thread.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/thread.html", - title: "管理子区" -} ---- \ No newline at end of file diff --git a/docs/document/applet/thread_message.md b/docs/document/applet/thread_message.md deleted file mode 100644 index 5032e74f..00000000 --- a/docs/document/applet/thread_message.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/thread_message.html", - title: "管理子区消息" -} ---- \ No newline at end of file diff --git a/docs/document/applet/uniapp.md b/docs/document/applet/uniapp.md deleted file mode 100644 index 686f8310..00000000 --- a/docs/document/applet/uniapp.md +++ /dev/null @@ -1,151 +0,0 @@ -# Uniapp 全平台方案简介 - - - -环信小程序 SDK 为各端小程序开发提供一套完整的技术解决方案,在各端小程序的开发环境下,集成 IM 相关的功能更加便捷、高效。让您的小程序快速获得安全稳定的 IM 能力,集成简单,使用方便,帮助您快速拓展业务,赢得先机。 - -:::tip -- uniapp SDK 目前支持微信、支付宝、QQ、百度小程序、抖音(请使用低于 1.70.0 以下的版本基础库)、uni-app 编译的 原生 Android 以及 iOS。 -- uniapp SDK 4.11.0 及以上版本支持鸿蒙系统。 -::: - -## 体验小程序 - -扫描下方小程序二维码,或者微信搜索 **环信 IM Uniapp** 即可快速体验环信小程序 Demo 在线版本 - -![img](/images/applet/applet-demo.png) - -:::tip - -- 小程序 Demo 只包含部分 IM 功能,详细参考 **功能说明**。 -- Uni-app Demo Git 源码地址 [https://github.com/easemob/webim-uniapp-demo](https://github.com/easemob/webim-uniapp-demo) - ::: - -## 功能说明 - -- 支持账户注册登录 -- 支持 IM 基本功能收发文本、图片、语音、视频、音频、文件、透传、扩展消息等 -- 支持 群组聊天室功能 -- 支持个人设置 -- 支持发送语音功能 - -## 开发者集成 - -### 集成前准备 - -[注册并创建应用](/product/enable_and_configure_IM.html#创建应用) - -### 搭建开发环境 - -1. 下载 HBuilderx 编辑器 [https://www.dcloud.io/hbuilderx.html](https://www.dcloud.io/hbuilderx.html)。 -2. DCloud 开发者中心注册 [https://dev.dcloud.net.cn/](https://dev.dcloud.net.cn/)。 - -之后登录 HBuilderx 编辑器。这样,小程序的开发环境准备完毕。 - -即将开发的平台配置服务 - -### 配置服务器域名(以微信为例) - -为满足不同客户的业务需求,环信在多地部署了数据中心。不同数据中心的 REST API 请求域名、WebSocket 访问域名不同。请根据您所在数据中心进行配置。 - -环信不同数据中心的 REST API 请求域名、WebSocket 访问域名: - -| 数据中心 | REST API 请求地址 | WebSocket 访问域名 | -| ------------- | ------------------ | -------------------------------- | -| 国内 1 区 | a1.easemob.com | im-api-wechat.easemob.com 或 im-api-wechat.easecdn.com | -| 国内 2 区 | a31.easemob.com | im-api-wechat-31.easemob.com 或 im-api-wechat-31.easecdn.com | -| 国内 VIP 区 | 请咨询商务经理 | 请咨询商务经理 | -| 客服专用 | 请咨询商务经理 | 请咨询商务经理 | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | im-api-wechat-sgp.easemob.com 或 im-api-wechat-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | im-api-wechat-61.easemob.com 或 im-api-wechat-61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | im-api-wechat-41.easemob.com 或 im-api-wechat-41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | im-api-wechat-71.easemob.com 或 im-api-wechat-71.easecdn.com | - -应用所在数据中心可以在环信用户管理后台>应用信息中查看:Console 中查看请求域名 - -![img](/images/applet/service_overview.png) - -登录 [微信公众平台](https://mp.weixin.qq.com/),进入 **开发 > 开发设置** 页面,配置以下服务器地址(其他平台小程序配置与微信一致): - -:::tip -request 合法域名,uploadFile 合法域名,downloadFile 合法域名 - -1. https://a1.easemob.com -2. https://a2.easemob.com -3. https://a3.easemob.com -4. https://a4.easemob.com -5. https://a5.easemob.com -6. https://a31.easemob.com -7. https://a1-sgp.easemob.com -8. https://a41.easemob.com -9. https://a51.easemob.com -10. https://a1-chatfile.easemob.com -11. https://rs.chat.agora.io -12. https://rs.easemob.com -::: - -:::tip -socket 合法域名: - -1. wss://im-api-wechat.easemob.com(3.0 IM SDK) -2. wss://im-api-wechat-31.easemob.com -3. wss://im-api-alipay.easemob.com/websocket(支付宝小程序专用) -4. wss://im-api-alipay-31.easemob.com/websocket(支付宝小程序专用) -::: - -### 各端小程序 WebSocket 连接数量 - -- QQ、微信小程序: `**1.7.0**` 及以上版本,最多可以同时存在 **5** 个 WebSocket 连接 -- 字节小程序: `**1.0.0**` 及以上版本 (在当前小程序页面已经有一个 WebSocket 连接的情况下,如果再创建一个 WebSocket 连接,会重新创建一个 WebSocket 连接,但是之前创建的 WebSocket 连接并不会自动关闭。) -- 百度小程序:`**1.9.4**` 及以上版本,支持存在多个 WebSokcet 连接,每次成功调用会返回一个新的 SocketTask -- 支付宝小程序:支付宝小程序在一段时间内只能保留一个 WebSocket 连接,如果当前已存在 WebSocket 连接,那么会自动关闭该连接,并重新创建一个新的 WebSocket 连接。 - -### 将 SDK 添加到自己的小程序 - -#### 下载 SDK - -可以通过以下方式获取 SDK: - -- 从 npm [easemob-websdk](https://www.npmjs.com/package/easemob-websdk/) 中获取。 - -#### 引入 SDK - -- 开始一个全新的项目: - 1. 安装 `easemob-websdk` npm 包。 - 2. 直接使用 `import/require` 方式获取引用,如果使用 mpvue 保持引文件方式的统一。 -- 基于 Demo 二次开发。 - -拉取代码,HBuilder 运行。 - -#### 调用示例 - -若项目之前未使用 npm 管理依赖(项目根目录下无 package.json 文件),先在项目根目录执行命令初始化 npm 工程: - -```bash -npm init -y -``` -在项目根目录执行命令安装 npm 包: - -```bash -npm i easemob-websdk -``` -引入 uniApp SDK - -```javascript -import SDK from 'easemob-websdk/uniApp/Easemob-chat'; -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -// 实例化 SDK 对象 -const WebIM = wx.WebIM = SDK; -const conn = new WebIM.connection({ - appKey: 'your appKey', //注意这里的 "K" 需大写 - url: 'wss://im-api-wechat.easemob.com/websocket', // websocket 连接地址 - apiUrl: 'https://a1.easemob.com',// REST API 连接地址 - useOwnUploadFun: true // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传 URL) -}); -``` diff --git a/docs/document/applet/uniappnativeapp.md b/docs/document/applet/uniappnativeapp.md deleted file mode 100644 index c97714d2..00000000 --- a/docs/document/applet/uniappnativeapp.md +++ /dev/null @@ -1,105 +0,0 @@ -# uni-app 打包原生 app(Android、iOS)方案简介 - - - -使用 环信小程序 SDK 在 **`HBuilderX`** 中编译 Android、iOS 应用,可实现一套代码多端同时打包。IM 相关的集成方式同 Web、小程序一样便捷、高效。 - -## 体验 IM 应用 - -- 安卓: [https://www.pgyer.com/h4XF](https://www.pgyer.com/h4XF) -- iOS: [https://www.pgyer.com/9ISC](https://www.pgyer.com/9ISC) - -:::tip - -- Demo 只包含部分 IM 功能,详细参考 **功能说明** -- Uni-app Demo Git 源码地址 [https://github.com/easemob/webim-uniapp-demo](https://github.com/easemob/webim-uniapp-demo)::: - -## 功能说明 - -- 支持账户注册登录 -- 支持 IM 基本功能收发文本、图片、语音、视频、音频、文件、透传、扩展消息等 -- 支持 群组聊天室功能 -- 支持个人设置 - -## 开发者集成 - -[注册并创建应用](/product/enable_and_configure_IM.html#创建应用) - -### 搭建 app 开发环境 - -1. 下载 HBuilderx 编辑器 https://www.dcloud.io/hbuilderx.html - -:::tip -项目中 HBuilderx 目前使用的最新版本,如果此前下载过 HBuilderx,为保证开发环境统一请更新到最新版本 -::: - -2. DCloud 开发者中心注册 [https://dev.dcloud.net.cn/](https://dev.dcloud.net.cn/) - -之后登陆 HBuilderx 编辑器。 至此 app 的开发环境差不多完成。 - -### 将 SDK 添加到自己的小程序 - -#### 下载 SDK - -可以通过以下两种方式获取 SDK: - -- 通过官网 [下载 SDK](https://www.easemob.com/download/im) -- Uni-app Demo 源码中获取 [https://github.com/easemob/webim-uniapp-demo](https://github.com/easemob/webim-uniapp-demo) - -#### 引入 SDK - -- 开始一个全新的项目 - 1. 将 SDK 目录下(src/sdk/)的文件全部导入到自己的项目中。 - 2. 直接使用 import/require 方式获取引用, 如果使用 mpvue 请保持引用文件方式的统一。 - -#### 基于 Demo 二次开发 - -拉取代码,连接手机,打开手机开发者模式,连接手机授权传输文件,即可运行起来。 - -#### 调用示例 - -```javascript -//使用示例 -import SDK from "../sdk/webimSDK3.x.x"; // 3.0sdk -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -//实例化 SDK 对象 -const WebIM = (wx.WebIM = SDK); -WebIM.conn = new WebIM.connection({ - isMultiLoginSessions: false, //是否可以登录多个,并在所有端上接收消息 - https: false, //是否使用 HTTPS - url: "wss://im-api-wechat.easemob.com/websocket", // socket server (3.0 SDK) - apiUrl: "https://a1.easemob.com", // rest server - heartBeatWait: 30000, //心跳间隔 - autoReconnectNumMax: 2, //自动重连次数 - useOwnUploadFun: false, // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传url) -}); -``` - -IM 基本功能,请参考 [消息管理](message_overview.html)。 - -## 打包发布 - -1. 原生 App-云打包:HBuilder 编辑器 → 发行 → 原生 App-云打包 (app 图标,启动页等详细配置可在 **`manifest.json`** 进行配置) -2. 原生 App-离线打包:HBuilder 编辑器 → 发行 → 生成本地打包 App 资源 (详细打包方案请看 **`iOS、Android 本地打包指南`**。) - -## Demo 兼容性 - -Demo 在以下安卓机器中存在一定兼容性能问题: - -- 魅族魅蓝 E (无法运行) -- 华为 p20(运行卡顿) - -## APP 开发者常见问题(重要) - -- App/uni-app 离线本地存储方案:[https://ask.dcloud.net.cn/article/166](https://ask.dcloud.net.cn/article/166) -- uni-app 实现全局变量:[https://ask.dcloud.net.cn/article/35021](https://ask.dcloud.net.cn/article/35021) -- 原生控件层级过高无法覆盖的解决方案:[https://uniapp.dcloud.io/component/native-component](https://uniapp.dcloud.io/component/native-component) -- 导航栏开发指南:[https://ask.dcloud.net.cn/article/34921](https://ask.dcloud.net.cn/article/34921) -- 关于推送:[https://ask.dcloud.net.cn/article/35622](https://ask.dcloud.net.cn/article/35622) -- 更多详情:[https://uniapp.dcloud.io/faq](https://uniapp.dcloud.io/faq) diff --git a/docs/document/applet/uniappuikit.md b/docs/document/applet/uniappuikit.md deleted file mode 100644 index bb0fac12..00000000 --- a/docs/document/applet/uniappuikit.md +++ /dev/null @@ -1,157 +0,0 @@ -# 小程序模版使用指南 - - - -此模版根据 uni-app 版本的小程序进行2次封装而来,组件可灵活抽离且可以快速集成在其他项目中。不用过分关注收发消息、发图片、发文件、消息上屏等逻辑。从而快速集成符合自身业务的功能 - -## 简介 - -小程序模版源码地址 (`注意:分支为:versions2.0`) - -- [https://github.com/easemob/webim-uniapp-demo/tree/versions2.0](https://github.com/easemob/webim-uniapp-demo/tree/versions2.0) - -### 安装scss/sass依赖 - -HBuilderx ⇒ 工具 ⇒ 插件安装 ⇒ 安装新插件 ⇒ 前往插件市场安装 - -- 地址:[https://ext.dcloud.net.cn/plugin?id=2046](https://ext.dcloud.net.cn/plugin?id=2046) - -### 集成说明 - -:::tip -小程序模版必须依赖环信 IM SDK,因而在使用小程序模版时必须同时添加环信 IM SDK 依赖。 -::: - -所有依赖配置项都在 utils 中: - -![img](/images/applet/utils.jpeg) - -具体 SDK 集成,详见 [Uniapp 全平台](uniapp.html) - -## 快速使用 - -小程序模版封装了常用 IM 功能,提供了会话,聊天及联系人等基本的 component,旨在帮助开发者快速集成环信 SDK。 同时也集成了第三方 UI 库(Uview-ui),且可按需引入。UI 库详情:[https://www.uviewui.com/components/intro.html](https://www.uviewui.com/components/intro.html) - -## 组件介绍 - - - -## 组件使用 - -```javascript -import chat from "@/components/chat/chat.vue"; -// chatType=singleChat 单聊 - // 必填 - - -// chatType=chatRoom 群聊 - -``` - - - -### chat 组件详细介绍 - -#### 参数介绍 - -- `username` – **必传参数** 由消息列表或联系人通过 URL 传入,包含当前用户 name 以及当前点击用户 name;示例:username: “{“myName”:“xx”,”your“:“xxx”}” -- `chatType` – **必传参数** 聊天类型singleChat:单聊 chatRoom:群聊 可自定新增 - -#### chat 组件依赖 - -- chat 组件依赖 utils 中的文件,因此使用 chat 组件时,务必保证 utils 中的文件一并存在 - - - -#### chat 组件的消息存取 - -- 所有消息都存在了各端小程序的 Storage 中,在 component/chat/msgtype.js 文件中定义消息类型,消息的逻辑处理在 component/chat/msgstorage.js 中,处理完各种消息类型并调用 `uni.setStorage()` 将消息存在本地,页面中通过 `uni.getStorageSync()` 获取消息 - -组件可根据自身需求随意调整样式,详细请看 `component/chat/chat.vue` - -### 滑动组件 - -```javascript -import swipeDelete from "@/components/swipedelete/swipedelete"; - ... -``` - -### 长按功能框 - -```javascript -import longPressModal from "@/components/longPressModal/index"; - // 样式 -``` - - - -### 长按组件详细介绍 - -#### 参数介绍 - -长按组件参数 - -- `winSize` – **必传参数** Objet,示例:winSize:{witdh: windowWidth, height: windowHeight} -- `popButton` – **必传参数** Array,示例:['删除该聊天','置顶','自定义'] -- `change` – Function ,当前选中的具体参数 -- `showPop` – **必传参数** Bool,遮罩默认 false -- `hidePop` – Function,显隐框操作事件 -- `popStyle` – string,样式 - -:::tip -使用长按组件时候需要先获取当前窗口,再根据当前点击的位置来显示组件框: -::: - -```javascript -onLoad(){ - /* 获取窗口尺寸 */ - uni.getSystemInfo({ - success: (res) => { - this.winSize = { - witdh: res.windowWidth, - height: res.windowHeight, - }; - }, - }); - } - -/* 长按事件 */ -longpress: function (e) { - //将当前选中的值存在data中方便后续操作 - this.currentVal = e - let [touches, style, index] = [e.touches[0],"",e.currentTarget.dataset.index,]; - - /* 因 非H5端不兼容 style 属性绑定 Object ,所以拼接字符 */ - if (touches.clientY > this.winSize.height / 2) { - style = `bottom:${this.winSize.height - touches.clientY}px;`; - } else { - style = `top:${touches.clientY}px;`; - } - if (touches.clientX > this.winSize.witdh / 2) { - style += `right:${this.winSize.witdh - touches.clientX}px`; - } else { - style += `left:${touches.clientX}px`; - } - - this.popStyle = style; - this.$nextTick(() => { - setTimeout(() => { - this.showPop = true; - }, 10); - }); - }, - -``` \ No newline at end of file diff --git a/docs/document/applet/user_relationship.md b/docs/document/applet/user_relationship.md deleted file mode 100644 index 9b3d6da3..00000000 --- a/docs/document/applet/user_relationship.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/user_relationship.html", - title: "管理用户关系" -} ---- \ No newline at end of file diff --git a/docs/document/applet/userprofile.md b/docs/document/applet/userprofile.md deleted file mode 100644 index c6b689b0..00000000 --- a/docs/document/applet/userprofile.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/document/web/userprofile.html", - title: "用户属性" -} ---- \ No newline at end of file diff --git a/docs/document/applet/wechat.md b/docs/document/applet/wechat.md deleted file mode 100644 index 2f798e99..00000000 --- a/docs/document/applet/wechat.md +++ /dev/null @@ -1,126 +0,0 @@ -# 微信小程序集成介绍 - - - -### Demo 体验 - -要体验微信小程序 Demo,请点击[这里](https://www.easemob.com/download/demo),使用微信扫描二维码。 - -要查看 Demo 源码,请点击[这里](https://github.com/easemob/webim-weixin-xcx)。 - -### 注册环信账号 - -开发者需要在环信管理后台 [注册并创建应用](/product/enable_and_configure_IM.html#创建应用),来获取唯一 appKey,SDK 初始化时需要配置 appKey。 - -### 搭建微信小程序开发环境 - -首先需要下载并安装 [开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html),然后按照微信小程序的 [接入流程](https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/getstart.html#%E7%94%B3%E8%AF%B7%E5%B8%90%E5%8F%B7)一步步创建一个小程序 - -### 配置服务器域名 - -小程序在发布前,需要配置合法域名。 - -登录[微信公众平台](https://mp.weixin.qq.com/), 在开发设置页面配置以下服务器域名。 - -:::tip -request 合法域名: - -1. https://a1.easemob.com -2. https://a2.easemob.com -3. https://a3.easemob.com -4. https://a4.easemob.com -5. https://a5.easemob.com -6. https://a1-chatfile.easemob.com -7. https://rs.chat.agora.io -8. https://rs.easemob.com -::: - -:::tip -socket 合法域名: -wss://im-api-wechat.easemob.com(3.0 IM SDK) -::: - -:::tip -uploadFile 合法域名: -https://a1.easemob.com -::: - -:::tip -downloadFile 合法域名: - -1. https://a1-v2.easemob.com -2. https://a4.easemob.com -3. https://a1.easemob.com -4. https://a4-v2.easemob.com -5. https://a3-v2.easemob.com -6. https://a5-v2.easemob.com -7. https://a2-v2.easemob.com -8. https://a1-chatfile.easemob.com -::: - -:::tip -为满足不同客户的业务需求,环信在多地部署了数据中心。不同数据中心的 REST API 请求域名、WebSocket 访问域名不同。请根据您所在数据中心进行配置。 -::: - -环信不同数据中心的 REST API 请求域名、WebSocket 访问域名: - -| 数据中心 | REST API 请求地址 | WebSocket 访问域名 | -| ------------- | ------------------ | -------------------------------- | -| 国内 1 区 | a1.easemob.com | im-api-wechat.easemob.com 或 im-api-wechat.easecdn.com | -| 国内 2 区 | a31.easemob.com | im-api-wechat-31.easemob.com 或 im-api-wechat-31.easecdn.com | -| 国内 VIP 区 | 请咨询商务经理 | 请咨询商务经理 | -| 客服专用 | 请咨询商务经理 | 请咨询商务经理 | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | im-api-wechat-sgp.easemob.com 或 im-api-wechat-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | im-api-wechat-61.easemob.com 或 im-api-wechat-61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | im-api-wechat-41.easemob.com 或 im-api-wechat-41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | im-api-wechat-71.easemob.com 或 im-api-wechat-71.easecdn.com | - -应用所在数据中心可以在环信用户管理后台>应用信息中查看: - -![img](/images/applet/service_overview.png) - -### 集成 SDK - -#### 下载 SDK - -可以通过以下两种方式获取 SDK: - -- 通过官网 [下载 SDK](https://www.easemob.com/download/im) -- 从环信的 [github 仓库](https://github.com/easemob/webim-weixin-xcx/tree/master/src/sdk) 中获取 SDK 中的文件 - -#### 引入 SDK - -- 开始一个全新的项目 - 1. 将下载的 SDK(src/sdk/)导入到自己的项目中。 - 2. 引入 SDK:`import IMSDK from "../sdk/Easemob-chat-miniProgram";` -- 基于 Demo 二次开发 - -将下载的代码导入开发者工具即可运行起来。 - -#### 调用示例 - -```javascript -//使用示例 -import SDK from "../sdk/connection"; // 2.0sdk -import SDK from "../sdk/Easemob-chat-miniProgram"; // 3.0sdk -``` - -#### 实例调用方式 - -实例化 SDK,并挂载在全局对象下。 - -```javascript -//实例化SDK对象 -const WebIM = (wx.WebIM = SDK); -WebIM.conn = new WebIM.connection({ - appKey: "your appKey", - https: true, //是否使用HTTPS - url: "wss://im-api-wechat.easemob.com/websocket", // socket server (3.0 SDK) - apiUrl: "https://a1.easemob.com", // rest server - heartBeatWait: 30000, //心跳间隔 - autoReconnectNumMax: 5, //自动重连次数 - useOwnUploadFun: false, // 是否使用自己的上传方式(如将图片文件等上传到自己的服务器,构建消息时只传url) -}); -``` - -微信小程序的 IM 的基本功能和 API 的使用方法与 Web 端一致,请参考 Web 端文档。 diff --git a/docs/document/flutter/overview.md b/docs/document/flutter/overview.md deleted file mode 100644 index fda9ca61..00000000 --- a/docs/document/flutter/overview.md +++ /dev/null @@ -1,152 +0,0 @@ -# SDK 集成概述 - - - -介绍 flutter 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号和取得 App key,见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -具体见 [开发环境要求](quickstart.html#前提条件)。 - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。 - -初始化示例代码: - -```dart -await EMClient.getInstance.init(EMOptions( - appKey: "<#your app key#>", -)); -// 通知 SDK UI 已准备好。该方法执行后才会收到 `EMChatRoomEventHandler`、`EMContactEventHandler` 和 `EMGroupEventHandler` 回调。 -await EMClient.getInstance.startCallback(); -``` - -## 注册用户 - -目前用户注册方式有以下几种: -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```dart -try { - await EMClient.getInstance.createAccount(userId, password); -} on EMError catch (e) {} -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -目前登录服务器支持手动和自动登录。手动登录有两种方式: - -- 用户 ID + 密码 -- 用户 ID + token - -手动登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `onConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -### 手动登录 - -**用户 ID + 密码** 登录是传统的登录方式。用户名和密码都是你的终端用户自行决定,密码需要符合密码规则要求。 - -```dart -try { - await EMClient.getInstance.login(userId, password); -} on EMError catch (e) {} -``` - -**用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取。 详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```dart -try { - await EMClient.getInstance.login(userId, token, false); -} on EMError catch (e) {} -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -### 自动登录 - -在初始化的时候,可以设置是否自动登录。如果设置为自动登录,则登录成功之后,后续启动初始化的时候会自动登录。 - -## 退出登录 - -```dart -try { - await EMClient.getInstance.logout(true); -} on EMError catch (e) {} -``` - -自动登录时,SDK 尝试连接服务器失败后,延时随机一段时间后自动重连。 - -## 连接状态相关 - -你可以通过注册连接监听来确认连接状态。 - -```dart -// 注册连接状态监听 -EMClient.getInstance.addConnectionEventHandler( - "UNIQUE_HANDLER_ID", - EMConnectionEventHandler( - // sdk 连接成功; - onConnected: () => {}, - // 由于网络问题导致的断开,sdk会尝试自动重连,连接成功后会回调 "onConnected"; - onDisconnected: () => {}, - // 用户 token 鉴权失败; - onUserAuthenticationFailed: () => {}, - // 由于密码变更被踢下线; - onUserDidChangePassword: () => {}, - // 用户被连接被服务器禁止; - onUserDidForbidByServer: () => {}, - // 用户登录设备超出数量限制; - onUserDidLoginTooManyDevice: () => {}, - // 用户从服务器删除; - onUserDidRemoveFromServer: () => {}, - // 调用 `kickDevice` 方法将设备踢下线,被踢设备会收到该回调; - onUserKickedByOtherDevice: () => {}, - // 登录新设备时因达到了登录设备数量限制而导致当前设备被踢下线,被踢设备收到该回调; - onUserDidLoginFromOtherDevice: (String deviceName) => {}, - // Token 过期; - onTokenDidExpire: () => {}, - // Token 即将过期,需要调用 renewToken; - onTokenWillExpire: () => {}, - ), -); -// 解注册连接状态监听 -EMClient.getInstance.removeConnectionEventHandler( - "UNIQUE_HANDLER_ID", -); -``` - diff --git a/docs/document/harmonyos/overview.md b/docs/document/harmonyos/overview.md deleted file mode 100644 index 6f4ed692..00000000 --- a/docs/document/harmonyos/overview.md +++ /dev/null @@ -1,208 +0,0 @@ -# SDK 集成概述 - - - -介绍 HarmonyOS 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号并取得 App key,见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -详见 [快速开始中的开发环境要求](quickstart.html#准备开发环境)。 - -## 添加权限 - -1. 找到模块的文件 `module.json5` -2. SDK 最少需要添加的权限如下: - -```xml - -ohos.permission.INTERNET - -ohos.permission.GET_NETWORK_INFO -``` - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。 - -初始化示例代码: - -```typescript -let options = new ChatOptions("Your appkey"); -......// 其他 ChatOptions 配置。 -// 初始化时传入上下文以及 options -ChatClient.getInstance().init(context, options); -``` - -## 注册用户 - -目前用户注册方式有以下几种: -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```typescript -ChatClient.getInstance().createAccount(userId, pwd).then(()=> { - // success logic -}); -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -目前登录服务器支持手动和自动登录。手动登录有两种方式: - -- 用户 ID + 密码 -- 用户 ID + token - -手动登录时传入的用户 ID 必须为 string 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `onConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -### 手动登录 - -**用户 ID + 密码** 登录是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合密码规则要求。 - -```typescript -ChatClient.getInstance().login(userId, pwd).then(() => { - // 登录成功回调 -}).catch((e: ChatError) => { - // 登录失败回调,包含错误信息 -}); -``` - -**用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取。详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```typescript -ChatClient.getInstance().loginWithToken(userId, token).then(() => { - // 登录成功回调 -}).catch((e: ChatError) => { - // 登录失败回调,包含错误信息 -}); -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -### 自动登录 - -初始化时可以设置是否自动登录。如果设置为自动登录,则登录成功之后,后续启动初始化的时候会自动登录。 - -自动登录时,SDK 尝试连接服务器失败后,延时随机一段时间后自动重连。 - -## 退出登录 - -```typescript -ChatClient.getInstance().logout().then(()=> { - // success logic -}) -``` -## 连接状态相关 - -你可以通过注册连接监听确认连接状态。 - -```typescript -let connectionListener: ConnectionListener = { - onConnected: (): void => { - // 长连接建立 - }, - onDisconnected: (errorCode: number): void => { - // 长连接断开 - }, - onLogout: (errorCode: number, info: LoginExtInfo): void => { - // 触发退出,需要主动调用 ChatClient#logout 方法 - }, - onTokenExpired: (): void => { - // 使用 token 登录时,token 过期触发。 - }, - onTokenWillExpire: (): void => { - // 使用 token 登录时,token 将要过期时触发。 - // 注意:如果本次登录服务器没有离线消息,不会触发该回调。 - }, - onOfflineMessageSyncStart: () => { - // 连接成功,开始从服务器拉取离线消息时触发。 - }, - onOfflineMessageSyncFinish: () => { - // 离线用户上线后从服务器拉取离线消息结束时触发。 - // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。 - } -} -// 注册连接状态监听 -ChatClient.getInstance().addConnectionListener(connectionListener); -// 移除连接状态监听 -ChatClient.getInstance().removeConnectionListener(connectionListener); -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等引起的连接终端,SDK 会自动尝试重连。重连成功或者失败的结果分别会收到通知 `onConnected` 和 `onDisconnected`。 - -### 被动退出登录 - -你可以通过监听回调 `ConnectionListener#onLogout` 后,调用 `ChatClient#logout` 进行退出并返回登录界面。 - -`ConnectionListener#onLogout(number)` 返回的 `errorCode` 有如下: - -- `APP_ACTIVE_NUMBER_REACH_LIMITATION = 8`: 应用程序的日活跃用户数量(DAU)或月活跃用户数量(MAU)达到上限 -- `USER_LOGIN_ANOTHER_DEVICE = 206`: 用户已经在其他设备登录 -- `USER_REMOVED = 207`: 用户账户已经被移除 -- `USER_BIND_ANOTHER_DEVICE = 213`: 用户已经绑定其他设备 -- `USER_LOGIN_TOO_MANY_DEVICES = 214`: 用户登录设备超出数量限制 -- `USER_KICKED_BY_CHANGE_PASSWORD = 216`: 由于密码变更被踢下线 -- `USER_KICKED_BY_OTHER_DEVICE = 217`: 由于其他设备登录被踢下线 -- `USER_DEVICE_CHANGED = 220`: 和上次设备不同导致下线 -- `SERVER_SERVICE_RESTRICTED = 305`: Chat 功能限制 - -以上参数具体可以参考 [ChatError](https://sdkdocs.easemob.com/apidoc/harmony/chat3.0/classes/ChatError.ChatError.html#errorCode) 对应说明。 - -## 输出信息到日志文件 - -环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。 - -默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。 - -例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。 - -SDK 默认输出调试信息(所有日志,包括调试信息、警告和错误),如果只需输出错误日志,需要关闭调试模式。 - -```typescript -ChatLog.setLogLevel(ChatLogLevel.ERROR_LEVEL); -``` - -### 获取本地日志 - -打开以下目录,获取本地日志。 - -``` -hdc file recv /data/app/el2/100/base/{应用包名}/{App Key}/core_log -``` - -获取本地日志,需要将 `{应用包名}` 替换为应用的包名,例如 `com.hyphenate.chatuidemo`;`{App Key}` 需要替换为应用的环信 App Key。 \ No newline at end of file diff --git a/docs/document/server-side/java_server_sdk.md b/docs/document/server-side/java_server_sdk.md deleted file mode 100644 index 026dfef0..00000000 --- a/docs/document/server-side/java_server_sdk.md +++ /dev/null @@ -1,436 +0,0 @@ -# Java Server SDK 1.0 - - - -## 功能概述 - -Server SDK 是对环信 IM [REST API](overview.html) 的封装,这样做是为了节省服务器端开发者对接环信 API 的时间,只需要配置自己的 App Key 相关信息即可使用。 - -Server SDK 提供了用户、消息、群组、聊天室等资源的操作管理能力。 - -## 前提条件 - -- Java 1.8 -- [Reactor](https://projectreactor.io/)(io.projectreactor:reactor-bom:2020.0.4) -- 有效的环信即时通讯 IM 开发者账号和 App Key、Client ID、ClientSecret,登录 [环信管理后台](https://console.easemob.com/user/login) 到“应用列表” → 点击“查看”即可获取到 App Key、Client ID、ClientSecret。 - -## 实现方法 - -### 安装 - -如果你的项目使用 Maven 构建,在 pom.xml 中添加下面代码: - -```xml - - com.easemob.im - im-sdk-core - 0.8.56 - -``` - -如果你的项目使用 Gradle 构建,可以在 build.gradle 中添加下面代码: - -```gradle -implementation 'com.easemob.im:im-sdk-core:0.8.56' -``` - -### 使用 - -[EMService](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/EMService.html) 是所有 API 的入口,可以这样初始化: - -#### 1. 使用 Easemob App Credentials 的情况 - -```java -建议写到配置类中,示例如下: -@Configuration -public class Config { - - @Bean - public EMService service() { - - EMProperties properties = EMProperties.builder() - .setAppkey("Appkey") - .setClientId("Client ID") - .setClientSecret("ClientSecret") - .build(); - - return new EMService(properties); - } -} -``` - -根据业务资源,API 分为: - -- [Attachment](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/attachment/AttachmentApi.html) 用于上传下载附件。 -- [Block](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/block/BlockApi.html) 用于限制访问(将用户加入黑名单、群组/聊天室禁言等)。 -- [Contact](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/contact/ContactApi.html) 用于管理联系人(添加好友等)。 -- [Group](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/group/GroupApi.html) 用于管理群组。 -- [Message](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/message/MessageApi.html) 用于发送消息。 -- [User](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/user/UserApi.html) 用于管理用户。 -- [UserMetadata](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/metadata/MetadataApi.html) 用于管理用户属性。 -- [Push](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/push/PushApi.html) 用于管理用户推送(设置推送免打扰等)。 -- [Token](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/token/TokenApi.html) 用于获取用户 Token。 -- [Room](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/room/RoomApi.html) 用于管理聊天室。 -- [Presence](https://easemob.github.io/easemob-im-server-sdk/com/easemob/im/server/api/presence/PresenceApi.html) 用于管理在线状态订阅。 - -每个业务资源对应一个方法,例如,用户相关的 API,都可以在 `.user()` 找到。 - -举个例子,我们要注册一个用户,就可以这样写: - -```java -@Service -public class UserService { - - @Autowired - private EMService service; - - private void createUser() { - try { - EMUser user = service.user().create("username", "password").block(); - } catch (EMException e) { - e.getErrorCode(); - e.getMessage(); - } - - } -} -``` - -API 的返回值是响应式的,如果希望阻塞,可以使用上面例子中的 `.block()`。 - -:::tip -如果你的项目不是响应式的编程,那么请在调用的 Server SDK API 的结尾添加 `.block()` -对使用的 API 添加 try/catch ,如果使用的 API 没有抛出异常,代表请求成功,反之则请求失败,通过异常 `EMException` 对象的 `getErrorCode()/getMessage()` 拿到错误码以及错误描述。 -::: - -#### 2.私有化配置,将你自己的私有化 REST 服务器地址设置给 `setBaseUri` 即可。 - -建议写到配置类中,示例如下: - -```java -@Configuration -public class Config { - - @Bean - public EMService service() { - - EMProperties properties = EMProperties.builder() - .setBaseUri("https://Your privatized address name") - .setAppkey("Appkey") - .setClientId("Client ID") - .setClientSecret("ClientSecret") - .build(); - - return new EMService(properties); - } -} -``` - -## 参考 - -- [Server SDK 的 API 文档](https://easemob.github.io/easemob-im-server-sdk/)。 -- [Server SDK 开源地址](https://github.com/easemob/easemob-im-server-sdk)。 - -## 常见问题 - -### 集成问题 - -如果你想看 Server SDK 的请求与响应,可以在配置文件中添加: - -```properties -logging.level.com.easemob.im.http=debug -``` - -如果在 Mac 系统上使用 Server SDK 出现 Dns 的警告,可以在配置文件中添加: - -```properties -logging.level.com.easemob.im.shaded.io.netty=error -``` - -### 使用问题 - -目前有开发者在使用 Server SDK 有遇到 `Connection reset by peer` 异常的情况,由于 Server SDK 使用的 Netty 来发送请求,该异常是由 Netty 抛出来的,Netty 官方有相关问题的 issue 并有一些[解决方案](https://github.com/reactor/reactor-netty/issues/1774),不过要依赖于对 Netty 的 `ConnectionProvider` 进行配置,因此 Server SDK 在 `EMProperties` 中增加与之对应的配置项,来让开发者针对自己的使用场景进行对 Netty 的 `ConnectionProvider` 进行配置。比如设置连接数量、连接空闲时间等,如果使用 Server SDK 请求量较大,那可以把连接数设置大一些。 - -示例: - -```java -@Configuration -public class Config { - - @Bean - public EMService service() { - - EMProperties properties = EMProperties.builder() - .setBaseUri("https://Your privatized address name") - .setAppkey("Appkey") - .setClientId("Client ID") - .setClientSecret("Client Secret") - .setHttpConnectionPoolSize(500) - .setHttpConnectionMaxIdleTime(20000) - .setHttpConnectionMaxLifeTime(60000) - .setHttpConnectionPendingAcquireTimeout(60000) - .setHttpConnectionEvictInBackground(120000) - .setServerTimezone("+8") - .build(); - - return new EMService(properties); - } -} -``` - -## 注意事项 - -1. Server SDK 是对环信 IM [REST API](overview.html) 的封装,但并没有封装所有的 API,只封装了开发者常用的 API,点击 [这里](#使用) 查看 Server SDK API。 - -对于注册环信 ID 的规则,Server SDK 有自己的限制,正则为 `^[a-z][0-9a-z-]{1,32}$`,这点与 [官网 REST API 文档](account_system.html#开放注册单个用户) 中说明的环信 ID 规则是有区别的,例如用户 ID 长度限制为 32 字节以内,这样做是因为目前环信 ID 注册的限制范围比较广,Server SDK 考虑缩小环信 ID 注册的限制范围使其更加规范。 - -如果不想使用 Server SDK 注册环信 ID 的限制,可以在初始化配置时添加 ‘turnOffUserNameValidation()’ (SDK 需要使用 0.3.5 以上的版本) - -```java -// 强烈建议不要使用纯数字或者有规律的字符串来注册环信 ID,否则用户可能容易遭受到攻击、接收到垃圾消息。 -EMProperties properties = EMProperties.builder() - .setAppkey("appkey") - .setClientId("Client ID") - .setClientSecret("ClientSecret") - .turnOffUserNameValidation() - .build(); -``` - -1. 使用代理的情况 - -前提需要你的代理支持 `CONNECT` 方法,确保你的代理配置文件中有 connectport 80 存在。 - -如果你使用的代代理不需要认证,那么需要传入自己的 IP、端口。 - -```java -EMProxy proxy = EMProxy.builder() - .setIP("ip") - .setPort(80) - .build(); - -EMProperties properties = EMProperties.builder() - .setProxy(proxy) - .setAppkey("appkey") - .setClientId("Client ID") - .setClientSecret("ClientSecret") - .build(); -``` - -如果你使用的代理需要认证,那么需要传入自己的 IP、端口、账号以及密码。 - -```java -EMProxy proxy = EMProxy.builder() - .setIP("ip") - .setPort(80) - .setUsername("username") - .setPassword("password") - .build(); - -EMProperties properties = EMProperties.builder() - .setProxy(proxy) - .setAppkey("appkey") - .setClientId("Client ID") - .setClientSecret("ClientSecret") - .build(); -``` - -## 更新日志 - -### V0.8.56 2024-11-20 - -1. 创建用户修改密码长度限制。 - -以上更新内容请到 UserApi 中查看。 - -### V0.8.55 2024-09-09 - -1. 增加 Presence 功能。 -2. 更新 javadoc sdk 文档。 - -以上更新内容请到 PresenceApi 中查看。 - -### V0.8.54 2024-07-29 - -1. 创建群组增加群组头像属性。 -2. 修改群组信息支持群组头像修改。 -3. 获取群组详情增加群组头像属性。 -4. 获取用户已加入的群组列表中增加群组头像属性。 - -以上更新内容请到 GroupApi 中查看。 - -### V0.8.53 2024-06-28 - -1. 增加 "批量设置离线推送时显示的昵称" 功能。 - -以上更新内容请到 PushApi 中查看。 - -### V0.8.52 2024-06-07 - -增加 "创建用户带推送昵称" 功能。 - -以上更新内容请到 UserApi 中查看。 - -### V0.8.51 2024-04-08 - -- 增加 "单向清空漫游消息" 功能。 -- 增加 "修改文本或自定义消息" 功能。 -- 增加 "设置好友备注和分页获取好友列表" 功能。 - -以上更新内容请到 MessageApi 、ContactApi 中查看。 - -### V0.8.2 2024-01-11 - -- 增加发送聊天室全局广播功能。 -- 增加群组封禁&群组解禁的功能。 - -以上更新内容请到 GroupApi & MessageApi 中查看。 - -### V0.8.1 2024-01-2 - -- 增加创建大型群组功能。 -- 删除向大型和小型聊天室发送消息的功能。 -- 批量 添加群组成员 & 移除群组成员 去掉用户列表数量检查。 -- 修改获取 用户 Token 功能的注释说明。 - -以上更新内容请到 GroupApi & MessageApi & TokenApi 中查看。 - -### V0.8.0 2023-12-21 - -- 增加 向聊天室发送定向消息 功能。 - -以上更新内容请到 MessageApi 中查看。 - -### V0.7.9 2023-11-28 - -增加查看指定用户是否已加入群组的功能。 - -以上更新内容请到 GroupApi 中查看。 - -### V0.7.8 2023-11-03 - -增加指定群主用户发送消息的功能。 - -以上更新内容请到 MessageApi 中查看。 - -### V0.7.7 2023-10-18 - -修复下载历史消息文件失败的问题。 - -### V0.7.6 2023-08-30 - -增加获取多个聊天室详情的功能。 - -以上更新内容请到 RoomApi 中查看。 - -### V0.7.5 2023-08-24 - -- `EMProperties` 中增加对 `ConnectionProvider` 的配置项,用于解决 Netty 请求连接问题。 -- 支持修改群组公开或私有属性。 -以上更新内容请到 `EMProperties` 和 `GroupApi` 中查看。 - -### V0.7.3 2023-07-05 - -- 发送聊天室消息增加 `chatroom_msg_level` 选项。 - -以上更新内容请到 MessageApi 中查看。 - -### V0.7.2 2023-06-29 - -- 增加禁言全体群成员和解除全员禁言功能。 -- 增加群成员自定义属性相关功能。 -- 处理 Rest 服务异常时 Response 返回为空不抛异常的问题。 - -以上更新内容请到 BlockApi & MetadataApi 中查看。 - -### V0.7.1 2023-06-14 - -- 增加 ttl 对获取环信用户 Token 生效的功能。 - -以上更新内容请到 TokenApi 中查看。 - -### V0.7.0 2023-06-06 - -- 增加批量获取群组详情功能。 -- 增加批量禁言/解禁聊天室成员功能。 -- 增加获取群组成员列表包括群主的功能。 -- `EMProperties` 支持设置 `pendingAcquireMaxCount`。 -- 修正部分方法使用示例错误的问题。 - -以上更新内容请到 `EMProperties/GroupApi/RoomApi/BlockApi` 中查看。 - -### V0.6.9 2023-04-07 - -- 增加批量注册用户功能。 -- 增加批量禁言群组成员功能。 - -以上更新内容请到 UserApi/BlockApi 中查看。 - -### V0.6.8 2023-03-17 - -更新发送消息与消息撤回方法的内部实现。 - -### V0.6.7 2023-02-07 - -修复下载附件方法失败的问题。 - -### V0.6.7 2022-12-02 - -修复注册用户时用户名使用大写字母会失败的问题。 - -### V0.6.6 2022-12-02 - -修复创建/获取/删除用户方法使用大写字母出现异常的问题。 - -### V0.6.3 - -1. 新增 离线推送设置 功能。 -2. 新增 分页获取用户已加入的群组列表 功能。 -3. 新增 批量获取用户属性 功能。 -4. 新增 指定群组 ID 建群 功能,需要联系商务开通。 -5. 修复了一些 Bug。 - -以上更新内容请到 PushApi/GroupApi/MetadataApi 中查看。 - -### V0.6.0 - -1. 新增 聊天室全员禁言/解禁 功能。 -2. 新增 获取聊天室详情返回当前成员人数。 -3. 新增 获取聊天室详情返回成员列表。 -4. 新增 发送消息不返回消息 ID 的方法。 -5. 新增 发送消息可携带 `sync_device` 字段。 - -6. 修复添加群组管理员参数错误无法捕捉异常的问题。 - -以上更新内容请到 `RoomApi/MessageApi` 中查看。 - -### V0.5.5 - -1. 新增 消息撤回 功能。 -2. 新增 删除单向会话 功能。 -3. 建群时增加群组名称是否需要审核参数。 -4. 获取群成员功能增加是否排序的参数。 -5. 获取群组详情返回群组名称、描述等数据。 -6. 修复调用群组批量移除成员方法移除单个成员时,抛出异常的问题。 - -以上更新内容请到 `GroupApi`/`MessageApi` 中查看。 - -### V0.5.4 - -新增 设置用户全局禁言/查询单个用户全局禁言剩余时间/查询所有用户全局禁言剩余时间 功能。 - -以上更新内容请到 `MuteApi` 中查看。 - -### V0.5.3 - -1. 创建群组方法增加 `needInviteConfirm`(邀请用户加群,受邀用户是否需要确认) 参数。 -2. 创建聊天室方法增加 `custom` 参数。 -3. 新增聊天室转让方法。 - -以上更新内容请到 `GroupApi`/`RoomApi` 中查看。 - -### V0.5.2 - -1. 修改群组信息方法增加 `custom` 参数。 -2. 新增群组转让方法。 - -以上更新内容请到 `GroupApi` 中查看。 diff --git a/docs/document/server-side/java_server_sdk_2.0.md b/docs/document/server-side/java_server_sdk_2.0.md deleted file mode 100644 index 26be2560..00000000 --- a/docs/document/server-side/java_server_sdk_2.0.md +++ /dev/null @@ -1,289 +0,0 @@ -# Java Server SDK 2.0 - - - -## 功能概述 - -Server SDK 2.0 是对环信 IM [REST API](overview.html) 的封装,这样做是为了节省服务器端开发者对接环信 API 的时间,只需要配置自己的 App Key 相关信息即可使用。 - -Server SDK 2.0 提供了用户、消息、群组、聊天室等资源的操作管理能力。 - -## 前提条件 - -- Java 1.8 -- 有效的环信即时通讯 IM 开发者账号和 App Key、Client ID、ClientSecret、BasePath,登录 [环信管理后台](https://console.easemob.com/user/login) 到“应用列表” → 点击“查看”即可获取到 App Key、Client ID、ClientSecret,到"即时通讯" → 点击"服务概览"获取到 "Rest api" 的服务器域名。 - -## 实现方法 - -### 安装 - -如果你的项目使用 Maven 构建,在 pom.xml 中添加下面代码: - -```xml - - com.easemob.im - im-sdk-core - 1.0.11 - -``` - -如果你的项目使用 Gradle 构建,可以在 build.gradle 中添加下面代码: - -```gradle -implementation 'com.easemob.im:im-sdk-core:1.0.11' -``` - -### 使用 - -在使用 Java Server SDK 前,需要进行初始化: - -#### 1. 使用 Easemob App Credentials 的情况 - -```java -SDK 初始化建议写到配置类中,示例如下: -@Configuration -public class Config { - - static { - try { - com.easemob.im.Configuration.setDefaultApiClient(ApiClient.builder() - .setBasePath("Rest BasePath") - .setAppKey("Appkey") - .setClientId("Client ID") - .setClientSecret("Client Secret") - .build()); - } catch (ApiException e) { - // exception handling - } - } - -} -``` - -根据业务资源,API 分为: - -- ChatFile 用于上传下载附件。 -- Block 用于限制访问(将用户加入黑名单)。 -- Contact 用于管理联系人(添加好友等)。 -- Group 用于管理群组。 -- Thread 用于管理群组子区。 -- Message 用于发送消息。 -- HistoryMessage 用于下载历史消息记录。 -- User 用于管理用户。 -- Metadata 用于管理用户属性、群成员属性。 -- Token 用于获取用户 Token。 -- Room 用于管理聊天室。 -- Push 用于管理推送设置。 -- Presence 用于管理用户在线状态订阅。 -- Reaction 用于管理消息表情回复。 - -每个业务资源对应一个类,例如,用户相关的 API,都可以在 `UserAPi`中 找到。 - -举个例子,我们要注册一个用户,就可以这样写: - -注意:在使用各业务 API 前,一定要保证 SDK 初始化完成。 - -```java -@Service -public class UserService { - - private UserApi userApi = new UserApi(); - - private void createUser() { - List emCreateUserList = new ArrayList<>(); - EMCreateUser createUser = new EMCreateUser(); - createUser.setUsername("user1"); - createUser.setPassword("123"); - emCreateUserList.add(createUser); - - try { - EMCreateUsersResult result = userApi.createUsers(emCreateUserList); - } catch (EMException e) { - e.getMessage(); - } - - } -} -``` - -各业务 API 的使用可以参考 [集成测试](https://github.com/easemob/easemob-im-server-sdk/tree/master_java_2.0/src/test/java/com/easemob/im/api)。 - -#### 2.私有化配置,将你自己的私有化 REST 服务器地址设置给 `setBasePath` 即可。 - -建议写到配置类中,示例如下: - -```java -try { - Configuration.setDefaultApiClient(ApiClient.builder() - .setBasePath("https://Your privatized address name") - .setAppKey("Appkey") - .setClientId("Client ID") - .setClientSecret("Client Secret") - .build()); -} catch (ApiException e) { - throw new RuntimeException(e); -} -``` - -## 参考 - -- [Server SDK 开源地址](https://github.com/easemob/easemob-im-server-sdk/tree/master_java_2.0)。 - -## 常见问题 - -### 使用问题 - -如果开发者请求的 API 量比较大,可以设置连接池的连接数量、连接空闲时间等进行调优。 - -示例: - -```java -try { - Configuration.setDefaultApiClient(ApiClient.builder() - .setBasePath("Rest BasePath") - .setAppKey("Appkey") - .setClientId("Client ID") - .setClientSecret("Client Secret") - .setMaxIdleConnections(100) - .setConnectKeepAliveMilliSeconds(10000) - .setConnectTimeoutMilliSeconds(10000) - .build()); -} catch (ApiException e) { - throw new RuntimeException(e); -} -``` - -## 注意事项 - -1.使用代理的情况 - -前提需要你的代理支持 `CONNECT` 方法,确保你的代理配置文件中有 connectport 80 存在。 - -如果你使用的代代理不需要认证,那么需要传入自己的 IP、端口。 - -```java -ApiClient.EMProxy proxy = ApiClient.EMProxy.builder() - .setIP("ip") - .setPort(80) - .build(); - -try { - Configuration.setDefaultApiClient(ApiClient.builder() - .setProxy(proxy) - .setBasePath("Rest BasePath") - .setAppKey("Appkey") - .setClientId("Client ID") - .setClientSecret("Client Secret") - .build()); -} catch (ApiException e) { - throw new RuntimeException(e); -} -``` - -如果你使用的代理需要认证,那么需要传入自己的 IP、端口、账号以及密码。 - -```java -ApiClient.EMProxy proxy = ApiClient.EMProxy.builder() - .setIP("ip") - .setPort(80) - .setUsername("username") - .setPassword("password") - .build(); - -try { - Configuration.setDefaultApiClient(ApiClient.builder() - .setProxy(proxy) - .setBasePath("Rest BasePath") - .setAppKey("Appkey") - .setClientId("Client ID") - .setClientSecret("Client Secret") - .build()); -} catch (ApiException e) { - throw new RuntimeException(e); -} -``` - -## 更新日志 - -### V1.0.11 2024-11-20 - -1. 增加 '批量设置群成员自定义属性' 功能。 - -以上更新内容请到 MetadataApi 中查看。 - -### V1.0.10 2024-09-21 - -1. 增加[根据消息 ID 单向删除单聊漫游消息](message_delete.html#根据消息-id-单向删除单聊漫游消息)功能。 -2. 增加[根据消息 ID 单向删除群聊漫游消息](message_delete.html#根据消息-id-单向删除群聊漫游消息)功能。 -3. 增加根据指定 ID 创建聊天室的功能。 -4. 增加根据指定 ID 创建群组的功能。 - -以上更新内容请到 MessageApi、RoomApi、GroupApi 中查看。 - -### V1.0.9 2024-07-29 - -1. 增加[发送聊天室全局广播消息](message_chatroom.html#发送聊天室全局广播消息)功能。 -2. 增加[导入好友列表](user_relationship.html#导入好友列表)功能。 -3. 增加[强制用户从单设备下线](account_system.html#强制用户从单设备下线)功能。 -4. [创建群组增加群组头像属性](group_manage.html#创建群组)。 -5. [修改群组信息支持群组头像修改](group_manage.html#修改群组信息)。 -6. [获取群组详情增加群组头像属性](group_manage.html#获取群组详情)。 -7. [获取用户已加入的群组列表](group_manage.html#获取单个用户加入的所有群组)中增加群组头像属性。 - -以上更新内容请到 MessageApi、ContactApi、UserApi、GroupApi 中查看。 - -### V1.0.8 2024-07-15 - -1. 解决依赖冲突的问题。 - -### V1.0.7 2024-06-28 - -1. 增加[批量修改用户推送昵称](push.html#批量设置离线推送时显示的昵称)功能。 - -2. 增加发送图片、语音、视频、文件、透传、扩展、自定义消息示例功能。 - -以上更新内容请到 UserApi、MessageApiTest 中查看。 - -### V1.0.6 2024-06-07 - -1. 增加[批量移除群组成员](group_member.html#批量移除群组成员)功能。 - -2. 增加[一次性获取好友列表](user_relationship.html#一次性获取好友列表)功能。 - -3. [注册用户](account_system.html#开放注册单个用户)增加推送昵称参数。 - -以上更新内容请到 GroupApi、ContactApi、UserApi 中查看。 - -### V1.0.5 2024-04-08 - -处理开发者引用 okhttp、gson 与 sdk 内部引用相同依赖版本不同产生的冲突问题。 - -### V1.0.4 2024-04-08 - -修复 "群组和聊天室定向消息" 功能不生效的问题。 - -以上更新内容请到 MessageApi 中查看。 - -### V1.0.3 2024-03-28 - -1. 增加 "单向清空漫游消息" 功能。 - -2. 增加 "修改文本或自定义消息" 功能。 - -3. 增加 "群组和聊天室定向消息" 功能。 - -4. 对 "创建群组" 和 "修改群组信息" 方法中的 membersonly 注释进行修改。 - -5. "获取单个用户加入的所有群组" 方法返回值增加 total 参数。 - -以上更新内容请到 MessageApi 、EMCreateMessage、EMCreateGroup、EMModifyGroup、EMGetUserJoinedGroupsResult 中查看。 - -### V1.0.2 2024-03-21 - -1. 增加 Push & Presence & Reaction 管理功能。 - -2. 降低 OkHttp 版本,避免与开发者引入的版本冲突。 - -### V1.0.0 2024-03-08 - -1. Java Server SDK 2.0 版本发布。 diff --git a/docs/document/server-side/php_server_sdk.md b/docs/document/server-side/php_server_sdk.md deleted file mode 100644 index 8b002119..00000000 --- a/docs/document/server-side/php_server_sdk.md +++ /dev/null @@ -1,150 +0,0 @@ -# PHP Server SDK - - - -## 介绍 - -PHP SDK 是对环信 IM [REST API](overview.html) 的封装,旨在节省服务器端开发者对接环信 API 的时间,只需要配置自己的 App Key 相关信息即可使用。 - -## 功能 - -PHP SDK 提供了用户、消息、群组、聊天室等资源的操作管理能力。 - -## 依赖 - -- PHP 5.3+ - -## 安装 - -直接使用 [composer](https://www.phpcomposer.com/) 进行安装 - -```shell -composer require maniac/easemob-php -``` - -## 目录结构 - -- examples 示例文件目录 -- runtime 临时文件、缓存文件目录 -- src 核心文件目录 -- tests 测试文件目录 - -## 准备 - -使用 PHP SDK 之前,需准备环信 App Key、Rest Api 服务器域名、 Client ID 和 Client Secret。 - -如果你有环信管理后台账号并创建过应用,请先登录环信管理后台,点击 [这里](https://console.easemob.com/user/login),然后在 **应用列表** 中点击 **管理** 即可获取 appkey、Client ID 和 ClientSecret。在左侧导航栏选择 **即时通讯** > **服务概览**。在 **服务概览** 页面的 **域名配置** 区域中查看 **Rest api** 的服务器域名。 - -如果你没有环信管理后台账号,请先注册账号,点击 [这里](https://console.easemob.com/user/register),注册成功后请登录,然后点击 **添加应用**,添加成功后点击 **管理** 即可获取 appkey、Client ID 和 ClientSecret。在左侧导航栏选择 **即时通讯** > **服务概览**。在 **服务概览** 页面的 **域名配置** 区域中查看 **Rest api** 的服务器域名。 - -## 使用 - -如果使用 Laravel、YII、ThinkPHP 之类的框架,composer 安装的库会自动加载,如果没有使用框架,需要手动引入 `vendor/autoload.php` 文件。 - -使用所有的类之前,均需先初始化授权对象,然后在初始化其他类时传入授权对象。 - -```php -require 'vendor/autoload.php'; - -use Easemob\Auth; -use Easemob\User; - -$auth = new Auth("appKey", "Client ID", "ClientSecret"); -$auth->setApiUri("rest api domain"); - -$user = new User($auth); -``` - -根据业务资源,API 分为: - -- Attachment 用于上传下载附件 -- Block 用于限制访问(将用户加入黑名单、群组/聊天室禁言等) -- Contact 用于管理联系人(添加好友等) -- Group 用于管理群组 -- Message 用于发送消息 -- User 用于管理用户 -- UserMetadata 用于管理用户属性 -- Push 用于管理用户推送(设置推送免打扰等) -- Room 用于管理聊天室 -- WhiteList 用于管理白名单 - -每个业务资源对应一个方法,例如,用户相关的 API,都可以在 User 类中找到。 - -例如,注册用户,示例代码如下: - -```php -require 'vendor/autoload.php'; - -use Easemob\Auth; -use Easemob\User; - -$auth = new Auth("appKey", "Client ID", "ClientSecret"); -$auth->setApiUri("rest api domain"); - -$user = new User($auth); - -// 注册单个用户 -$data = array( - 'username' => 'user1', - 'password' => 'user1', - 'nickname' => 'user1', -); -$user->create($data); - - -// 批量注册用户 -$data = array( - array( - 'username' => 'user2', - 'password' => 'user2', - 'nickname' => 'user2', - ), - array( - 'username' => 'user3', - 'password' => 'user3', - 'nickname' => 'user3', - ), -); -$user->create($data); -``` - -## 参考 - -- PHP SDK 的 API 文档在 [这里](https://easemob.github.io/im-php-server-sdk/annotated.html) -- PHP SDK 开源地址在 [这里](https://github.com/easemob/im-php-server-sdk) - -## 常见问题 - -1. 关于 PHP 低版本中文乱码问题 - -在纯 PHP 页面中使用 - -```php -header("Content-Type:text/html;charset=utf-8"); -``` - -在 HTML 和 PHP 混编的页面中使用 - -```html - -``` - -2. 关于 SDK 返回的错误码和错误描述 - -PHP SDK 会直接返回 REST API 的错误码及错误描述,具体请参考 [服务器端 REST API 常见错误码](error.html) - -3. 使用代理的情况 - -初始化授权对象 Auth 之后,可以设置代理: - -```php -require 'vendor/autoload.php'; - -use Easemob\Auth; -use Easemob\Http\Http - -$easemob = $config['easemob']; -$auth = new Auth("appKey", "Client ID", "ClientSecret"); -// 设置代理 -Http::setProxy("ip地址", 8080); -``` diff --git a/docs/private/README.md b/docs/private/README.md deleted file mode 100644 index dc3334c5..00000000 --- a/docs/private/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 私有部署 ---- diff --git a/docs/private/im/README.md b/docs/private/im/README.md deleted file mode 100644 index 9f6d505f..00000000 --- a/docs/private/im/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 即时通讯 ---- diff --git a/docs/private/im/uc_Web_private.md b/docs/private/im/uc_Web_private.md deleted file mode 100644 index 54964b23..00000000 --- a/docs/private/im/uc_Web_private.md +++ /dev/null @@ -1,67 +0,0 @@ -# 私有云 Web SDK 集成配置 - -## Web Vue 2 Demo - -对于 Web Vue Demo,进行私有化配置需在 [Vue 2 Demo 源代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/zq/private-vue2-20230104.zip)中进行修改。 - -### 修改环境配置 - -在 `src/utils/WebIMConfig.js` 文件中,进行如下修改: - -```javascript -appkey: 'easemob#easeim', // 私有化的 App Key -isHttpDNS: false, // 是否允许通过 DNS 获取。由于私有云需自己配置,这里必须为 `false`。 -socketServer: 'https://xxx.xxxxx.com', // 私有化的 WebSocket 地址 -restServer: 'https://xxx.xxxxx.com', // 私有化的 RESTful 服务器地址。对于 Uniapp 全平台,需要全局搜索,查找 `a1.easemob.com` 替换为 `restServer`。 -``` - -### 修改 SDK 初始化配置 - -在 `src/utils/WebIM.js` 文件中,进行如下修改: - -```javascript - appKey: WebIM.config.appkey, - url: WebIM.config.socketServer, - apiUrl: WebIM.config.restServer, - isHttpDNS:WebIM.config.isHttpDNS, // 对于私有云,该参数必须为 `false`。 - // 其他配置可酌情添加 -``` - -## Web Vue 3 Demo - -对于 Web Vue 3 Demo,进行私有化配置需在 [Vue 3 Demo 源代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/zq/private-vue3-20230104.zip)中进行修改。 - -### 修改环境配置 - -在 `src/IM/initwebsdk.js` 文件中,进行如下修改: - -```javascript -const DEFAULT_APPKEY = "easemob#easeim"; // 私有化的 App Key -const DEFAULT_URL = "https://xxx.xxxxx.com"; // 私有化的 WebSocket 地址 -const DEFAULT_APIURL = "https://xxx.xxxxx.com"; // 私有化的 RESTful 服务器地址 -``` - -## Web React Demo - -对于 Web React Demo,进行私有化配置需在 [React Demo 源代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/zq/private-demo-20230104.zip)中进行修改。 - -修改配置如下: - -1. 在 `/demo/src/config/WebIMConfig.js` 中修改配置信息,如下所示: - -```javascript - appkey: appkey || 'easemob-demo#zim', - isHttpDNS: false, - restServer: rest.restServer || (window.location.protocol === 'https:' ? 'https:' : 'http:') + '//xxx.xxxxx.com', - restServer: rest.restServer || (window.location.protocol === 'https:' ? 'https:' : 'http:') + '//xxx.xxxxx.com', -``` - -2. 在 `/demo/src/config/WebIM.js` 中修改初始化配置,如下所示: - -```javascript - appKey: WebIM.config.appkey, - url: WebIM.config.socketServer, - apiUrl: WebIM.config.restServer, -``` - -然后,将 `if(WebIM.config.isSandbox)` 判断去掉,只使用 `options` 中配置的地址。 diff --git a/docs/private/im/uc_android_private.md b/docs/private/im/uc_android_private.md deleted file mode 100644 index e9a36709..00000000 --- a/docs/private/im/uc_android_private.md +++ /dev/null @@ -1,35 +0,0 @@ -# 私有云 Android SDK 集成配置 - - - -## 静态配置 IP(域名)地址 - -SDK 默认指向公有云地址,在部署私有云后,需要将地址重新指向到新的地址,以下是地址修改方法: - -```java -EMOptions emOptions = new EMOptions();//实例化 EMOptions 对象 -emOptions.setRestServer("10.10.10.10:00");//设置私有云 REST 地址(ip/域名:port) -emOptions.setIMServer("10.10.10.10");//设置私有云 IM 地址 -emOptions.setImPort(00);//设置私有云 IM 端口号 -emOptions.enableDNSConfig(false);//默认是 true,在私有云下,需要关闭(设置成 false) - -EMClient.getInstance().init(context,emOptions);//最后初始化 SDK -``` -:::tip -如果需要配置 HTTPS 只需在 REST 地址前加一个前缀。 -::: - -```java -emOptions.setRestServer("https://10.10.10.10:00");//设置私有云 REST 地址(ip:port) -``` - -## 动态配置地址 - -1. 服务器端配置 DNS 地址表 -2. 从服务器端动态获取地址 - -```java -EMOptions emOptions = new EMOptions(); -emOptions.setDnsUrl("url");//从服务器端动态获取地址 -EMClient.getInstance().init(context,emOptions);//初始化 SDK -``` \ No newline at end of file diff --git a/docs/private/im/uc_configure.md b/docs/private/im/uc_configure.md deleted file mode 100644 index 3c65eaeb..00000000 --- a/docs/private/im/uc_configure.md +++ /dev/null @@ -1,134 +0,0 @@ -# 开通配置环信即时通讯 IM 服务 - - - -## 前提条件 - -配置环信即时通讯 IM 服务前,请确保已经具备以下条件: - -- 已部署私有化即时通讯服务。 - -## 创建应用 - -参照以下步骤在环信即时通讯云控制台创建应用和配置即时通讯 IM 服务。 - -1. 登录环信即时通讯云控制台,在首页的**应用列表**区域点击 **创建应用** 按钮,创建即时通讯 IM 应用。 - -![img](/images/privitization/deploy_index.png) - -2. 在 **创建应用** 对话框中,输入新应用的相关信息,点击 **创建** 按钮创建应用。 - -:::tip -1. `appname`:你设置的应用名称,用于生成 App Key。该参数的值只能包含小写字母、数字和连字符,不能超过 32 个字符。 -2. `Appkey`:即时通讯服务分配给每个应用的唯一标识,由 `orgname` 和 `appname` 参数的值组成,生成后无法修改。 -::: - -![img](/images/privitization/deploy_create_app.png) - - - -## 获取环信即时通讯 IM 的信息 - -在环信即时通讯云控制台,你可以查看你的环信即时通讯 IM 服务的如下信息: - -| 应用信息 | 描述 | 如何查看 | -| :--------- | :----- | :------- | -| `Orgname` | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。该参数是 `APPKEY` 的一部分。 | 在环信即时通讯云控制台的 **应用详情** 页面查看。 | -| `Appname` | 你在环信即时通讯云控制台创建应用时填入的应用名称。该参数是 `AppKey` 的一部分。| 在环信即时通讯云控制台的 **应用详情** 页面查看。 | -| `APPKEY` | 应用的唯一标识,由 `Orgname` 和 `Appname` 组成,生成后不允许修改。 | 在环信即时通讯云控制台的 **应用详情** 页面查看。 | - -## 查看和配置功能 - -创建应用后,参照以下步骤在环信即时通讯云控制台上查看环信即时通讯 IM 服务的详情以及进行配置。 - -在环信即时通讯云控制台的首页的 **应用列表** 中,点击目标应用的 **操作** 栏中的 **管理** 按钮,在左侧导航栏选择 **服务管理** > **服务概览** ,您可以查看到当前 App Key 的服务配置并根据实际业务需求管理相关配置,具体操作说明如下: - -1. **免费开通**:指该功能当前服务版本里已包含,可根据实际业务需求选择是否开通;点击 **免费开通**,则可立即开通该功能; -2. **设置**:指该功能已开通且有需要设置的配置项,点击 **设置**,即可进入对应设置页配置; -3. **可调整,联系商务升级**:功能如果当前服务版本中不包含、或需要提高功能状态中的参数值,则通过联系商务调整升级至符合业务需求的服务版本即可; - -![img](/images/privitization/deploy_service.png) - -## 设置消息撤回(REST & 客户端) - -1. 在环信即时通讯云的左侧导航栏中,选择**服务管理** > **服务概览**。在 **服务概览** 页面下,搜索找到消息撤回(REST&客户端),单击右侧的 **设置**(已开通状态下)。 -2. 在弹出的 **消息撤回时间设置** 对话框中,设置消息可撤回时长。端消息撤回时长和 REST 消息撤回时长均不能超过 7 天。 -3. 单击 **确定** 保存配置。 - -![img](/images/privitization/deploy_rest.png) - -## 配置推送证书 - -使用离线推送通知之前,需完成各平台的证书配置。当前支持以下平台:苹果 APNs、谷歌 FCM、华为、小米、OPPO、VIVO 和魅族。 - -开启环信即时通讯 IM 服务后,按照以下步骤添加消息推送证书: - -1. 在环信即时通讯云控制台首页的**应用列表**中,在目标应用的 **操作** 栏中,点击 **管理**。 - -![img](/images/privitization/deploy_credentials.png) - -2. 在左侧导航栏,选择 **即时推送** > **配置证书**,进入 **配置证书** 页面。 - -![img](/images/privitization/deploy_push_settings.png) - -3. 点击 **添加推送证书** 按钮,打开 **添加推送证书** 对话框。 - - -![img](/images/privitization/deploy_push-settings_window.png) - -4. 在 **添加推送证书** 对话框中,填写各厂商平台的相关推送信息,点击 **保存** 按钮,完成证书配置。 - -![img](/images/privitization/deploy_push-settings_form.png) - -## 配置消息回调 - -环信即时通讯 IM 提供消息回调服务。配置回调后,应用服务器会收到所选类型的消息和事件。 - -购买环信即时通讯 IM 服务后,按照以下步骤添加消息回调证书: - -1. 在环信即时通讯云控制台首页的**应用列表**中,在目标应用的 **操作** 栏中点击 **管理**。 - -![img](/images/privitization/deploy_credentials.png) - -2. 在左侧导航栏,选择 **服务管理** > **回调服务**,进入 **回调服务** 页面。 - -![img](/images/privitization/deploy_push_callback.png) - -3. 点击 **添加回调地址** 按钮,打开回调配置对话框,在回调配置对话框中,填写回调相关配置信息,点击 **保存** 按钮,完成回调配置,具体配置内容说明见 [回调配置](/product/enable_and_configure_IM.html#配置回调规则)。 - -![img](/images/privitization/deploy_push_window.png) - - -## 敏感词设置 - -1. 在环信即时通讯云的左侧导航栏中,选择 **服务管理** > **敏感词服务** 。 -2. 在敏感词配置页面,单击 **添加敏感词**,在弹出的 **添加敏感词** 对话框中,自定义敏感词库。 -3. 单击 **确定** 保存配置。 - -![img](/images/privitization/deploy_sensitive_words.png) - -## REST-IP 白名单设置 - -### 添加 IP 白名单 - -1. 在环信即时通讯云的左侧导航栏中,选择 **服务管理** > **白名单服务** 。 -2. 在 **白名单服务** 页面,单击 **添加IP**,在弹出的 **添加 IP** 对话框中,输入 IP 地址。 -:::tip -1. 每次只能输入 1 个 IP 地址,最多可添加 8 个。 -2. 添加 IP 地址成功后 10 分钟后生效。 -3. 若白名单列表为空,则所有 IP 地址均可发 REST 消息。 -::: -3. 单击 **保存** 完成配置。 -![img](/images/privitization/deploy_ip_whitelist.png) - -### 删除 IP 白名单 - -如果你不再允许某个 IP 地址继续发送 REST 消息,可以在 IP 白名单中将其删除。如果你删除了 IP 白名单中所有 IP,即白名单列表为空,则默认所有 IP 地址均可发送 REST 消息。 - -1. 在环信即时通讯云的左侧导航栏中,选择 **服务管理** > **白名单服务**。 - -2. 在 **IP白名单** 列表中,单击目标 IP 右侧的 **删除**。 - -![img](/images/privitization/deploy_ip_allow_list.png) - -3. 单击 **确认**,则删除该 IP 地址。 diff --git a/docs/private/im/uc_deploy.md b/docs/private/im/uc_deploy.md deleted file mode 100644 index ae9e74b6..00000000 --- a/docs/private/im/uc_deploy.md +++ /dev/null @@ -1,120 +0,0 @@ -# 私有化部署流程说明 - - - -## 1、服务说明 - -​ 为满足私有化客户试用体验、二次开发验证及正式使用等需求,我们致力于提供一种高效、安全、灵活的自动化安装部署方案,无论部署在本地服务器、云端或者信创等任意环境,都可以使用到一致的高质量服务。 - -同时为了客户能够更便捷地开始使用产品,整套自动化部署流程非常简单,已提供相应安装介质及统一申请授权流程,只需提供使用需求信息,即可快速获取授权,具体流程可见文中详解,期待满足您的私有化部署需求,为您提供卓越的服务体验。 - -## 2、部署流程 - -![img](/images/privitization/deploy_flowchart.png) - -### 2.1 下载部署资料 - -信息安全已成为国家重要安全战略,各行业客户对业务环境、功能及数据存储的安全性要求越来越高。需要将功能完备的即时通讯服务部署到内网物理服务器集群、公有云以及私有云等多种平台,请根据实际使用场景选择安装包及部署手册,下载后请按照部署手册要求准备环境并实施部署。 - - - - - - - - - - - - - - -
安装包名称适配环境要求下载安装包下载部署手册
环信私有化即时通讯服务安装包(单机版)操作系统:Linux、ubuntu 20 及以上、centos 7 及以上
CPU 架构:X86、ARM
立即下载(X86)
立即下载(ARM)
立即下载
- -### 2.2 申请授权 - -当服务部署完成后,处于未授权状态,需要根据当前服务机器码申请授权。 - -1. 获取机器码 - -使用部署手册中提供的环信控制台信息(包括登录地址、登录账号)进行登录,登录成功后,在环信控制台首页获取机器码标识。 - -![img](/images/privitization/deploy_machine_code.png) - -2. 申请授权码 license - -无论是正式版还是试用版服务,均可通过填写机器码信息申请授权,[申请授权地址](https://get-license.easemob.com/)。 - --正式版:支持设置服务用户量及使用时间,申请后商务经理一日内反馈提供; - --试用版:固定服务用户量及使用时间,申请后立即生成,可进行试用体验; - -3. 配置授权码 license - -获取授权码后,登录环信控制台首页,点击 **激活 License** 按钮,在弹窗中填写授权码信息,点击 **确定** 生效。 - -![img](/images/privitization/deploy_auth_code.png) - -### 2.3 验证服务 - -当服务配置完成后,可直接使用 Web IM-Demo 进行各类消息及功能测试,在浏览器中输入地址:**http://IP:12005**,即可访问 Web IM-Demo。 - -1. 验证授权: - -通过注册用户账号验证服务是否被授权,如果注册成功,则已开通用户授权;如果注册失败,客户端提示错误码 “无 license”,此时需要登录环信控制台检查 license 配置是否生效。 - -2. 验证功能: - -启动两个 Web IM-Demo ,可以完成添加好友、创建会话、发送消息等功能验证。 - -## 3、集成测试 - -当服务端验证完成后,可通过下载需要的客户端 SDK 及 Demo 进行集成体验。环信客户端 SDK 已对 IM 核心服务完成封装, 通过调用 SDK API 接口,即可快速获得消息收发 、会话管理 、群组 、好友 、聊天室等功能。目前客户端 SDK 已覆盖 Windows 、Linux 、MacOS 、Android 、iOS 、Web 、小程序等多种平台,服务器端 SDK 已覆盖 Java 、PHP 等平台,[下载私有化客户端 SDK](http://doc.easemob.com/private/im/uc_private.html#私有化-sdk-下载)。 - -示例一:以 Android 端 demo 体验为例 - -下载并安装 demo 后,打开应用服务器设置页面,配置以下信息: - -- 使用自定义服务器:开启 -- appkey:easemob-demo#zim -- 使用私有化服务器:开启 -- IM server:私有化服务器主机地址 -- IM Port:msync 端口,6717 -- Rest server 地址&端口:Rest API 地址 - -![img](/images/privitization/deploy_android_custom_server.png) - -示例二:以 iOS 端 demo 体验为例 - -下载并安装 demo 后,打开应用服务器设置页面,配置以下信息 - -- 使用自定义服务器:开启 -- appkey:easemob-demo#zim -- Specify Server:开启 -- IM server:私有化服务器主机地址 -- IM Port:msync 端口,6717 -- Rest server 地址&端口:Rest api 地址 - -![img](/images/privitization/deploy_ios_custom_server.png) - -## 4、联系我们 - -如果您准备使用或正在使用私有化即时通讯服务,有任何疑问和建议,欢迎您添加方案负责人或提交工单与我们交流 - -1. 联系方案负责人 - -微信 扫一扫,添加方案负责人: - -![img](/images/privitization/deploy_wechat_code.png) - -2. 提交工单 - -登录[环信通讯云管理后台](https://console.easemob.com/user/login),点击“服务支持-工单支持”,点击“进入工单系统” - -![img](/images/privitization/deploy_ticket.png) - -3. Geek 社区 - -[Geek 开发者社区](http://www.imgeek.org/)里面的环信专区/环信技术交流板块提供了很多常见问题的讨论和解答,您也可以发帖提问,我们的技术和服务人员会尽力解答您的疑问! - -- 技术咨询邮箱:[support@easemob.com](mailto:support@easemob.com) diff --git a/docs/private/im/uc_iOS_private.md b/docs/private/im/uc_iOS_private.md deleted file mode 100644 index 01f346d8..00000000 --- a/docs/private/im/uc_iOS_private.md +++ /dev/null @@ -1,34 +0,0 @@ -# 私有云 iOS SDK 集成配置 - - - -## 静态配置 IP 地址(域名) - -SDK 默认指向公有云地址,在部署私有云后,需要将地址重新指向到新的地址,以下是地址修改方法: - -```objectivec -EMOptions *options = [EMOptions optionsWithAppkey:appkey]; -options.enableDnsConfig = NO; -options.chatPort = 8080;//设置端口号 -options.chatServer = "xxx.xxx.xxx.xxx";//设置 IP 地址 -options.restServer = "xxx.xxx.xxx.xxx:8080";//设置ip:port -options.rtcUrlDomain= "wss://mprtc.easemob.com";//设置多人音视频的服务器域名,此为线上地址 -[[EMClient sharedClient] initializeSDKWithOptions:options]; -``` - -:::tip -如果需要配置 HTTPS 只需加一个属性即可。 -::: - -```objectivec -options.usingHttpsOnly = YES; -``` - -## 动态配置地址 - -1. 服务器端配置 DNS 地址表 -2. 设置服务器端配置的 URL 地址 - -```objectivec -options.dnsURL = @"xxxx";//设置服务器端配置的 URL 地址 -``` \ No newline at end of file diff --git a/docs/private/im/uc_lowcode.md b/docs/private/im/uc_lowcode.md deleted file mode 100644 index fa999c08..00000000 --- a/docs/private/im/uc_lowcode.md +++ /dev/null @@ -1,97 +0,0 @@ -# 轻客服远程协助(个性化协同) - - - -[下载应用 >>](#下载体验)。 - -## 产品介绍 - -环信个性化协同 SDK 是基于 IM+RTC+即时推送整体解决方案,不仅提供好友关系、音视频通话、富媒体消息、群组管理、即时推送等底层通讯能力,还提供了丰富的场景功能及开放的接口设计,能够实现应用复用、个性化开发、数据抓取及横向业务协同,快速为企业高价值客户提供了定制化、个性化的专属服务,提升用户体验,提高用户留存与转化,为企业带来更多的附加价值。 - -![img](/images/privitization/lowcode.png) - - -## 应用场景 -### 售后服务 -支持创建专属售后服务群,支持用户、客服、销售等多种业务角色加入会话,免去衔接沟通困扰,及时响应客户需求,提升用户体验 - -### 社群运营 -支持创建社群,发布社群公告及活动通知,社群成员管理等功能,提高用户活跃度与粘性,打造良好的社群氛围,吸引企业私域用户沉淀 - -### 营销推送 -支持向用户推送运营活动、内容订阅、社交互动等内容,帮助用户快速获取最新、最热门的信息,提高应用日活,实现活跃用户的增长 - -### 业务协同 -支持稳定可靠的消息传输通道,提供文本、图片、文件及自定义消息类型,可对接工单、订单等业务系统,实现业务联动,提高处理效率 - -## 产品功能 - -### 全消息类型 - -支持发送文字、表情、图片、语音、视频、附件、位置、扩展消息、透传消息、自定义消息等类型 - -### 音视频通话 - -支持群内成员发起音视频通话,突破时间与空间限制,提供远程客户服务和技术支持 - -### 群会话管理 - -群消息已读未读状态、群成员身份标签、群禁言等功能,且群组数量及加入群数量无上限 - -### 多端设备同步 - -支持历史消息云端存储,同一用户登录iOS、Android、Web端,消息记录多端同步,方便随时查看历史聊天记录 - -### 开放的接口设计 - -高度开放的接口设计,支持对接内部工单、订单等系统,自定义UI风格,适配企业业务需求 - -### 推送服务 - -支持向苹果、华为、小米、OPPO、vivo、魅族等主流手机厂商发送运营推送通知 - - - -## 产品优势 - -### 敏捷开发,降低上线周期与成本 - -易集成易部署,开箱即用的场景化 UI+SDK,UI 自定义,部署方式灵活适配,可快速复用至现有客户端应用中 - -### 通信中台,推进数智化转型 - -高可靠强协同,「IM+RTC+推送」一站式解决方案,开放接口支持业务扩展与协同,为搭建通讯中台提供底层基础 - -### 数据筛选,挖掘数据实用价值 - -安全存储与筛选,持久化加密存储通讯记录,保障企业信息安全,用户触点回调同步,为数字分析提供数据资源 - -### 安全合规,保障用户隐私安全 - -支持国内外不同区域合规要求,根据最小化和公开透明处理原则,保护不同区域的网络安全、数据安全及用户隐私安全 - -### 自主可控,全面信创适配 - -![img](/images/privitization/uc_client.png) - -## 下载体验 - -个性化协同支持全端(Web、Android 和 iOS)覆盖,为帮助开发者及企业客户更好的体验产品功能,各端应用可通过以下链接下载。您也可以拨打400-622-1776 联系我们,环信会安排专业的顾问,为贵单位提供定制、安全、可扩展的个性化协同解决方案。 - - - - - - - - -
平台应用端下载地址备注
访客端iOS联系商务获取下载后选择【用户模块】注册与登录
Android下载体验下载后选择【用户模块】注册与登录
客服&运管人员iOS联系商务获取下载后选择【运管模块】,使用客服预置账号登录
Android下载体验下载后选择【运管模块】,使用客服预置账号登录
Web点击体验下载后选择【运管模块】,使用客服预置账号登录
- -授权免费开源
-通过签署授权协议,环信可提供个性化协同源码以帮助合作伙伴或最终客户降低开发成本,加速项目进程。请联系程先生 (Tel:17611319060)。 \ No newline at end of file diff --git a/docs/private/im/uc_overview.md b/docs/private/im/uc_overview.md deleted file mode 100644 index 400c8319..00000000 --- a/docs/private/im/uc_overview.md +++ /dev/null @@ -1,86 +0,0 @@ -# 企业协同办公(环信通) - - - -[下载环信通 >>](#下载体验)。 - -## 产品介绍 - -企业智能办公场景解决方案(简称:环信通)是环信基于 10 年以上的行业服务经验,深挖企事业单位办公场景需求,全力打造的安全统一通讯平台,具有低代码、跨平台、易扩展、灵活部署、定制化、全面信创适配等特性,帮助企事业单位快速搭建一站式智慧办公平台,提升沟通与业务协同效率,实现安全高效的数字化转型。 - -![img](/images/privitization/uc_architecture.png) - -## 产品功能 - -#### 即时通讯 - -多样化场景功能,为沟通创造无限可能 - - 单聊、千人群聊 - - 全消息类型 - - 多终端消息同步 - - 已读未读状态 - -#### 音视频会议 - -稳定通话质量,随时随地便捷开会 - - 1080P 高清码流 - - 远程桌面共享 - - 会议控制 - - 成员管理 - -#### 企业通讯录 - -精细化企业通讯录,成员架构灵活配置 - - 组织架构配置 - - 成员批量导入 - - 星标好友 - - 群组管理 - -#### 协同办公 - -任务日程高效协同,重要事项不遗漏 - - 日程管理 - - 会议日程 - - 系统推送 - -#### 信息安全 - -全流程加密策略,信息安全多重保障 - - 水印、阅后即焚 - - 敏感词管理 - - 通讯安全 - - 客户端安全 - -#### 开放平台 - -高度开放接口,快速满足个性化需求 - - H5 应用嵌入 - - 开放 REST 接口 - - 全平台 SDK - - 定制化开发 - -## 全面信创适配 - -![img](/images/privitization/uc_client.png) - -## 产品规格 - -环信通支持私有云、混合云及服务器等多种环境自动部署,既可满足千人以下专有单服务器部署,亦可弹性扩容满足万人以上集群部署。 - - - 单机版:适用于 5000 人以下使用,服务配置(8 核 32GB 内存 200GB 以上硬盘) - - 集群版:适用于万人以上使用,服务可随业务扩展弹性扩容,服务配置(至少3台 8核 32GB 内存 200GB以上硬盘) - -## 下载体验 - -环信通支持全端(Linux、Windows、macOS、Android 和 iOS)覆盖,为帮助开发者及企业客户更好的体验产品功能,各端应用可通过以下链接下载。您也可以拨打400-622-1776 联系我们,环信会安排专业的顾问,为贵单位提供定制、安全、可扩展的企业协同办公解决方案。 - -| 应用端 | 下载地址 | -| :------------------- | :----- | -| Windows | [下载体验](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/win/%E7%8E%AF%E4%BF%A1%E9%80%9A.2.x.exe) | -| Linux | [下载体验](http://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/linux/easemoboa_2.0.3-build0110_amd64.deb)
当前应用适配 Ubuntu 18-Ubuntu 20,如需其他版本请联系商务。| -| macOS | [下载体验](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/mac/%E7%8E%AF%E4%BF%A1%E9%80%9A.2.x.dmg) | -| Android | [下载体验](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/android/app-release.apk) | -| iOS | [下载体验](https://testflight.apple.com/join/j1ssvXm0)| - -授权免费开源
-通过签署授权协议,环信可提供环信通源码以帮助合作伙伴或最终客户降低开发成本,加速项目进程。请联系程先生 (Tel:17611319060)。 \ No newline at end of file diff --git a/docs/private/im/uc_private.md b/docs/private/im/uc_private.md deleted file mode 100644 index a67754ba..00000000 --- a/docs/private/im/uc_private.md +++ /dev/null @@ -1,256 +0,0 @@ -# 私有化即时通讯 - - - -[下载私有化 SDK >>](#私有化-sdk-下载)。 - -环信即时通讯私有化服务是基于 IM 核心技术实现的可私有化部署解决方案。本方案可适配内网物理服务器集群、公有云以及私有云等任意部署环境,提供功能完备、安全可靠、易于扩展的即时通讯平台。整体通讯平台架构主要由三部分组成,分别为客户端、服务端、Web 控制台。 - -- **客户端**:采用 SDK 形式,对核心通信模块进行封装,提供场景功能接口,覆盖多种平台(包括:Android、iOS、Web、小程序、 Windows/Mac OS、Linux),支持快速集成终端用户应用。 -- **服务端**:采用 Java 和 Erlang 语言编写,可支持用户高并发连接和系统动态调配,高效处理用户长连接相关的服务和用户管理、推送等无状态服务。同时提供服务端 REST API 和 Java Server SDK 接口,便于完成即时通讯软件中服务的控制、数据的转发存储工作。 -- **Web 控制台**:是基于 B/S 模式的可视化操作平台,可支持开通与配置应用功能,查询各类 IM 服务情况,管理与维护用户体系(增、删、改、查),满足系统管理员、开发者等多种业务角色使用需求,提升业务集成与运营管理效率。 - -## 私有化服务优势 - -### 部署多样化 - -环信即时通讯系统支持 Linux 裸系统、容器化等多种部署方式。不仅可以提供更灵活、更便捷、更稳定的平台性能,同时容器化部署可实现自动部署,具备服务自动发现、服务自动负载均衡等特点。 - -### 高可用 - -环信即时通讯系统具备高可用特性,当系统内某一个节点或主机出现宕机后,该故障节点上的所有服务会自动转移到其他节点上而不会引发服务中断,保障系统可用性。 - -### 易扩展 - -环信即时通讯系统服务架构支持弹性扩展,系统内所有资源可在各节点之间实现灵活调度,当 CPU、内存等计算资源利用率较高时,可通过横向添加 node 实现平滑扩容。 - -### 安全性 - -环信即时通讯系统实现通讯全流程安全加密,支持客户端敏感信息加密存储、服务器密钥权限管理、消息传输过程私有协议加密以及用户信息隐私保护等措施。 - -### 国产化 - -环信即时通讯系统严格遵循国家法律法规和技术标准规范,积极响应国内自主可控、安全可控要求,从 IT 基础设置、操作系统、数据库等方面进行国产化升级,满足信创环境部署要求。 - -## 私有化 SDK 下载 - -环信客户端及服务端 SDK 已对 IM 核心服务完成封装,通过调用 SDK API 接口,即可快速获得消息收发、会话管理、群组、好友、聊天室等功能,目前客户端 SDK 已覆盖 Windows、Linux、MacOS、Android、iOS、Web、小程序等多种平台,服务器端 SDK 已覆盖 Java、PHP 等平台,各端 SDK 下载及开发指南如下所示。 - -:::tip - -1. 若要体验环信即时通讯 IM 的功能,可下载[公有云 Demo](https://www.easemob.com/download/demo)。 -2. 若要体验私有化 Demo,需下载下表中对应平台的 Demo,然后在登录页面的**服务器配置**区域完成配置。 -3. 若要集成,需选择下表中的 SDK 及 Demo 版本,按照下表中**开发指南**一列的文档配置私有化环境信息。 - ::: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

SDK 类型

-
-

平台

-
-

版本号

-
-

下载地址

-
-

开发指南

-
-

 

-

客户端 SDK

-
-

Android

-
-

3.9.1

-
-

下载 SDK 及 Demo 体验 Demo

-
-

查看

-
-

Web

-
-

4.0.4

-
-

• React: 下载 SDK 及 Demo 体验 Demo
• Vue 2: 下载 SDK 及 Demo
• Vue 3: 下载 SDK 及 Demo

-
-

查看

-
-

iOS

-
-

3.9.1

-
-

下载 SDK 及 Demo 

-
-

查看

-
-

Windows(C++)

-
-

3.9.1

-
-

下载 SDK 及 Demo

-
-

查看

-
-

Windows(C#)

-
-

1.0.2

-
-

下载 SDK

-
-

查看

-
-

Linux

-
-

3.1.0

-
-

下载 SDK

-
-

查看

-
-

Electron

-
-

3.8.4

-
-

下载 SDK

-
-

查看

-
-

uni-app

-
-

4.0.4

-
-

下载 SDK 及 Demo

-
-

查看

-
-

小程序

-
-

4.0.4

-
-

下载 SDK 及 Demo

-
-

查看

-
-

Unity

-
-

3.9.0

-
-

下载 SDK

-
 
-

Flutter

-
-

3.9.0+2

-
-

下载 SDK

-
-

查看

-
-

 

-

服务端 SDK

-
-

Java

-
-

0.6.3

-
-

下载 SDK

-
-

查看

-
-

PHP

-
-

0.1.0

-
-

下载 SDK

-
-

查看

-
diff --git a/docs/private/media/README.md b/docs/private/media/README.md deleted file mode 100644 index 7763bfcd..00000000 --- a/docs/private/media/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 音视频 ---- diff --git a/docs/private/media/common_clientsdk.md b/docs/private/media/common_clientsdk.md deleted file mode 100644 index 4a17a0fa..00000000 --- a/docs/private/media/common_clientsdk.md +++ /dev/null @@ -1,73 +0,0 @@ -# 客户端下载 - -## 音视频SDK下载 - -将即时通讯和音视频能力封装在一个SDK中,同时已在Demo中提供1对1通话及多人通话实现方案。 - - - - - - - - - - - - - - - - - - - - - -
方案平台说明下载SDK及Demo下载应用
音视频SDKAndroidSDK 兼容 android 5.0及以上版本,easeUI 兼容 android 5.0及以上版本下载代码体验Demo
iOSSDK 兼容 iOS 10及以上版本下载代码体验Demo
Web环信 WebIM SDK 为 PC /移动 Web 应用,提供完善的即时通信与音视频功能下载代码体验Demo
小程序端环信小程序 SDK提供全平台小程序解决方案,支持平台包括微信小程序、QQ小程序、百度小程序、抖音以及Uniapp编译的原生应用下载代码\
- - -## 场景DEMO及源码下载 - -针对音视频云的常见使用场景,环信提供了场景Demo,让开发者可以在了解最佳实践的同时,低成本快速上线 - - - - - - - - - - - - - - - - - - - - - - - -
方案说明平台下载SDK及Demo下载应用
视频会议音视频会议可以支持创建会议、加入会议等功能Android下载代码体验Demo
iOS下载代码\
Web下载代码体验Demo
桌面端下载代码体验Windows Demo

体验MAC Demo
\ No newline at end of file diff --git a/docs/private/media/common_error_code.md b/docs/private/media/common_error_code.md deleted file mode 100644 index 33bbfda9..00000000 --- a/docs/private/media/common_error_code.md +++ /dev/null @@ -1,165 +0,0 @@ -# 音视频错误码描述 - -## 服务端错误码 - -SUCCESS(0) 成功 - -TOKEN_AUTHZ_FAIL(-100) imtoken认证失败 - -ILLEGAL_RIGHTS(-101) 权限不够,比如观众不允许发布流 - -REQUEST_PARAMS_ERROR(-200) 请求参数不正确 - -CONFR_NOT_EXIST(-301) 会议不存在,可能是超时 - -CONFR_DISBAND(-302) 会议被解散 - -SYS_REFUSE_CRT_CONFR(-700) 不允许创建会议 - -SYS_REFUSE_ENTER_CONFR(-701) 不允许加入会议 - -SYS_REFUSE_CHANAGE_ROLES(-702) 不允许更改成员权限 - -RTC_SERVICE_NON_ACTIVATED(-706) rtc服务不可用,比如没有开通rtc服务 - -RTC_SERVICE_ARREARS(-707) rtc服务欠费 - -RTC_SERVICE_DISABLE(-708) rtc服务被封 - -RTC_SERVICE_CLOSED(-709) rtc服务被关闭 - -EXCEPTION(-501) 异常操作,比如在不允许pub流时强行pub流 - -TICKET_INVALID(-500) ticket不可用,比如解析失败 - -TICKET_EXPIRED(-502) ticket过期 - -MEMBER_INVALID(-504) 成员不正确,比如ticket验证失败,成员过期 - -CONFR_INVALID(-506) 会议不可用,比如会议过期,被关闭 - -PASSWORD_INVALID(-508) 密码不正确 - -NOT_SUPPORT_CLIENT(-510) 不支持的终端 - -SUBFAIL_NOT_SUPPORT_VCODES(-520) 不支持的编码方式 - -CONFR_MEMBER_TOO_MANY(-522) 会议成员太多 - -CONFR_TALKER_TOO_MANY(-523) 会议主播太多 - -PUB_VIDEO_TOO_MANY(-524) 发布视频流太多 - -REQUIRE_SDP(-550) 需要提供sdp - -REQUIRE_RTC(-552) 需要支持rtc - -PUB_INACTIVE(-554) 发布流失败 - -BAD_REQUEST(-501) 错误的请求,包含很多情况 - -NOT_SUPPORT_OPER(-507) 不支持的操作,比如不可见的成员要求更改流设置 - -## 移动端错误码 - -### Android端错误码 - -GENERAL_ERROR = 1 一般错误,未细分的错误一般通过此errorcode抛出来 - -NETWORK_ERROR = 2 网络异常 - -CALL_INVALID_ID = 800 callid无效 - -CALL_BUSY = 801 正在通话中 - -CALL_REMOTE_OFFLINE = 802 对方不在线 - -CALL_CONNECTION_ERROR = 803 建立连接失败 - -CALL_CONFERENCE_CREATE_FAILED = 804 会议创建失败 - -CALL_CONFERENCE_CANCEL = 805 会议取消 - -CALL_ALREADY_JOIN = 806 已经加入 - -CALL_ALREADY_PUB = 807 已经 Publish - -CALL_ALREADY_SUB = 808 已经 Subscribe - -CALL_NO_SESSION = 809 没有 Session - -CALL_NO_PUBLISH = 810 没有 Publish - -CALL_NO_SUBSCRIBE = 811 没有 Subscribe - -CALL_NO_STREAM = 812 没有 Stream - -CALL_TICKET_INVALID = 813 会议 Ticket 无效 - -CALL_TICKET_EXPIRED = 814 会议 Ticket 过期 - -CALL_SESSION_EXPIRED = 815 会议会话过期 - -CALL_CONFERENCE_NO_EXIST = 816 会议不存在或者已经解散 - -CALL_INVALID_CAMERA_INDEX = 817 无效的摄像头编号 - -CALL_INVALID_PARAMS = 818 无效的会议参数 - -CALL_CONNECTION_TIMEOUT = 819 通话连接超时 - -CALL_JOIN_TIMEOUT = 820 通话加入超时 - -CALL_OTHER_DEVICE = 821 通过其他设备加入会议 - -CALL_CONFERENCE_DISMISS = 822 会议解散 - -CALL_TALKER_ISFULL = 823 主播已满 - -CALL_CONFERENCE_ALREADY_IN_CONFERENCE = 824 主播已经在当前会议中 - -### iOS端错误码 - -EMErrorGeneral = 1, 一般错误 - -EMErrorNetworkUnavailable = 2, 网络不可用 - -EMErrorCallInvalidId = 800, 实时通话ID无效 - -EMErrorCallBusy = 801, 已经在进行实时通话了 - -EMErrorCallRemoteOffline = 802, 对方不在线 - -EMErrorCallConnectFailed = 803, 实时通话建立连接失败 - -EMErrorCallCreateFailed = 804, 创建实时通话失败 - -EMErrorCallCancel = 805, 取消实时通话 - -EMErrorCallAlreadyJoined= 806, 已经加入了实时通话 - -EMErrorCallAlreadyPub= 807, 已经上传了本地数据流 - -EMErrorCallAlreadySub= 808, 已经订阅了该数据流 - -EMErrorCallNotExist = 809, 实时通话不存在 - -EMErrorCallNoPublish = 810, 实时通话没有已经上传的数据流 - -EMErrorCallNoSubscribe = 811, 实时通话没有订阅数据流 - -EMErrorCallNoStream = 812, 实时通话没有数据流 - -EMErrorCallInvalidTicket = 813, 无效的ticket - -EMErrorCallTicketExpired = 814, ticket已过期 - -EMErrorCallSessionExpired = 815, 实时通话已过期 - -EMErrorCallInvalidParams = 818, 无效的会议参数 - -EMErrorCallSpeakerFull = 823, 主播个数已达到上限 - -EMErrorCallVideoFull = 824, 视频个数已达到上限 - -EMErrorCallCDNError = 825, cdn推流错误 \ No newline at end of file diff --git a/docs/private/media/common_faq.md b/docs/private/media/common_faq.md deleted file mode 100644 index 08da2317..00000000 --- a/docs/private/media/common_faq.md +++ /dev/null @@ -1,112 +0,0 @@ -# 常见问题 - -## 概述 -本文主要列举使用服务时遇到的常见问题,列举如下: - -### 业务开通 - -- [如何开通音视频云服务](#如何开通音视频云服务) - - -### 服务集成 - -- [网络异常和用户异常退出的处理](#网络异常和用户异常退出的处理) -- [接受通话邀请方在收到邀请后杀死APP,发起方是否可以收到通知并挂断](#接受通话邀请方在收到邀请后杀死app-发起方是否可以收到通知并挂断) -- [主叫发起后,被叫未接受。主叫挂断后,被叫的接受页面也需要挂断,如何实现](#主叫发起后-被叫未接受。主叫挂断后-被叫的接受页面也需要挂断-如何实现) -- [1对1呼叫对方不在线如何推送](#_1对1呼叫对方不在线如何推送) -- [Web版如何对自己的预览画面镜像](#web版如何对自己的预览画面镜像) -- [Web版如何等比例显示视频](#web版如何等比例显示视频) -- [音视频通话内容是否加密](#音视频通话内容是否加密) -- [美颜实现Demo](#美颜实现demo) - - - -## 详细信息 - -### 如何开通音视频云服务 - ------ - - -开通环信私有化音视频服务,请联系商务经理程先生(Tel:17611319060) - -### 网络异常和用户异常退出的处理 - ------ - -关于一对一音视频和多人音视频过程中网络异常等事件的处理,建议如下: - -- 本机网络信号不好,会收到SDK发出的回调,APP可以利用此回调展示网络不好的提示。 -- 本机如果网络中断,SDK会持续的进行自动重连,并从SDK发出回调。如果不希望一直进行重连,APP在收到此回调后,可以做一个倒计时。如果在一段时间内,都没有重连成功,则APP可以终止此次音视频。 -- 会议的一个用户异常离开的情况下,是无法发出leave事件的。这种情况下,参会人员会看到掉线的人的画面是卡住的。服务器有心跳检测,超过超时时间后,服务器会广播onMemberExited事件,在EMConferenceListener中会收到该回调,详见各端文档。 - -### 接受通话邀请方在收到邀请后杀死APP,发起方是否可以收到通知并挂断 - ------ - -当会议通知发送给对方后,如果对方杀死APP,这个行为和对方收到会话邀请弹屏但不点击接受邀请是没有区别的。发起方无法检测到对方为何不接受会议。所以发起方无法收到通知并挂断。此外,这个和微信的行为是一致的。 - -### 主叫发起后,被叫未接受。主叫挂断后,被叫的接受页面也需要挂断,如何实现 - ------ - -这个功能需要通过APP自己的应用服务器来实现,需要应用服务器记住当前有哪些人是处于正在加入会议状态,然后主叫挂断后通知给APP自己的业务服务器,业务服务器给这些人发消息告诉他们主叫已经终止会议了。 -:::tip -针对利用多人会议实现一对一通话的场景(为了兼容小程序),因为实质是一对一,所以是知道被邀请方的ID的,直接给对方发个消息就可以实现了。 -::: - -### 1对1呼叫对方不在线如何推送 - ------ - -推荐使用IM消息提醒对方来电,对方会在通知栏看到来电提醒,点击后可以打开app接收来电。 需要先打开EMCallOption#setIsSendPushIfOffline()中的开关,并实现并注册对方离线的回调。 - -以Android为例: - -``` -public interface EMCallPushProvider { - /** - * Function is called when remote peer is offline, we want to let remote peer known we are calling. For IOS that's go through APNS, for Android that's will go through GCM, MiPush, HuaweiPush. Condition: Only works when EMOptions's configuration setPushCall to be true. -*/ - void onRemoteOffline(final String to); - } - - EMClient.getInstance().callManager().setPushProvider(pushProvider); -``` - -### Web版如何对自己的预览画面镜像 - ------ - -设置 video 标签的 css 属性 - -``` -video { - transform: rotateY(180deg); -} -``` -### Web版如何等比例显示视频 - ------ - -可以设置 video 的 css属性 object-fit : fill | contain | cover | none | scale-down, 会输出不同的宽高比 - -详见 https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit - -### 音视频通话内容是否加密 - ------ - -通话内容数据是加密的;加密算法使用AES128。 - -### 美颜实现Demo - ------ - -如果想集成美颜功能,可以自行集成第三方美颜SDK。下面是基于环信IM Demo 集成相芯美颜SDK的 Demo, 可以参考下。 - -如果用户需要使用该方案,需要自行申请相芯的证书,代码repo: - -https://github.com/Faceunity/FUEaseIMDemoDroid - -https://github.com/Faceunity/FUEMiOSDemo \ No newline at end of file diff --git a/docs/private/media/common_introduction.md b/docs/private/media/common_introduction.md deleted file mode 100644 index 16394f86..00000000 --- a/docs/private/media/common_introduction.md +++ /dev/null @@ -1,77 +0,0 @@ -# 音视频概览 - -## 概述 - -私有化音视频平台是为政企用户提供实时音视频能力的系统,该系统支持构建在物理隔离或逻辑隔离的网络环境下。通过该平台,用户可以获得安全可靠的音视频通信能力,并根据自身需求定制化部署和管理私有化音视频服务。 - -## 产品特性 - -- 支持超低延迟的语音通话和视频通话 -- 支持1对1通话时进行P2P传输 -- 支持多人通话的权限控制 -- 支持会议属性,灵活自定义控制 -- 支持云录制 -- 支持超高清视频 -- 支持自适应动态视频码率和帧率 -- 支持对接第三方美颜 -- 增强的弱网适应,抗丢包,抗抖动 -- 增强的语音处理,回音消除,噪声抑制等 -- 支持多集群代理 -- 支持cdn推流 - -## SDK架构 - -![img](/images/privitization/em-rtcsdk-architecture.png) - -环信音视频SDK提供3套API体系,[1对1通话](one2one_introduction),[多人通话](conference_introduction),以上API能满足客户的绝大多数使用场景。 - -## 典型场景 - -环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。 - -![img](/images/privitization/em-rtcsdk-scenarios.png) - -## 兼容性说明 - -环信音视频SDK支持Android、iOS、Web、微信小程序、Windows、macOS、Linux,支持各平台互通,平台兼容性见下表: - -![img](/images/privitization/em-rtcsdk-compatibility.png) - -对于浏览器的支持情况见下表: - - -![img](/images/privitization/em-rtcsdk-compatibility-web.png) - -注意: - -1. 由于Android碎片化严重,微信H5、APP内嵌H5支持大部分手机,有少量手机不支持,如发现不支持手机型号,请反馈给环信工作人员; -2. Android APP内嵌H5建议使用腾讯浏览器内核:https://x5.tencent.com/tbs/product/tbs.html; -3. iOS APP内嵌H5,从iOS13开始支持SFSafariViewController控件,UIWebView和WKWebView目前尚未支持。 - -## 视频编码和码率 - -- 支持的视频编码:H264,VP8 -- 视频码率(带宽占用)是自适应的,不是固定值,会自动根据网络拥塞情况调整清晰度,码率,帧率; -- 各个分辨率的码率范围 - - 240p:150k~400kbps,推荐 200kbps - - 480p:300k~1000bps,推荐 500kbps - - 720p:900k ~2500kbps,推荐 1100kbps - - 1080p: 2000k ~ 5000kbps,推荐 3000kbps - -## 音频编码和码率 - -- 支持的音频编码:Opus,G.711,G.722等,默认使用opus编码 -- 支持可配置码率范围 6k ~ 510kbps,默认32kbps - -## 通话数据流量 - -实时语音(每分钟): - -- 45KB ~ 3.8MB - -实时视频(每分钟): - -- 240p: 1.1MB ~ 3MB -- 480p: 2.2MB ~ 7.5MB -- 720p: 6.7MB ~ 18.7MB -- 1080p: 15MB ~ 37.5MB \ No newline at end of file diff --git a/docs/private/media/conference_android.md b/docs/private/media/conference_android.md deleted file mode 100644 index 917d7f81..00000000 --- a/docs/private/media/conference_android.md +++ /dev/null @@ -1,2097 +0,0 @@ -# Android集成多人通话 - -## 跑通Demo - -### 1. 示例代码 - -- [下载视频会议Demo代码](https://github.com/easemob/videocall-android) -- [体验Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/rtcdemo/videocall-android.apk) - -或进入环信[客户端下载](common_clientsdk.html#场景demo及源码下载)页面,选择下载Android端视频会议 Demo。 - -### 2. 前提条件 - -- Android Studio 3.0 或以上版本 -- Android SDK API 等级 19 或以上 -- Android 4.4 或以上版本的设备 - -### 3. 运行Demo - -#### 3.1 Demo代码目录简介 - -![img](/images/privitization/conference_android_demo.png) -源码目录如上所示,主要目录如以下介绍:
-- ui是有关所有Activity的具体实现 -- runtimepermissions是有关运行是有关动态权限的获取的封装 -- untils是有关工具类的封装 -- DemoHelper和DemoApplication类是全局单例,用来做一些初始化 - -#### 3.2 工程设置,SDK导入 - -选择如下任意一种方式将环信语音SDK集成到你的项目中: - -**方法一:使用 JCenter 自动集成** - -在项目的 /app/build.gradle 文件中,添加如下行: - -``` -dependencies { - ... - // x.x.x 请填写具体版本号,如:3.7.0 - // 可通过 SDK 发版说明取得最新版本号 - api 'com.hyphenate:hyphenate-sdk:x.x.x' - } -``` - -**方法二:手动复制 SDK 文件** - -前往SDK载页面,获取最新版的环信音视频SDK,然后解压;
-将SDK包内libs路径下的如下文件,拷贝到你的项目路径下:
-- hyphenatechat_3.7.0.jar 文件 /app/libs/ -- arm-v8a 文件夹 /app/src/main/jniLibs/ -- armeabi-v7a 文件夹 /app/src/main/jniLibs/ -- x86文件夹 /app/src/main/jniLibs/ -- x86_64文件夹 /app/src/main/jniLibs/ - -#### 3.3 运行项目 - -用Android Studio 运行examples\ChatDemoUI3.0 或者 连接Android 手机,直接运行即可。
-需要注意的的是项目build.gradle中的,配置成和自己Android Studio相匹配的 gradle 版本,如下所示
- -``` -dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' - } -``` - -## 快速集成 - -### 1. 环信后台注册appkey - -环信为管理者与开发者提供了方便易用的App工作台– **环信管理后台**。
-通过环信管理后台可以完成应用创建、服务配置、企业信息修改基础功能;同时,管理后台也提供了发送消息、用户管理、群组管理、聊天室管理和数据统计等管理监控功能。
-在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。 - -### 2. 创建项目 - -- 打开 Android Studio点击Start a new Android Studio project;
-- 在Select a Project Template界面,选择 Phone and Tablet > Empty Activity;
-- 点击 Next;
-- 在 Configure Your Project界面,依次填入以下内容:Name:你的Android项目名称,如 HelloWrold;
-- Package name:你的项目包的名称,如 package.easemob.helloworld;
-- Save location:项目的存储路径;
-- Language:项目的编程语言,如 Java;
-- Minimum API level:项目的最低 API 等级;(**注意本SDK 支持API 19或以上**)
-- 点击 Finish;
-- 根据屏幕提示,安装可能需要的插件;
-上述步骤使用 Android Studio 3.6.2 示例,你也可以直接参考Android Studio 官网文档创建首个应用。 - -### 3. 导入SDK到工程 - -新建项目完成以后,可以选择以上任何一种导入SDK的方法,把环信音视频SDK集成到你的项目里面,参考[导入SDK](#_3-2-工程设置-sdk导入)。 - -### 4. 添加权限 - -根据场景需要,在 /app/src/main/AndroidManifest.xml 文件中添加如下行,获取相应的设备权限;
-在清单文件 AndroidManifest.xml 里加入以下权限,以及写上你注册的 AppKey;
-权限配置(实际开发中可能需要更多的权限,可参考 Demo); - -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ... - -``` - -:::tip -在创建应用后,获取EASEMOB_APPKEY对应的value -::: - - -``` - 申请 AppKey并进行相关配置,环信Demo中AppKey为easemob-demo#chatdemoui; -``` - -### 5. 打包混淆 - -在 app/proguard-rules.pro 文件中添加如下行,防止混淆环信SDK的代码。 - -``` --keep class com.hyphenate.** {*;} - -dontwarn com.hyphenate.** - //3.6.8版本之后移除apache,无需再添加 - -keep class internal.org.apache.http.entity.** {*;} - //如果使用了实时音视频功能 - -keep class com.superrtc.** {*;} - -dontwarn com.superrtc.** -``` - -### 6. 初始化SDK - -初始化环信SDK,可以参考使用DemoHelper中的init方法,可设置私有部署地址或者是否允许日志输出,调用如下: - -``` -public void init(Context context) { - EMOptions options = initChatOptions(context); - appContext = context; - //可设置私有服务地址 - options.setRestServer("a.b.c"); - options.setIMServer("1.2.3.4"); - options.setImPort(8081); - EMClient.getInstance().init(context, options); - //打开日志输出 - EMCallManager manager = EMClient.getInstance().callManager(); - EMClient.getInstance().setDebugMode(true); -} -``` - -### 7. 音视频功能初始化 - -**设置会议监听**
-DemoHelper还有一个重要的功能就是设置[EMConferenceListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html) 进行会议监听, -通过这个监听可以在加入会议的时候获取到已经在会议的流或人员, -调用EMConferenceManager#addConferenceListener(EMConferenceListener listener)方法指定回调监听 -成员加入或离开会议,数据流更新等。 -:::tip -回调监听中的所有方法运行在子线程中,请勿在其中操作UI -::: - -``` -EMConferenceListener listener = new EMConferenceListener() { - @Override public void onMemberJoined(String username) { - // 有成员加入 - } - - @Override public void onMemberExited(String username) { - // 有成员离开 - } - - @Override public void onStreamAdded(EMConferenceStream stream) { - // 有流加入 - } - - @Override public void onStreamRemoved(EMConferenceStream stream) { - // 有流移除 - } - - @Override public void onStreamUpdate(EMConferenceStream stream) { - // 有流更新 - } - - @Override public void onPassiveLeave(int error, String message) { - // 被动离开 - } - - @Override public void onConferenceState(ConferenceState state) { - // 聊天室状态回调 - } - - @Override public void onStreamSetup(String streamId) { - // 流操作成功回调 - } - - @Override public void onSpeakers(final List speakers) { - // 当前说话者回调 - } - - @Override public void onReceiveInvite(String confId, String password, String extension) { - // 收到会议邀请 - if(easeUI.getTopActivity().getClass().getSimpleName().equals("ConferenceActivity")) { - return; - } - Intent conferenceIntent = new Intent(appContext, ConferenceActivity.class); - conferenceIntent.putExtra(Constant.EXTRA_CONFERENCE_ID, confId); - conferenceIntent.putExtra(Constant.EXTRA_CONFERENCE_PASS, password); - conferenceIntent.putExtra(Constant.EXTRA_CONFERENCE_IS_CREATOR, false); - conferenceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - appContext.startActivity(conferenceIntent); - } - - // 在Activity#onCreate()中添加监听 - EMClient.getInstance().conferenceManager().addConferenceListener(conferenceListener); -}); -``` - -### 8. 加入会议 - -在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/android/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。
-若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/android/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7)。
-登录环信ID以后,可以加入会议了,通过 [EMConferenceManager#joinRoom](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8940f54febf2086ccd978d75980c7763) API加入房间。
-- 创建会议成功以后,默认超时时间为三分钟,超过三分钟没有人加入,会议会自动销毁; -- 另外当会议中所有人离开2分钟后,会议也会被销毁; - -joinRoom api在会议不存在会自动去创建,joinRoom有以下两个接口,请看下面详细介绍(第二个多参的方法可以指定所创建会议的各种属性) - -``` -/** - * \~chinese - * 加入多人音视频加议房间 - * @param room 会议房间名 - * @param password 会议房间密码 - * @param role 当前用户加入时指定角色 (EMConferenceRole类型) - * @param callback 回调 - */ - public void joinRoom(final String room ,final String password,final EMConferenceRole role, final EMValueCallBack callback) - - /** - * \~chinese - * 加入多人音视频加议房间 - * @param room 会议房间名 - * @param password 会议房间密码 - * @param roletype 当前用户加入时指定角色 (EMConferenceRole类型) - * @param param 设置会议参数 (EMRoomConfig类型) - * @param callback 回调函数 - */ - public void joinRoom(final String room ,final String password,final EMConferenceRole roletype ,final EMRoomConfig param, final EMValueCallBack callback) - - 有关EMRoomConfig定义如下: - /** - * 会议房间属性类 - * confrTyp 会议类型 - * isSupportVxmini 是否支持小程序 - * isRecord 是否支持录制 - * isMergeRecord 是否支持和流 - * nickName 用户昵称 - * ext 用户头像 - * maxTalkerCount 房间最多主播 - * maxVideoCount 房间最多视频流媒体 - * maxAudienceCount 房间最多观众 - * maxPubDesktopCount 房间最多共享桌面流 - */ - public class EMRoomConfig { - EMConferenceManager.EMConferenceType confrTyp = EMConferenceManager.EMConferenceType.SmallCommunication; - private boolean isSupportMiniProgram = false; - private boolean isRecord = false; - private boolean isMergeRecord = false; - private String nickName = null; - private String ext = null; - private int maxTalkerCount = -1; - private int maxVideoCount = -1; - private int maxAudienceCount = -1; - private int maxPubDesktopCount = -1; - private EMLiveConfig liveConfig = null; - - public EMRoomConfig(EMConferenceManager.EMConferenceType confrTyp, - boolean isSupportMiniProgram,boolean isRecord, - boolean isMergeRecord , String nickName, - String ext, int maxTalkerCount, - int maxVideoCount,int maxAudienceCount, - int maxPubDesktopCount) - {...}; - } -``` - -### 9. 发布流 - -展示从DemoHelper类EMConferenceListener中的onStreamAdded回调和onMemberJoined获取到的流和主播列表。
-在ConferenceActivity中实现EMConferenceListener,然后直接把 ConferenceActivity 注册监听,可以用以下方法:
EMClient.getInstance().conferenceManager().addConferenceListener(this) -这样就可实现 EMConferenceListener 事件的处理,比如主播 **进出房间** **增加流** **移除流** **角色变更** **管理员信息变更**等事件。
- -进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流,不能发布视频流;
-可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置, -比如**是否上传视频** **是否上传音频** **使用前置或后置摄像头** **视频码率** **显示视频页面**等等。
-具体实现可以参考中发布订阅视频流的内容,关于以上的代码逻辑如以 如以下:
- -``` -pirvate void pubLocalStream() { - EMStreamParam param = new EMStreamParam(); - param.setStreamType(EMConferenceStream.StreamType.NORMAL); - param.setVideoOff(false); - param.setAudioOff(false); - param.setVideoWidth(720); - param.setVideoHeight(480); - EMClient.getInstance().conferenceManager().publish(param, new EMValueCallBack() { - @Override - public void onSuccess(String streamId) { - } - - @Override - public void onError(int error, String errorMsg) { - EMLog.e(TAG, "publish failed: error=" + error + ", msg=" + errorMsg); - } - }); -} -``` -:::tip -注意:如果是纯音频会议,只需要在发布数据流时将EMStreamParam中的setVideoOff置为true即可, - 共享桌面时候发布的是桌面流 EMConferenceStream.StreamType.DESKTOP -::: - -**设置视频流的参数** - -如果用户想对发布的音频或者视频流的参数进行调整,可以使用EMStreamParam中的参数进行设置。
只发布音频流,可以设置关闭视频, -设置视频流的分辨率 - -``` - normalParam.setVideoOff(true); - normalParam.setVideoHeight(720); - normalParam.setVideoWidth(1280); -``` - -### 10. 订阅流 - -成员A成功发布数据流后,会议中其他成员会收到,监听类回调EMConferenceListener#onStreamAdded
-如果成员B想看成员A的音视频,可以调用subscribe接口进行订阅 - -``` -@Override - public void onStreamAdded(final EMConferenceStream stream) { - runOnUiThread(new Runnable() { - @Override - public void run() { - ConferenceMemberView memberView = new ConferenceMemberView(activity); - // 添加当前view到界面 - callConferenceViewGroup.addView(memberView); - // 设置当前view的一些状态 - memberView.setUsername(stream.getUsername()); - memberView.setStreamId(stream.getStreamId()); - memberView.setAudioOff(stream.isAudioOff()); - memberView.setVideoOff(stream.isVideoOff()); - memberView.setDesktop(stream.getStreamType() == EMConferenceStream.StreamType.DESKTOP); - - EMClient.getInstance().conferenceManager().subscribe(stream, memberView.getSurfaceView(), new EMValueCallBack() { - @Override - public void onSuccess(String value) { - } - - @Override - public void onError(int error, String errorMsg) { - - } - }); - } - }); -} -``` - -### 11. 退出会议 - -成员B可以调用EMConferenceManager#exitConference接口离开会议, -会议中的其他成员会收到回调EMConferenceListener#onMemberExited -:::tip -注意:当最后一个成员调用leave接口后,会议会自动销毁 -::: -``` -EMClient.getInstance().conferenceManager().exitConference() -@Override - public void onMemberExited(final EMConferenceMember member) { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(activity, member.memberName + " removed conference!", Toast.LENGTH_SHORT).show(); - } - }); -} -``` - -## 进阶功能 - -### 会议管理 - -#### **取日志** - -SDK会写入日志文件到本地。日志文件路径如下:sdcard/Android/data/(自己App包名)/(appkey)/core_log/easemob.log;
-以Demo为例,通过adb命令获取本地的log: - -``` -adb pull /sdcard/Android/data/com.hyphenate.chatuidemo/easemob-demo#chatdemoui/core_log/easemob.log -``` - -#### **创建会议并加入** - -SDK还提供了createAndJoinConference接口创建并加入会议。 -- A调用该接口后,将拥有一个会议实例Conference,同时A将成为该Conference的成员且角色是Admin; -- 用户创建会议时可以设置参数指定是否支持小程序音视频,是否需要在服务器端录制,录制时是否合并流; -- 通过这个AIP创建会议以后,其他人可以通过joinConference通过会议ID,密码方式加入会议;
- -createAndJoinConference可以有以下四种方法去创建,请看以下方法详细介绍 - -``` -**方法一:参数(会议类型,会议密码,是否支持小程序,是否录制,是否合流, 回调);** - - public void createAndJoinConference(final EMConferenceType type, final String password, - final boolean isSupportMiniProgram,final - boolean recordOnServer,final boolean mergeStream, - final EMValueCallBack callback) - EMClient.getInstance().conferenceManager().createAndJoinConference(emConferenceType, - password, true, false, false, new EMValueCallBack() { - @Override - public void onSuccess(EMConference value) { - // 返回当前会议对象实例 value - // 可进行推流等相关操作 - // 运行在子线程中,勿直接操作UI - } - - @Override - public void onError(int error, String errorMsg) { - // 运行在子线程中,勿直接操作UI - } - }); - - -** 方法二:参数(会议类型,会议密码,回调);** - - public void createAndJoinConference(final EMConferenceType type, final String password, - final EMValueCallBack callback){} - EMClient.getInstance().conferenceManager().createAndJoinConference(emConferenceType, - password, new EMValueCallBack() { - @Override - public void onSuccess(EMConference value) { - // 返回当前会议对象实例 value - // 可进行推流等相关操作 - // 运行在子线程中,勿直接操作UI - } - - @Override - public void onError(int error, String errorMsg) { - // 运行在子线程中,勿直接操作UI - } - }); - - **方法三:参数(会议类型,会议密码,是否录制,是否合流, 回调);** - - public void createAndJoinConference(final EMConferenceType type, final String password, - final boolean recordOnServer,final boolean mergeStream, - final EMValueCallBack callback) {}; - EMClient.getInstance().conferenceManager().createAndJoinConference(emConferenceType, - password, false, false, new EMValueCallBack() { - @Override - public void onSuccess(EMConference value) { - // 返回当前会议对象实例 value - // 可进行推流等相关操作 - // 运行在子线程中,勿直接操作UI - } - - @Override - public void onError(int error, String errorMsg) { - // 运行在子线程中,勿直接操作UI - } - }); - - **方法四:参数(会议类型,会议密码,房间信息对象,推流信息, 回调);** - - public void createAndJoinConference(final @NonNull EMConferenceType type, final String password, - final EMRoomConfig roomConfig, final EMStreamParam param, - final EMValueCallBack callback){}; - 有关EMRoomConfig定义如下: - /** - * 会议房间属性类 - * confrTyp 会议类型 - * isSupportVxmini 是否支持小程序 - * isRecord 是否支持录制 - * isMergeRecord 是否支持和流 - * nickName 用户昵称 - * ext 用户头像 - * maxTalkerCount 房间最多主播 - * maxVideoCount 房间最多视频流媒体 - * maxAudienceCount 房间最多观众 - * maxPubDesktopCount 房间最多共享桌面流 - */ - public class EMRoomConfig { - EMConferenceManager.EMConferenceType confrTyp = EMConferenceManager.EMConferenceType.SmallCommunication; - private boolean isSupportMiniProgram = false; - private boolean isRecord = false; - private boolean isMergeRecord = false; - private String nickName = null; - private String ext = null; - private int maxTalkerCount = -1; - private int maxVideoCount = -1; - private int maxAudienceCount = -1; - private int maxPubDesktopCount = -1; - private EMLiveConfig liveConfig = null; - - public EMRoomConfig(EMConferenceManager.EMConferenceType confrTyp, - boolean isSupportMiniProgram,boolean isRecord, - boolean isMergeRecord , String nickName, - String ext, int maxTalkerCount, - int maxVideoCount,int maxAudienceCount, - int maxPubDesktopCount) - {...}; - } -EMClient.getInstance().conferenceManager().joinConference(confId, - password,new EMValueCallBack() { - @Override - public void onSuccess(EMConference value) { - // 返回当前会议对象实例 value - // 可进行推流等相关操作 - // 运行在子线程中,勿直接操作UI - } - - @Override - public void onError(int error, String errorMsg) { - // 运行在子线程中,勿直接操作UI - } - }); -``` - -#### **邀请成员加入会议** - -SDK没有提供邀请接口,你可以自己实现,比如使用环信IM通过发消息邀请,比如通过发邮件邀请等等。
-至于需要发送哪些邀请信息,可以参照SDK中的join接口, -目前是需要Conference的confrId和password比如用环信IM发消息邀请,如下所示: - -``` -final EMMessage message = EMMessage.createTxtSendMessage("邀请你观看直播", to); -message.setAttribute(Constant.EM_CONFERENCE_ID, conference.getConferenceId()); -message.setAttribute(Constant.EM_CONFERENCE_PASSWORD, conference.getPassword()); -EMClient.getInstance().chatManager().sendMessage(message); -``` - -#### **管理员销毁会议** - -会议中的成员可以调用SDK中的 [EMConferenceManager#destoryConference](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8d95d4e839a2598d76be85ed69e06244)接口销毁会议,
-会议被销毁以后,会议中的其他成员会收到回调[EMConferenceListener#onPassiveLeave](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html)。 - -``` -EMClient.getInstance().conferenceManager().destoryConference() -``` -:::tip - 注意:只有管理员角色可以调用这个接口,可以在会议中显式调用这个接口,强制结束进行中的会议,会议中其他人在EMConferenceListener#onPassiveLeave回调里收到 error为 -411,message为 reason-conference-dismissed,收到这个以后调EMClient.getInstance().conferenceManager().exitConference() 主动退出会议。 -::: -``` -EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() { - @Override - public void onSuccess(Object value) { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(activity, "destroy conference succeed!", Toast.LENGTH_SHORT).show(); - } - }); - } - - @Override - public void onError(int error, String errorMsg) { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(activity, "destroy conference failed:"+errorMsg, Toast.LENGTH_SHORT).show(); - } - }); - } - }); -``` - -#### **设置会议人数限制** - -通过带EMRoomConfig参数的joinRoom接口加入会议的时候 可以设置:**房间最多视频主播数**、**房间最多视频数**、 **房间最多观众**、 **房间最多共享桌面流**等会议信息。
-默认设置限制:最多主播是100个,最大视频数是9个,房间最多观众是600个 ,最多共享桌面流2个,如下所示: - -``` -/** - * \~chinese - * 加入多人音视频加议房间 - * @param room 会议房间名 - * @param password 会议房间密码 - * @param roletype 当前用户加入时指定角色 (EMConferenceRole类型) - * @param param 设置会议参数 (EMRoomConfig类型) - * @param callback 回调函数 - */ - public void joinRoom(final String room ,final String password,final EMConferenceRole roletype ,final EMRoomConfig param, final EMValueCallBack callback) - - 有关EMRoomConfig定义如下: - /** - * 会议房间属性类 - * confrTyp 会议类型 - * isSupportVxmini 是否支持小程序 - * isRecord 是否支持录制 - * isMergeRecord 是否支持和流 - * nickName 用户昵称 - * ext 用户头像 - * maxTalkerCount 房间最多主播 - * maxVideoCount 房间最多视频流媒体 - * maxAudienceCount 房间最多观众 - * maxPubDesktopCount 房间最多共享桌面流 - */ - public class EMRoomConfig { - EMConferenceManager.EMConferenceType confrTyp = EMConferenceManager.EMConferenceType.SmallCommunication; - private boolean isSupportMiniProgram = false; - private boolean isRecord = false; - private boolean isMergeRecord = false; - private String nickName = null; - private String ext = null; - private int maxTalkerCount = -1; - private int maxVideoCount = -1; - private int maxAudienceCount = -1; - private int maxPubDesktopCount = -1; - private EMLiveConfig liveConfig = null; - - public EMRoomConfig(EMConferenceManager.EMConferenceType confrTyp, - boolean isSupportMiniProgram,boolean isRecord, - boolean isMergeRecord , String nickName, - String ext, int maxTalkerCount, - int maxVideoCount,int maxAudienceCount, - int maxPubDesktopCount) - {...}; - } -``` -:::tip -注意:设置会议人数限制只有是加入会议的第一个设置才有效,也就是会议的创建者。 -::: - -#### **获取会议信息** - -在会议进行中,可以通过getConferenceInfo 方法来查询会议信息,从而可以拿到主播列表、观众人数等信息。 - -``` -/** - * \~chinese - * 查询会议信息 - * - * @param confId 会议id - * @param password 会议密码 - * @param callback 获取结果 - */ - public void getConferenceInfo(final String confId, final String password, - final EMValueCallBack callback) - - - /** - * 获取主播列表 - */ - public String[] getTalkers() - /** - * 获取观众总数 - */ - public int getAudienceTotal() -``` - -#### **cdn合流推流** - -多人音视频支持将会议中的音视频流合并成一个流,推送到第三方的cdn直播服务器。
-整个合流推流过程包括开启cdn推流,更新推流布局,停止推流。 - -**开启cdn推流** - -会议的创建者在创建会议时使用EMRoomConfig的接口,可以决定是否开启cdn推流,推流配置EMLiveConfig是EMRoomConfig的一个参数,可设置cdn推流的相关信息,然后调用 **创建会议接口**,可以开启cdn推流(注意:只有会议创建者才能开启cdn推流,如果会议已经创建好,其他人再调用开启cdn推流无效)。 开启过程如下: - -``` -EMCDNCanvas canvas = new EMCDNCanvas(ConferenceInfo.CanvasWidth, ConferenceInfo.CanvasHeight, 0,30,900,"H264"); - String url = PreferenceManager.getInstance().getCDNUrl(); - EMLiveConfig liveConfig = new EMLiveConfig(url, canvas); - roomConfig.setLiveConfig(liveConfig); - EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, - new EMValueCallBack() -``` - -当EMCDNCanvas设置的width、height为0时,cdn推流为**纯音频推流** - -推流成功后,可以在EMConferenceManager中 getLiveCfgs() 方法可以获取到liveId,liveCfgs存储了所有的推流信息,liveCfgs为一个Map,key为liveId,value为对应的推流Url。 - -EMLiveConfig可设置的参数如下: - -``` -/** - * \~chinese - * CDN 画布设置,创建会议时使用 - * width (画布 宽) - * height(画布 高) - * bgclr (画布 背景色 ,格式为 RGB 定义下的 Hex 值,不要带 # 号, - * 如 0xFFB6C1 表示浅粉色。默认0x000000,黑色) - * fps (推流帧率,可设置范围10-30 ) - * kpbs (推流码率,单位kbps,width和height较大时,码率需要提高,可设置范围1-5000) - * codec (推流编码格式,目前只支持"H264") - * - * \~english - * The cdn canvas config - * width (Canvas width) - * height(Canvas height) - * bgclr (Canvas background color, Hex value defined by RGB, no #, - * such as 0xFFB6C1 means light pink.Default 0x000000, black)) - * fps (The fps of cdn live,valid valuei is 10-30) - * kpbs (The birateBps of cdn live,the unit is kbps,valid value is 1-5000 ) - * codec (The codec of cdn live,now only support H264) - */ -public class EMCDNCanvas { - private int width = -1; - private int height = -1; - private int bgclr = 0; - private int fps = -1; - private int kpbs = -1; - private String codec = null; - - public EMCDNCanvas(){ - - } - public EMCDNCanvas(int width, int height, int bgclr,int fps,int kpbs,String codec){ - this.width = width; - this.height = height; - this.bgclr = bgclr; - this.fps = fps; - this.kpbs = kpbs; - this.codec = codec; - } -} - -/** - \~chinese - * 音频录制的配置信息 - * bps 音频比特率,类型为 EMAudioBpsType枚举; - * channels 音频通道数,可选(1,2),类型为ChannelsType枚举; - * samples 音频采样率,类型为 EMAudioSamplesType枚举; - * - * - * \~english - * The config of audio record. - * bps audio bit rate, type is EMAudioBpsType enum; - * channels number of audio channels, optional (1,2), type is ChannelsType enum; - * samples audio sampling rate, type is EMAudioSamplesType enum; - * - */ - -public class EMAudioConfig { - EMAudioBpsType bps = EMAudioBpsType.BPS_64K; - ChannelsType channels = ChannelsType.DUAL; - EMAudioSamplesType samples = EMAudioSamplesType.SAMPLES_16K; - - public enum ChannelsType{ - SINGLE, //单声道 - DUAL //双声道 - } - - public EMAudioConfig(EMAudioBpsType bps, ChannelsType channels,EMAudioSamplesType samples){ - this.bps = bps; - this.channels = channels; - this.samples = samples; - } - } - -/** - * \~Chinese - * CDN推流设置 - * cdnurl cdn推流地址 - * cdnCanvas 画布设置 (cdnCanvas可以缺省) - * record 设置是否录制推往CDN的流 - * audioConfig 设置音频录制的配置信息 - * liveLayoutStyle 设置CDN推流使用的画布类型 - * - * \~English - * The CDN push stream config - * cdnurl cdn push stream address - * cdnCanvas canvas settings (cdnCanvas can be default) - * record whether to enable the recording push network CDN to remain - * audioConfig set the audio recording configuration information - * liveLayoutStyle sets the canvas type used by the CDN push stream - */ - -public class EMLiveConfig { - private String cdnurl; - private EMCDNCanvas cdnCanvas = null; - private boolean record = false; - private EMAudioConfig audioConfig = null; - - private EMLiveLayoutStyle liveLayoutStyle = EMLiveLayoutStyle.GRID; - - public EMLiveConfig(){ - - } - } -``` - -##### **获取cdn推流LiveId** - -推流成功后,可以在EMConferenceManager中 getLiveCfgs() 方法可以获取到liveId,liveCfgs存储了所有的推流信息,liveCfgs为一个Map,key为liveId,value为对应的推流Url。 - -``` -/** - * CDN推流liveID (key为推流liveID,value为推流URL) - * @return - */ - public Map getLiveCfgs(); -``` - -**更新布局** - -当用户调用更新布局接口后,cdn推流方式将强制变成CUSTOM模式,所有流的位置信息都由用户自己定义。 更新布局的接口如下: - -``` -/** - * \~chinese - * CDN 推流更新布局(只有管理员可操作) - * 用户角色: Admin > Talker > Audience - * 注意: 更新布局只允许Admin 去操作 - * - * @param liveId 推流CDN的liveId - * @param regions EMCanvasRegion布局对象列表 - * @param callback 结果回调 - * - * \~english - * CDN pushes to update the layout - * - * @param liveId Push the liveId of CDN - * @param regions Layout EMCanvasRegion list - * @param callback Result callback - */ - public void updateLiveLayout(String liveId ,List regions , final EMValueCallBack callback){} -``` - -EMLiveRegion的结构如下: - -``` -/** - * \~Chinese - * 视频流在画布宽高及显示位置等参数 - * x 在画布横坐标位置 - * y 在画布纵坐标位置 - * width 视频流宽度(64~1280) - * height 视频流高度(64~1280) - * zorder 视频流zorder层位置(最小值为 0(默认值),表示该区域图像位于最下层 - * 最大值为 100,表示该区域图像位于最上层) - * style 视频流显示方式(fit模式或者fill模式) - * streamId 视频流ID - * - * - * \~English - * Video streaming in the canvas width and height and display location and other parameters - * x On the horizontal position of the canvas - * y On the vertical position of the canvas - * width Video stream width - * height Video stream height - * zorder Video stream zorder layer location - * style Video stream display mode (fit mode or fill mode) - * streamId The video stream ID - */ -public class EMLiveRegion { - private int x; - private int y; - private int width; - private int height; - private int zorder; - private EMRegionStyle style; - private String streamId; - - public EMLiveRegion(){} - public EMLiveRegion(int x,int y, int width, int height, int zorder, EMRegionStyle style, String streamId){ - this.x = x; - this.y = y; - this.width = width; - this.height = height; - this.zorder = zorder; - this.style = style; - this.streamId = streamId; - } - public enum EMRegionStyle { - FIT, // fit模式 - FILL // fill模式 - } -} -``` - -使用方法如下: - -``` -List regionsList = new LinkedList<>(); -EMLiveRegion region = new EMLiveRegion(); -region.setStreamId(streamInfo.getStreamId()); -region.setStyle(EMLiveRegion.EMRegionStyle.FILL); -region.setX(80); -region.setY(60); -region.setWidth(320); -region.setHeight(640); -region.setZorder(1); -regionsList.add(region); -Map livecfgs = EMClient.getInstance().conferenceManager().getLiveCfgs(); -String liveId = null; -Iterator iter = livecfgs.keySet().iterator(); -while(iter.hasNext()) { - liveId = iter.next(); - break; -} -EMClient.getInstance().conferenceManager().updateLiveLayout(liveId,regionsList,new EMValueCallBack(); -``` - -**多路推流** - -多人音视频支持加入会议后,增加一路推流,只有管理员权限可进行次操作。增加一路推流的api方法如下: - -``` -/** - * \~chinese - * 增加CDN多路推流 - * @param liveConfig CDN推流布局配置 - * @param callback 结果回调 - * - * \~english - * Add CDN multiplex push stream - * @param liveConfig CDN push stream layout configuration - * @param callback Result callback - */ - public void addLiveStream(EMLiveConfig liveConfig , final EMValueCallBack callback){} -``` - -**自定义录制布局** - -在推流的EMLiveConfig设置里,设record为true,可以开启自定义录制,开启后会把推流到cdn的音视频按照推流布局录制下来。如果推流时未开启,也可以在推流后进行开启/停止自定义录制布局操作。开启/停止自定义录制布局的api如下: - -``` -/** - * \~chinese - * 开启或停止录制CDN的流 - * @param liveId CDN推流 liveID - * @param enable 是否开启录制,true为开启 false为停止 - * @param callback 结果回调 - * - * \~english - * Start or stop recording CDN streams - * @param liveId CDN liveID push stream - * @param enable Whether recording is on or off, true means false or stop - * @param callback Result callback - * - */ - public void enableRecordLivestream(String liveId, boolean enable, final EMValueCallBack callback){} -``` - -**停止推流** - -多人音视频支持停止向某一个地址的推流,停止推流接口如下: - -``` -/** - * \~chinese - * 停止CDN推流 - * @param liveId 推流CDN的liveId - * @param callback 结果回调 - * - * \~english - *@param liveId Push the liveId of CDN - *@param callback Result callback - * Stop the CDN push - * - * @param callback Result callback - */ - public void stopLiveStream(String liveId, final EMValueCallBack callback) -``` - -#### **云端录制** - -通过带EMRoomConfig参数的joinRoom接口加入会议的时候,可以通过 -isRecord(是否支持录制)和isMergeRecord(是否支持和流)这两个参数设置是否开始云端录制和合流,如下所示: - -``` -/** - * \~chinese - * 加入多人音视频加议房间 - * @param room 会议房间名 - * @param password 会议房间密码 - * @param roletype 当前用户加入时指定角色 (EMConferenceRole类型) - * @param param 设置会议参数 (EMRoomConfig类型) - * @param callback 回调函数 - */ - public void joinRoom(final String room ,final String password,final EMConferenceRole roletype , - final EMRoomConfig param, final EMValueCallBack callback) - - 有关EMRoomConfig定义如下: - /** - * 会议房间属性类 - * confrTyp 会议类型 - * isSupportVxmini 是否支持小程序 - * isRecord 是否支持录制 - * isMergeRecord 是否支持和流 - * nickName 用户昵称 - * ext 用户头像 - * maxTalkerCount 房间最多主播 - * maxVideoCount 房间最多视频流媒体 - * maxAudienceCount 房间最多观众 - * maxPubDesktopCount 房间最多共享桌面流 - */ - public class EMRoomConfig { - EMConferenceManager.EMConferenceType confrTyp = EMConferenceManager.EMConferenceType.SmallCommunication; - private boolean isSupportMiniProgram = false; - private boolean isRecord = false; - private boolean isMergeRecord = false; - private String nickName = null; - private String ext = null; - private int maxTalkerCount = -1; - private int maxVideoCount = -1; - private int maxAudienceCount = -1; - private int maxPubDesktopCount = -1; - private EMLiveConfig liveConfig = null; - - public EMRoomConfig(EMConferenceManager.EMConferenceType confrTyp, - boolean isSupportMiniProgram,boolean isRecord, - boolean isMergeRecord , String nickName, - String ext, int maxTalkerCount, - int maxVideoCount,int maxAudienceCount, - int maxPubDesktopCount) - {...}; - } -``` -:::tip -注意:设置会议人数限制只有是加入会议的第一个设置才有效,也就是会议的创建者。 -::: - -#### **设置昵称 头像** - -通过带EMRoomConfig参数的joinRoom接口加入会议的时候,可以通过nickName(昵称)和ext(可设置扩展字段比如 用户头像等)这两个参数设置昵称和头像等扩展字段,如下所示: - -``` -/** - * \~chinese - * 加入多人音视频加议房间 - * @param room 会议房间名 - * @param password 会议房间密码 - * @param roletype 当前用户加入时指定角色 (EMConferenceRole类型) - * @param param 设置会议参数 (EMRoomConfig类型) - * @param callback 回调函数 - */ - public void joinRoom(final String room ,final String password,final EMConferenceRole roletype , - final EMRoomConfig param, final EMValueCallBack callback) - - 有关EMRoomConfig定义如下: - /** - * 会议房间属性类 - * confrTyp 会议类型 - * isSupportVxmini 是否支持小程序 - * isRecord 是否支持录制 - * isMergeRecord 是否支持和流 - * nickName 用户昵称 - * ext 用户头像 - * maxTalkerCount 房间最多主播 - * maxVideoCount 房间最多视频流媒体 - * maxAudienceCount 房间最多观众 - * maxPubDesktopCount 房间最多共享桌面流 - */ - public class EMRoomConfig { - EMConferenceManager.EMConferenceType confrTyp = EMConferenceManager.EMConferenceType.SmallCommunication; - private boolean isSupportMiniProgram = false; - private boolean isRecord = false; - private boolean isMergeRecord = false; - private String nickName = null; - private String ext = null; - private int maxTalkerCount = -1; - private int maxVideoCount = -1; - private int maxAudienceCount = -1; - private int maxPubDesktopCount = -1; - private EMLiveConfig liveConfig = null; - - public EMRoomConfig(EMConferenceManager.EMConferenceType confrTyp, - boolean isSupportMiniProgram,boolean isRecord, - boolean isMergeRecord , String nickName, - String ext, int maxTalkerCount, - int maxVideoCount,int maxAudienceCount, - int maxPubDesktopCount) - {...}; - } -``` - -#### **会议属性** - -会议属性是会议的状态信息,由一组(key,value)组成, 会议中的所有角色成员(管理员、主播、观众)都可以 **设置/删除会议频道属性** **设置的会议属性会通知给会议中的所有人** ,设置会议属性的api方法如下: - -``` -/** - * \~chinese - * 设置频道属性,该会议中的所有人(包括自己)都会收到{@link EMConferenceListener#onAttributesUpdated}回调. - * 该方法需要在加入会议后调用. - * - * @param key - * @param value - * @param callback - * - * \~english - * Set conference attribute,All members in this conference(include myself) will receive a callback - * in {@link EMConferenceListener#onAttributesUpdated}. - * this method can only be used after join a conference. - * - * @param key - * @param value - * @param callback - */ - public void setConferenceAttribute(@NonNull String key, @NonNull String value, final EMValueCallBack callback) {} -``` - -删除会议属性的api方法如下: - -``` -/** - * \~chinese - * 删除频道属性,该会议中的所有人(包括自己)都会收到{@link EMConferenceListener#onAttributesUpdated}回调. - * 该方法需要在加入会议后调用. - * - * @param key - * @param callback - * - * \~english - * Delete conference attribute,All members in this conference(include myself) will receive a callback - * in {@link EMConferenceListener#onAttributesUpdated}. - * this method can only be used after join a conference. - * - * @param key - * @param callback - */ - public void deleteConferenceAttribute(@NonNull String key, final EMValueCallBack callback) {} -``` - -当会议属性信息改变时,会议中的在EMConferenceListener中的 onAttributesUpdated 回调方法收到通知,如下: - -``` -public void onAttributesUpdated(EMConferenceAttribute[] attributes) {} -``` - -每一个EMConferenceAttribute包括了会议属性中的key,value,以及本次修改的action,action包括ADD、UPDATE、DELETE。 - - - -#### **私有部署** - -私有部署设置方法参见[私有云 Android SDK集成配置](../im/uc_android_private.md)。 - -### 音视频管理 - -#### **设置视频流参数** - -如果用户想对发布的音频或者视频流的参数进行调整,可以进行一些设置:
-用EMStreamParam中的参数进行设置,只发布音频流,可以设置关闭视频;
-设置视频流的分辨率 最小码率 最大码率 最大音频码率等,如下所示: - -``` -//设置分辨率 - normalParam.setVideoOff(true); - normalParam.setVideoHeight(720); - normalParam.setVideoWidth(1280); - -//设置最大 最小码率 - normalParam.setMinVideoKbps(200); - normalParam.setMaxVideoKbps(300); - normalParam.setMaxAudioKbps(300); -``` - -**设置流畅度或者清晰度优先** - -可以通过以下方法设置视频流畅度优先还是清晰度优先(true 为清晰度优先,false为流畅度优先)。 - -``` -EMClient.getInstance().callManager().getCallOptions().setClarityFirst(true); -``` - -#### **停止发布流** - -成员A可以调用unpublish接口取消自己已经发布的数据流,操作成功后,会议中的其他成员会收到回调
`EMConferenceListener#onStreamRemoved(EMConferenceStream stream)`,将对应的数据流信息移除。 - -``` -@Override -public void onStreamRemoved(final EMConferenceStream stream) { - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(activity, stream.getUsername() + " stream removed!", Toast.LENGTH_SHORT).show(); - if (streamList.contains(stream)) { - removeConferenceView(stream); - } - } - }); -} -``` - -#### **停止订阅流** - -成员B如果不想再看成员A的音视频,可以调用SDK接口unsubscribe。 - -``` -EMClient.getInstance().conferenceManager().unsubscribe(emConferenceStream, new EMValueCallBack() { - @Override - public void onSuccess(String value) { - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### **通话中音视频控制** - -会议过程中可以做一些音视频进行控制,比如**开启关闭音频**、**视频**、**切换前后摄像头**, -具体API如下所示: - -``` -// 开启音频传输 - EMClient.getInstance().conferenceManager().openVoiceTransfer(); - // 关闭音频传输 - EMClient.getInstance().conferenceManager().closeVoiceTransfer(); - // 开启视频传输 - EMClient.getInstance().conferenceManager().openVideoTransfer(); - // 关闭视频传输 - EMClient.getInstance().conferenceManager().closeVideoTransfer(); -``` -:::tip -以上这四个方法都是修改 stream,群里其他成员都会收到 EMConferenceListener.onStreamUpdate()回调。 -::: -``` -// 切换摄像头 - EMClient.getInstance().conferenceManager().switchCamera(); - // 设置展示本地画面的 view - EMClient.getInstance().conferenceManager().setLocalSurfaceView(localView); - // 更新展示本地画面 view - EMClient.getInstance().conferenceManager().updateLocalSurfaceView(localView); - // 更新展示远端画面的 view - EMClient.getInstance().conferenceManager().updateRemoteSurfaceView(streamId, remoteView); -``` - -#### **音视频首帧回调** - -当成员发布流成功,发送第一帧音视频数据时,会触发EMConferenceListener的以下回调函数。 - -``` -/** - * \~chinese - * Pub 首帧回调 - * streamId 流ID - * frameType the first frame callback type of the stream - * - * \~english - * Pub first frame callback - * streamId streamId - * frameType the first frame callback type of the stream - */ - public void onFirstFrameSent(String stremId,StreamFrameType frameType){} -``` - -当成员订阅流成功,收到第一帧音视频数据时,会触发EMConferenceListener的以下回调函数。 - -``` -/** - * \~chinese - * Sub 首帧回调 - * streamId 流ID - * frameType the first frame callback type of the stream - * - * \~english - * Sub first frame callback - * streamId streamId - * state the first frame callback type of the stream - * - */ - public void onFirstFrameRecived(String streamId,StreamFrameType frameType){} -``` - -#### **音视频无数据回调** - -当会议中的成员A因断网或异常退出,而无音视频数据上传时,订阅该流的其他成员会收到EMConferenceListener 中的以下回调通知。 - -``` -/** - * \~chinese - * 订阅流的数据状态回调 - * @param streamId 订阅的流ID - * @param state 流的视频或音频数据状态 - * - * \~english - * A data state callback for a subscription stream - * @param streamId StreamId - * @param state Stream video or audio data status - */ - default void onStreamStateUpdated(String streamId,StreamState state){}; -``` - -该功能需要会议中开启质量统计 - -``` -/** - * \~chinese - * 启用统计 - * - * @param enable 是否启用统计 - * - * \~english - * enable statistics - * @params enable enable statistics - */ - public void enableStatistics(boolean enable) {}; -``` - -#### **弱网监控** - -在会议中可以实时获取到自己的网络状态,通过EMConferenceListener中的以下回调通知。 - -``` -@Override - public void onConferenceState(final ConferenceState state) { - runOnUiThread(new Runnable() { - @Override - public void run() { - } - }); - } - //有以下状态 - STATE_NORMAL, // 正常状态 - STATE_DISCONNECTION, // 连接断开 - STATE_RECONNECTION, // 重新连接 - STATE_POOR_QUALITY, // 通话质量差 -``` - -#### **通话质量** - -通话过程中可以实时获取到自己或者订阅流的通话信息,比如:**视频宽高**、**丢包率**、**帧率**等等。
-具体信息可参考 [EMStreamStatistics](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_statistics.html) 该功能需要会议中开启质量统计,如下面的接口: - -``` -/** - * \~chinese - * 启用统计 - * - * @param enable 是否启用统计 - * - * \~english - * enable statistics - * @params enable enable statistics - */ - public void enableStatistics(boolean enable) {}; -``` - -开启质量统计后,在视频过程中会实时触发EMConferenceListener 中的回调函数 onStreamStatistics。
-如下所示,从而可以获取到每路流的质量统计信息: - -``` -@Override - public void onStreamStatistics(EMStreamStatistics statistics) { - EMLog.e(TAG, "Encode Resolution: " + statistics.getLocalEncodedWidth() + " " - + statistics.getLocalEncodedHeight() + " bps: " +statistics.getLocalVideoActualBps() + - " FPS: " + statistics.getLocalEncodedFps()); - } -``` - -#### **监听谁在说话** - -多人音视频会议可以实时监听谁在说话,该功能需要开启,启动/停止控制如下: - -``` -//开始监听说话者,参数为间隔时间 - EMClient.getInstance().conferenceManager().startMonitorSpeaker(int interval); - - //停止监听说话者 -EMClient.getInstance().conferenceManager().stopMonitorSpeaker(); -``` - -有人说话时,会议成员会收到如下回调通知。 - -``` -@Override -public void onSpeakers(final List speakers)(){ } -``` - -#### **mute远端音视频流** - -在视频会议过程中可以 mute订阅的流的音频或者视频,方法如下所示: - -``` -/** - * \~chinese - * mute远端音频 - * - * \~english - * Mute remote audio - * - * @param mute - */ - public void muteRemoteAudio(String streamId, boolean mute) { - mediaManager.muteRemoteAudio(streamId, mute); - } - - /** - * ~\chinese - * mute远端视频 - * - * \~english - * Mute remote video - * - * @param mute - */ - public void muteRemoteVideo(String streamId, boolean mute) { - mediaManager.muteRemoteVideo(streamId, mute); - } -``` - -#### **变声/自定义音频** - -**开启外边音频输入** - -用户使用自定义音频数据时,需要配置外部输入音频数据的开关以及音频采样率,通道数(当前通道数只支持1),开启方式如下(true 为开启,false为不开启)。 - -``` -EMClient.getInstance().callManager().getCallOptions().setExternalAudioParam(true, 44100,1); -``` - -**输入音频数据** - -音频数据采集可参考Demo中的ExternalAudioInputRecord.java类实现, -音频数据的输入必须在会话接通后开始,否则会导致网络阻塞,影响通话质量。 -建议用户将音频数据采集的开始放在**会话接通的回调里**及**callDidAccept回调中**。 - -``` -EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack() { - @Override - public void onSuccess(String value) { - - //如果启动外部音频输入 ,启动音频录制 - if(PreferenceManager.getInstance().isExternalAudioInputResolution()){ - ExternalAudioInputRecord.getInstance().startRecording(); - } - .... - } -``` - -音频采集过程参考Demo中的ExternalAudioInputRecord类实现, -音频采集过程开始后,在音频数据采集线程里调用外部输入音频数据接口,具体参考Demo中的实现。 - -``` -EMClient.getInstance().conferenceManager().inputExternalAudioData(byteBuffer.array(), byteBuffer.capacity()); -``` - -**停止音频输入** - -会话挂断时,停止音频采集及输入过程: - -``` -if(PreferenceManager.getInstance().isExternalAudioInputResolution()){ - ExternalAudioInputRecord.getInstance().stopRecording(); - } -``` - -#### **美颜/自定义视频** - -如果用户需要自己采集特定的数据或者对于数据需要先进行一些处理,可以使用SDK的外部输入数据的方法进行。
- -例如想要使用美颜等功能,需要用户使用系统的摄像头, -然后启动监听系统设备,获取到数据后进行处理,处理后再调用我们输入数据的api发布出去。
- -使用自定义视频接口如下:开启外边视频输入, -用户使用自定义视频数据时,需要配置外部输入数据数据的开关(true 为开启,false为不开启)。 - -``` -EMStreamParam normalParam = new EMStreamParam(); -normalParam.setUsingExternalSource(true); //设置使用外部视频数据输入 -EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack() {} -``` - -**输入视频数据** - -当需要自己获取视频数据,进行美颜等处理时,循环调用以下方法输入数据。
-这个调用频率就相当于你的帧率,调用间隔可以自己进行控制,一般最大30帧/秒), -输入视频数据的方法如下: - -``` -/** - * - * 视频数据的格式是摄像头采集的格式即:NV21 420sp 自己手动传入时需要将自己处理的数据转为 yuv 格式输入 - */ - EMClient.getInstance().conferenceManager().inputExternalVideoData(data, width, height, rotate); -``` - -#### **视频水印** - -在Android系统可以将图片资源设置为视频流的水印。首先将图片资源转换为Bitmap对象, -然后设置WaterMarkOption中的属性,比如**位置**,**分辨率**及**距离边缘的margin**等。 - -``` -try { - InputStream in = this.getResources().getAssets().open("watermark.png"); - watermarkbitmap = BitmapFactory.decodeStream(in); -} catch (Exception e) { - e.printStackTrace(); -} -watermark = new WaterMarkOption(watermarkbitmap, 75, 25, WaterMarkPosition.TOP_RIGHT, 8, 8); -//设置水印 -EMClient.getInstance().conferenceManager().setWaterMark(watermark); -``` - -#### **共享桌面** - -在android 5.0以上系统中,可以使用外部输入视频数据的方法,将采集的桌面图像数据发布出去。 主要方法如下: - -``` -desktopParam = new EMStreamParam(); -desktopParam.setAudioOff(true); -desktopParam.setVideoOff(true); -desktopParam.setStreamType(EMConferenceStream.StreamType.DESKTOP); - -public void publishDesktop() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - desktopParam.setShareView(null); - } else { - desktopParam.setShareView(activity.getWindow().getDecorView()); - } - EMClient.getInstance().conferenceManager().publish(desktopParam, new EMValueCallBack() { - @Override - public void onSuccess(String value) { - conference.setPubStreamId(value, EMConferenceStream.StreamType.DESKTOP); - startScreenCapture(); - } - - @Override - public void onError(int error, String errorMsg) { - - } - }); - } - - - private void startScreenCapture() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - if (ScreenCaptureManager.getInstance().state == ScreenCaptureManager.State.IDLE) { - ScreenCaptureManager.getInstance().init(activity); - ScreenCaptureManager.getInstance().setScreenCaptureCallback(new ScreenCaptureManager.ScreenCaptureCallback() { - @Override - public void onBitmap(Bitmap bitmap) { - EMClient.getInstance().conferenceManager().inputExternalVideoData(bitmap); - } - }); - } - } - } - -``` - -具体实现可以参考videocall-android中的ConferenceActivity.java文件 - -### 角色管理 - -#### **角色管理** - -**申请主播** - -会议中的观众角色可以向管理员发申请成为主播,管理员可以选择同意或者拒绝。
-观众申请管理员的接口需要管理员的memId,先通过获取会议属性接口获取到管理员的memName,然后根据memName以及成员加入的回调中获取到的EMConferenceMember,获取到memId接口如下: - -``` -/** - * \~chinese - * 发送上麦请求 - * - * @param memberId 管理员的memberId(只有管理员可处理上麦请求); - * - * \~english - * Request to be speaker - * - * @param memberId of the admin (only the admin can process the request on the mic); - */ - public void applyTobeSpeaker(String memberId); -``` - -观众发出申请后,管理员将会收到以下回调: - -``` -/** - * \~chinese - * 请求上麦通知 (只有管理员能收到) - * - * \~english - * Request On wheat notification - */ - default void onReqSpeaker(String memId,String memName,String nickName); -``` - -在回调中,管理员可以选择同意或者拒绝;
-- 同意:先调用改变用户权限的接口,然后调用回复接口; -- 拒绝:则直接调用回复接口; - -修改用户的权限接口如下: - -``` -/** - * \~chinese - * 用户角色: Admin > Talker > Audience - * 当角色升级时,用户需要给管理员发送申请,管理通过该接口改变用户接口. - * 当角色降级时,用户直接调用该接口即可. - * 注意: 暂时不支持Admin降级自己 - * - * @param confId 会议id - * @param member {@link EMConferenceMember},目前使用memberName进行的操作 - * @param toRole 目标角色,{@link EMConferenceRole} - * @param callback 结果回调 - * - * \~english - * Role: Admin > Talker > Audience - * When role upgrade, you need to send a request to Admin, only Admin can upgrade a role. - * When role degrade, you can degrade with this method yourself. - * Attention: Admin can not degrade self. - * - * @param confId Conference id - * @param member {@link EMConferenceMember} - * @param toRole Target role,{@link EMConferenceRole} - * @param callback Result callback - */ - public void grantRole(final String confId, final EMConferenceMember member, final EMConferenceRole toRole, - final EMValueCallBack callback); -``` - -回复接口如下: - -``` -/** - * \~chinese - * 管理员处理 上麦请求 - * 注意:只允许Admin 去操作 - * - * @param memberId 请求者 memberId; - * @param accept true 代表同意 false 代表不同意 - * - * \~english - * Admin handle to be speak requests - * - * @param memberId requestor memberId; - * @param accept true means agree , false means disagree - * */ - public void handleSpeakerApplication(String memberId, boolean accept); -``` - -**申请管理员** - -会议中的主播角色可以向管理员发申请成为管理员,管理员可以选择同意或者拒绝。
-成为管理员后,各管理员之间的权限是相同的,主播申请管理员的接口需要管理员的memId,先通过获取会议属性接口获取到管理员的memName, -然后根据memName以及成员加入的回调中获取到的EMConferenceMember,获取到管理员memId。接口如下: - -``` -/** - * \~chinese - * 发送申请管理员请求 - * - * @param memberId 管理员的memberId; - * - * \~english - * Request to be admin - * - * @param memberId of the admin; - */ - public void applyTobeAdmin(String memberId); -``` - -主播发出申请后,管理员将会收到以下回调: - -``` -/** - * \~chinese - * 请求成为管理员通知(只有管理员能收到) - * - * \~english - * Request administrator notification - */ - default void onReqAdmin(String memId,String memName,String nickName){} -``` - -在回调中,管理员可以选择同意或者拒绝;
-- 同意:先调用改变用户权限的接口,然后调用回复接口; -- 拒绝:则直接调用回复接口。 - -修改用户的权限接口如下: - -``` -/** - * \~chinese - * 用户角色: Admin > Talker > Audience - * 当角色升级时,用户需要给管理员发送申请,管理通过该接口改变用户接口. - * 当角色降级时,用户直接调用该接口即可. - * 注意: 暂时不支持Admin降级自己 - * - * @param confId 会议id - * @param member {@link EMConferenceMember},目前使用memberName进行的操作 - * @param toRole 目标角色,{@link EMConferenceRole} - * @param callback 结果回调 - * - * \~english - * Role: Admin > Talker > Audience - * When role upgrade, you need to send a request to Admin, only Admin can upgrade a role. - * When role degrade, you can degrade with this method yourself. - * Attention: Admin can not degrade self. - * - * @param confId Conference id - * @param member {@link EMConferenceMember} - * @param toRole Target role,{@link EMConferenceRole} - * @param callback Result callback - */ - public void grantRole(final String confId, final EMConferenceMember member, final EMConferenceRole toRole, - final EMValueCallBack callback); -``` - -回复接口如下: - -``` -/** - * \~chinese - * 管理员处理 申请管理员请求 - * 注意: 只允许Admin 去操作 - * - * @param memberId 请求者 memberId; - * @param accept true 代表同意 false 代表不同意 - * - * \~english - * Admin handle to be admin requests - * - * @param memberId requestor memberId; - * @param accept true means agree false means disagree - * */ - public void handleAdminApplication(String memberId, boolean accept); -``` - -#### **管理员踢人** - -管理员可以调用kickMember api强制将成员从会议中移除。 - -:::tip -只有管理员角色可以调用踢人接口,可以在会议中踢走主播,被踢的主播在EMConferenceListener#onPassiveLeave回调里 -收到 error为 -412,message为 reason-beenkicked 。
收到这个以后调用 EMClient.getInstance().conferenceManager(). -exitConference()主动退出会议。 -::: -``` -/** - * \~chinese - * 踢走会议中存在的主播 - * 用户角色: Admin > Talker > Audience - * 注意: 踢人只允许Admin 去操作,Admin 不能踢自己 - * - * @param confId 会议id - * @param members 移除的主播列表 - * @param callback 结果回调 - * - * \~english - * Remove talkers from the Conference - * - * @param confId Conference id - * @param members Removed list of talkers - * @param callback Result callback - */ - public void kickMember(final String confId, final List members, final EMValueCallBack callback) -``` - -调用踢人接口,会议中被踢的主播收到回调 - -``` -EMConferenceListener#onPassiveLeave(final int error, final String message) -``` - -#### **全体静音/管理员指定成员静音** - -管理员可以对会议中的指定成员进行静音/解除静音设置,被指定成员可以是主播也可以是管理员。 -设置后,被指定成员将静音/解除静音。只有管理员可以调用此接口。 -接口API如下: - -``` -/** - * \~chinese - * 发送静音命令 - * 注意: 只允许Admin 去操作 - * - * @param memberId memberId 被静音的成员的memberId; - * - * \~english - * Send the mute command - * - * @param memberId MemberId of the member being mute (only admin can sends mute command); - * - * */ - public void muteMember(String memberId); -/** - * \~chinese - * 发送解除静音命令 - * 注意: 只允许Admin 去操作 - * - * @param memberId 被取消静音的成员的memberId; - * - * \~english - * Send the unmute command - * - * @param memberId Send the memberId of the member whose unmute command is cancelled; - * - * - * */ - public void unmuteMember(String memberId); -``` - -管理员调用此接口后,被指定的成员将收到静音状态的回调,回调函数如下 - -``` -/** - * \~chinese - * 被静音通知 - * - * \~english - * Be muted notification - */ - default void onMute(String adminId, String memId){}; -/** - * \~chinese - * 被取消静音通知 - * - * \~english - * Be unmuted notification - */ - default void onUnMute(String adminId, String memId){}; -``` - -#### **本身角色变更回调** - -在会议中如果 申请主播或者管理员成功等角色改变,则触发EMConferenceListener中以下角色变更回调, -回调中参数为自己目前的角色 - -``` -@Override - public void onRoleChanged(EMConferenceManager.EMConferenceRole role) { - EMLog.i(TAG, "onRoleChanged, role: " + role); - } -``` - -#### **管理员变更回调** - -在会议中如果其他人新增管理员或者移除管理员,则会触发EMConferenceListener中以下回调函数 - -``` -/** - * 管理员增加回调 - * - * @param streamId - */ - @Override - public void onAdminAdded(String streamId){ - ... - } - - /** - * 管理员移除回调 - * - * @param streamId - */ - @Override - public void onAdminRemoved(String streamId) { - ... - } -``` - -## 客户端API - -多人视频会议的API包括以下接口 - -- EMConferenceManager 会议管理单例类 -- EMConference 会议实体类 -- EMConferenceListener 会议监听类 -- EMConferenceMember 会议人员实体类 -- EMConferenceStream 会议流实体类 -- EMStreamParam 会议流参数类 -- EMStreamStatistics 音视频通话统计信息实体类 -- EMConferenceAttribute 会议属性实体类 -- EMRoomConfig 会议房间属性类 -- EMLiveConfig CDN推流设置类 -- EMAudioConfig 音频录制的配置信息 -- EMCDNCanvas CDN画布设置类 -- EMLiveRegion 视频流在画布宽高及显示位置等参数类 - -### EMConferenceManager - -| 方法 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------- | -| [joinRoom](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8940f54febf2086ccd978d75980c7763) | 加入会议房间 | -| [createAndJoinConference](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a420a13e4bc932f7ee98502ee40168d50) | 创建并加入会议 | -| isCreator | 是否为会议创建者 | -| [addConferenceListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a62bb92e3ae75f9c55a5da4b63471c34b) | 增加会议监听 | -| [removeConferenceListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a254acf2c8ea56054157baa4bfacb811d) | 移除会议监听 | -| [startAudioMixing](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a339fc678b9a22b05e6cd441a6f2c1128) | 开启本地伴音功能 | -| [stopAudioMixing](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8940f54febf2086ccd978d75980c7763:~:text=int%20com.hyphenate.chat.EMConferenceManager.stopAudioMixing) | 停止本地伴音功能 | -| [adjustAudioMixingVolume](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a0546239a8e45778d59deeb5796770505) | 设置伴奏音量 | -| [getConferenceInfo](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a4b76f361f9f94a9aa6a38c1af4dd0a05) | 获取会议信息 | -| [joinConference](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa04a85ab5f36f3f4ac14dc23ac18afb8) | 加入会议房间 | -| [updateLiveLayout](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a08f1d1f058cb40a6bf745dfa4e0ab1e1) | 更新CDN推流布局 | -| [stopLiveStream](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a6f154980142e31629ca5786d756f38fa) | 停止CDN推流 | -| [addLiveStream](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a1682b222486d14ffd77da06a6c111c88) | 增加CDN旁路推流 | -| [enableRecordLivestream](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#abf0e222c3ec094c9dea7ec9c7b89a1a1) | 开启或停止录制CDN的流 | -| [joinConferenceWithTicket](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aab4ae14065e192f9a1f284443c911149) | 通过Ticket加入会议 | -| [inviteUserToJoinConference](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a46185b19b85ee8366c0f22ef36a3e05e) | 邀请其他人加入会议 | -| [grantRole](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a52a1e73bc4b588bc57227c7a57512409) | 改变会议角色 | -| [kickMember](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#af8762ac9fa0fd293f05b4bcf1efbef10) | 会议中踢人 | -| [muteAll](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a6f7709002fb62d3279f101e4032954bf) | 设置全体静音 | -| [setConferenceAttribute](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | 设置会议属性 | -| [deleteConferenceAttribute](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a5527cfbd5bcb9851eb01bdb8ffd97eaa) | 删除会议属性 | -| [destroyConference](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8d95d4e839a2598d76be85ed69e06244) | 销毁会议 | -| [exitConference](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a1b52063a838ac0a89b0c5bd2ef0187ad) | 退出会议 | -| [publish](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa087a548e2d8f79ce06f50927decc137) | 开始推流 | -| [unpublish](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a926c631717ce04a6c2a31401c8e095f7) | 停止推流 | -| [subscribe](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a405c38df38cbb0e6bf11420ff80540e0) | 订阅流 | -| [updateSubscribe](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a084981244bf4840d717a7d49ba472bcb) | 更新订阅流 | -| [unsubscribe](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a87f0977b0e7aa91fe5c1b5a6855d311b) | 取消订阅流 | -| setWaterMark | 设置水印 | -| clearWaterMark | 取消水印 | -| [inputExternalAudioData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#ace04306620a500e1892d6759af9c34f5) | 外部属于音频 | -| [inputExternalVideoData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a606c489f65d2ca02ca8269604b9b5ef4) | 外部视频输入 | -| [startMonitorSpeaker](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#ade491f1314d5275d8880d0466aa044ed) | 开启正在说话监听器 | -| [stopMonitorSpeaker](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#ac1bd1ff347f4ddcf55395c855bdafc60) | 停止正在说话监听器 | -| [setLocalSurfaceView](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a9594aa797296a3e7327fadd699f2ac53) | 设置本地视频视图 | -| [updateLocalSurfaceView](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a63bd88ed797f3eeb650ac592dc1464b2) | 更新本地视频视图 | -| [updateRemoteSurfaceView](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a4e1350c5b350054474ba85c8d29d67d5) | 更新远端视图 | -| [switchCamera](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a0be64c2071bb8275a64fe877f31b8648) | 切换前后置摄像头 | -| [closeVideoTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#afce9a2bea4d0ee1397d696da5940d9dd) | 停止视频传输 | -| [openVideoTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a807cea2439323c341c5111e30e6aac8b) | 恢复视频传输 | -| [closeVoiceTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a7b4bd022d9daf8fe127d89494897bf99) | 停止音频传输 | -| [openVoiceTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#ab140d5e3185760c5dcefabf367385df6) | 恢复音频传输 | -| [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa55d14555c59930263659b1f608e8f18) | mute远端音频 | -| [enableStatistics](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8332e86b981056d930dde2965c047274) | 开始会议质量统计 | -| [getConferenceMemberList](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#ae9183eaa2c0d105d426ddf917aff0fd4) | 获取当前会议成员 | -| [getAvailableStreamMap](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a4f0bad698a8c6e0b62d781b8225129a3) | 获取当前会议可订阅Stream | -| [getSubscribedStreamMap](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a8332e86b981056d930dde2965c047274) | 获取当前会议已订阅 Stream | -| [setLocalVideoViewMirror](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#acc62694d0c18068081209f6d987b0db6) | 设置本地视频view镜像 | -| [setRotation](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#ad29c3544ec98b0ac4596d7d9abe35df9) | 设置视频会议中Camera采集到的VideoFrame的rotation | -| [applyTobeSpeaker](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a59d53f3c392714f201486d788f38cf07) | 发送上麦请求 | -| [handleSpeakerApplication](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#affaa83f9c32e5a99caa7ec0627ddfcb2) | 管理员处理上麦请求 | -| [applyTobeAdmin](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a5240c7d53051f0d14b27f0a59a2fc945) | 发送申请管理员请求 | -| [handleAdminApplication](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a5240c7d53051f0d14b27f0a59a2fc945:~:text=hyphenate.chat.EMConferenceManager.-,handleAdminApplication) | 管理员处理申请管理员请求 | -| [muteMember](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a5176c44768bec0b59578315281dae6ad) | 发送静音命令 | -| [unmuteMember](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a5176c44768bec0b59578315281dae6ad:~:text=hyphenate.chat.EMConferenceManager.-,unmuteMember) | 发送解除静音命令 | - - -### EMConference - -| 属性 | 描述 | -| :----------------------------------------------------------- | :----------------- | -| [PubStreamId](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#adcda2ab5ab431592ef906983c8a9df26) | pub流id | -| [ConferenceId](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#abbc72b5f188a81ce4ca5838e0d978279) | 会议id | -| [ConferenceType](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#ac4670d3c5bdf52c470bb86153038a781) | 会议类型 | -| [Admins](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#a55d2d906bc8338b457dac33277a196f9) | 会议中的管理员列表 | -| [Talkers](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#a705ffe7f293ec11ec4fe41c431eb9557) | 会议中的主播列表 | -| [RecordOnServer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#ad9d0782589e50a43a7c9ce3f17497994) | 是否开启云端录制 | -| [AudienceTotal](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#af1de8816baeca6f69d49c7d4539740d0) | 会议中的观众人数 | -| [Extension](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference.html#a38a2d557655a55f51f1376a9497d64e4) | 会议扩展信息 | - -### EMConferenceListener - -| 方法 | 描述 | -| :----------------------------------------------------------- | :------------------------------------- | -| [onMemberJoined](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#af1d01093be1c3ba9301a23ca094cbb7a) | 成员加入会议 | -| [onMemberExited](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#aff81ccb071666c3f06197bedf1ed0f39) | 成员离开会议 | -| [onStreamAdded](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#ad06a034d00575fbf41798b98bebe6089) | 有新的成员推流 | -| [onStreamUpdate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a11fd34c44310869dc1b610d8929bdb65) | 有成员更新自己的推流 | -| [onPassiveLeave](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a1582a269102203e93373853d50ca7a74) | 被动离开会议 | -| [onAdminAdded](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a544928e7b0fb91b5d86edfc86bad7bfa) | 管理员增加通知 | -| [onAdminRemoved](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a9cb74ec8dc164d5e8be0ef41db4ed2fa) | 管理员移除通知 | -| [onApplyAdminRefused](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#af1d01093be1c3ba9301a23ca094cbb7a:~:text=default%20void%20com.hyphenate.EMConferenceListener.onApplyAdminRefused) | 申请管理员失败通知(只有申请管理者收到) | -| [onApplySpeakerRefused](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a995b85e550b2de8c3055a9b1709267a1) | 申请主播失败通知(只有申请管理者收到) | -| [onPubStreamFailed](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a0208f1a6c8610a1bc89bedfd8c1583bf) | pub 流失败 | -| [onUpdateStreamFailed](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a63bdfe9b48ff313cd3d4458fd91fc262) | update 流失败 | -| [onConferenceState](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#af54f319c0388bf4a9f0bbaa118baa4b0) | 会议状态通知回调 | -| [onStreamStatistics](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#aa1bd09bf1b7532a234e66968c33b7c34) | 统计信息回调 | -| [onStreamSetup](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#ad27bc75a608abc06c48ddbbbe8449d52) | 推本地流或订阅成员流成功回调 | -| [onStreamStateUpdated](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a3e7bec56a7a6b12da1314911a451871a) | 订阅流的数据状态回调 | -| [onSpeakers](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a4e9febe04b53b334e5c11b69fbf27749) | 当前说话者回调 | -| [onReceiveInvite](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a6ff0dfbd9286181dbfd5a5a26b3bc07a) | 收到会议邀请 | -| [onRoleChanged](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a6df0e567fc534314cee3008c310dfe72) | 当前登录用户角色被管理员改变 | -| [onReqSpeaker](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a316b29cdcf4b6e0b4887ba2ef7a339a3) | 请求成为主播通知 | -| [onReqAdmin](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a745d99b8f8d7560a67f009cd1c280a4c) | 请求成为管理员通知 | -| [onMuteAll](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#acc356b01d68a1182a3ff658e1739cc66) | 被全体静音 | -| [onMute](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#acc356b01d68a1182a3ff658e1739cc66) | 被静音通知 | -| [onUnMute](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a42ed6aba161a01a7374311047a55e3a7) | 被取消静音通知 | -| [onGetLivecfg](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a469617faf2cba13273c903875ad6c7a8) | 获取直播推流CDN 信息 | -| [onGetLocalStreamId](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#ae6f40a14bf9b7e198877ba06178fb32b) | 获取自己StreamId | -| [onPubDesktopStreamFailed](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a427cf03bbd681f6e5a4c7d8cec24d0ef) | 发布共享桌面流失败回调 | -| [onFirstFrameSent](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a95313ebf76b573192f91fa586ebc832c) | Pub 首帧回调streamId流ID | -| [onFirstFrameRecived](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a98e14b220cfa43ff992406cb3a9089e5) | Pub 首帧回调 | -| [onFirstFrameSent](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1_e_m_conference_listener.html#a95313ebf76b573192f91fa586ebc832c) | Sub 首帧回调 | - -### EMConferenceMember - -| 属性 | 描述 | -| :----------------------------------------------------------- | :--------------- | -| [memberName](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_member.html) | 会议成员Name | -| [memberId](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_member.html) | 会议成员Id | -| [nickName](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_member.html) | 会议成员昵称 | -| [extension](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_member.html) | 会议成员扩展字段 | - -### EMConferenceStream - -| 属性 | 描述 | -| :----------------------------------------------------------- | :----------------------- | -| [StreamId](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a2c05fdc542e7de1fe510c86e5d2ffae7) | 流id | -| [StreamName](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a1f138ff27a4550e0660f013ff7a479cc) | 流Name | -| [MemberName](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a558e8149e02a2bed7ede363db600f8ca) | 流的所属成员的MemberName | -| [Username](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a851e77d978ef23db876d9f99c59789a8) | 流的所属成员的Username | -| [Extension](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a243ef8254bd354b6038e0779b9342115) | 流的扩展字段 | -| [VideoOff](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#adf570ce4deafeff59ca289949fd3d48f) | 流视频是否关闭 | -| [AudioOff](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a9de7ca96da69e90ba7c6fb8091938a40) | 流音频是否关闭 | -| [StreamType](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_stream.html#a9de7ca96da69e90ba7c6fb8091938a40) | 流的类型 | - -### EMStreamParam - -| 属性 | 描述 | -| :----------------------------------------------------------- | :----------------- | -| [name](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a210fcb233701b4c2e5698b08aa029fe9) | 推流配置名称 | -| [videoOff](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a2cbb57448a013c854f552adf2837d0e6) | 是否关闭视频 | -| [audioOff](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a4e4bc1d46d1c82f324950aea9b0c8a0f) | 是否静音 | -| [useBackCamera](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a682014ca04fe6e692ee0470f3d59d325) | 使用后置摄像头 | -| [videoHeight](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a4d7f3be9c29fe1146160fe81050076e5) | 视频高度 | -| [videoWidth](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#af9e0a4165400cc07113936e976841ace) | 视频宽度 | -| [extension](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a65daa3acf8e0fc0b0e5b684b4265df77) | 扩展字段 | -| [maxAudioKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a337e2c42212282ff188f119e478c885a) | 设置最大音频比特率 | -| [minVideoKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#adb8eb12d1d37b28f9a2216e57aa651d4) | 设置最小的网络带宽 | -| [maxVideoKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a0065046c59c8fda054ad833b8c3cae5a) | 最大视频码率 | -| [streamType](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a1a196f933b8504073732bcb19900699a) | stream 类型 | -| [shareView](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#af6c63073334df4b09fc81a4f5a3b2c8e) | 分享的view | -| [audioSampleRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_param.html#a2818857429c256757573eb0ade1084a3) | 设置音频采样频率 | - -### EMStreamStatistics - -音视频通话统计信息实体类,具体请看[EMStreamStatistics ](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_stream_statistics.html)的详细介绍 - -### EMConferenceAttribute - -会议属性设置类,具体请看[EMConferenceAttribute](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_attribute.html) 的详细介绍 - -### EMRoomConfig - -会议房间属性类 ,具体请看[EMRoomConfig](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_room_config.html) 的详细介绍 - -### EMLiveConfig - -CDN推流设置类,具体请看[EMLiveConfig](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_live_config.html) 的详细介绍 - -### EMAudioConfig - -自定义录制格式定义类,具体请看[EMAudioConfig](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_audio_config.html) 的详细介绍 - -### EMCDNCanvas - -CDN 画布设置类,具体请看[EMCDNCanvas](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_c_d_n_canvas.html) 的详细介绍 - -### EMLiveRegion - -视频流在画布宽高及显示位置等参数类,具体请看[EMLiveRegion](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_live_region.html) 的详细介绍 \ No newline at end of file diff --git a/docs/private/media/conference_introduction.md b/docs/private/media/conference_introduction.md deleted file mode 100644 index bb196f6e..00000000 --- a/docs/private/media/conference_introduction.md +++ /dev/null @@ -1,213 +0,0 @@ -# 多人通话简介 - -## 产品概述 - -- 以会议为单位,支持创建会议,加入会议,发布流,订阅流,退出会议等功能; -- 发布流是指参会者发布媒体流(即发言,包括视频流和音频流)到服务器,其他人收到发布事件然后去订阅拉取媒体流。 -- 只依赖即时通讯的用户登录功能,不依赖即时通讯的消息机制,所以和即时通讯功能(例如环信即时通讯云)是松耦合的; -- 本身不支持呼叫邀请功能,开发者可以通过发送自定义即时通讯消息来实现邀请其他人加入会议; -- 纯音频会议最高可以支持千人会议;视频会议支持12个主播视频互动,支持百人以上的观众; - -## 功能列表 - -| 功能 | Android 原生 | iOS 原生 | Web | 微信小程序 | PC桌面 | -| :------------- | :----------- | :------- | :------- | :--------- | :----- | -| 音频通话 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 视频通话 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 共享桌面 | 支持 | 支持 | 部分支持 | 不支持 | 支持 | -| 静音自己 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 不听他人 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 外部视频源输入 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | -| 管理员踢人 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 管理员全体静音 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 管理员授权上麦 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 观众申请上麦 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 伴音 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | -| 视频流水印 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | -| 开启云录制 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 会议属性 | 支持 | 支持 | 支持 | 支持 | 支持 | -| 合流旁路CDN | 支持 | 支持 | 支持 | 不支持 | 支持 | - -## 通话流程 - -SDK端创建和操作音视频会议的过程简单来说,可以分为以下几步: - -- 设置监听 -- create: 创建会议 -- join: 加入会议 -- pub: 发布音视频数据流 -- sub: 订阅并播放音视频数据流 -- leave: 离开会议 -- destroy:销毁会议 - -## 角色权限 - -- 参会用户中有管理员,主播和观众三种角色 - - 管理员(也称作主持人):拥有最高权限,可以发布媒体流,订阅媒体流,设定其他人是主播还是观众;一个会议中可以有多个管理员; - - 主播:可以发布媒体流,订阅媒体流 - - 观众:只有订阅媒体流权限 -- 会议创建者自动是管理员 -- 创建会议时可以指定其他人默认最高权限 - - 如果指定默认其他人最高权限是主播,则其他人可以主播角色加入会议,也可以观众角色加入会议 - - 如果指定默认其他人最高权限是观众,则其他人只能以观众角色加入会议,不能以主播角色加入会议 -- 在会议中,管理员可以随时修改某个参会者的最高权限 -- 管理员退出会议时,系统会自动指定一名主播为管理员,如果没有主播则不会指定; -- 观众加入会议是静默的,即管理员,主播和其他观众不会收到通知(为了避免通知风暴) - -## 会议属性 - -- 会议属性是一个Key:Value字符串对,Key和Value由开发者自由设置 -- 当一个会议属性被修改时,所有人都会收到通知 -- 开发者可以使用会议属性来实现更灵活的会议控制,满足各种场景的需求 - -## 场景应用下载 - -[>>下载场景应用Demo及源码](common_clientsdk.html#场景demo及源码下载) - - - - - - - - - - - - - - - - - - - - - - - - -
方案说明平台下载SDK及Demo下载应用
视频会议音视频会议可以支持创建会议、加入会议等功能Android下载代码体验Demo
iOS下载代码\
Web下载代码体验Demo
桌面端下载代码体验Windows Demo

体验MAC Demo
- - -## 计费说明 - -环信私有化音视频服务计费规则及功能详情,请联系商务经理程先生(Tel:17611319060) \ No newline at end of file diff --git a/docs/private/media/conference_ios.md b/docs/private/media/conference_ios.md deleted file mode 100644 index d413cfb8..00000000 --- a/docs/private/media/conference_ios.md +++ /dev/null @@ -1,1618 +0,0 @@ -# iOS 多人音视频通话 - -## 跑通Demo - - - -### 1. 示例代码 - -- [下载视频会议Demo代码 ](https://github.com/easemob/videocall-ios) - -或进入环信[客户端下载](common_clientsdk.html#场景demo及源码下载)页面,选择下载iOS端视频会议 Demo。 - -### 2. 前提条件 - -运行Demo前需要具备以下条件: - -- mac操作系统10.11以上 -- 安装Xcode 11以上 -- iPhone设备iPhone 6以上,安装系统iOS 9.0以上 - -### 3. 运行Demo - -#### 3.1 Demo代码目录简介 - -目录 VideoCallDemo/EMiOSVideoCallDemo 中的 Demo 关键类介绍 - -![img](/images/privitization/conference_ios_demo.png) - -多人音视频Demo主要包含3个target,SharedDesktop和SharedDesktopSetupUI用于实现共享桌面功能,EMiOSVideoCallDemo是会议target,实现类如下: - -- RoomJoinViewController 加入房间页面 -- ConferenceViewController 视频展示页面 -- AccountSettingViewController 个人设置页面 -- RoomSettingViewController 房间设置页面 -- SpeakerListViewController 主播列表页面 -- KickSpeakerViewController 选人下麦页面 -- EMStreamView 视频小窗口类 -- EMDemoOption 会议管理类,存储会议的设置和单例属性 -- ChangeRoleView 管理员处理上麦申请页面 -- ProfileVidwController 个人资料页面 -- UpdateNicknameViewController 修改昵称页面 -- SelectHeadImageViewController 修改头像页面 - -#### 3.2 工程设置 - -Demo中的源码不包含SDK,SDK可以从cocospods安装,或者从官网下载,然后拷贝到当前工程下 - -- 使用cocoapods安装SDK - -如果当前系统上没有安装cocoapods,需要用户自己安装,安装过程参考 [Getting Started with CocoaPods 安装说明](https://guides.cocoapods.org/using/getting-started.html#getting-started)。 - -修改VideoCallDemo/EMiOSVideoCallDemo目录下的Podfile文件,添加如下: - -``` -pod 'Hyphenate', '~> 3.7.1' -``` - -Terminal进入该目录,运行命令: - -``` -pod install -``` - -成功安装后,Terminal 中会显示 Pod installation complete!,此时项目文件夹下会生成podfile目录,Pod已加入工作空间中 - -- 手动导入SDK - -下载 iOS SDK + Demo,目录中包含HyphenateFullSDK目录,该目录下的Hyphenate.framework即为SDK,将SDK拷贝到VideoCallDemo/EMiOSVideoCallDemo/目录下。 - -Terminal进入VideoCallDemo/EMiOSVideoCallDemo/目录,运行命令: - -``` -pod install -``` - -打开EMiOSVideoCallDemo.xcworkspace工作空间,进入工程TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content 菜单,将Hyphenate.framework拖拽进来完成添加。
- -为保证动态库的签名和 app 的签名一致,需要将动态库的 Embed 属性设置为 Embed & Sign。 - -#### 3.3 运行项目 - -连接iPhone手机,选择目标设备,点击运行 - -## 快速集成 - -多人音视频会议主要涉及到的环信SDK头文件如下: - -``` -// 多人会议部分,包含会议id,会议类型等 -EMCallConference.h - -// 数据流部分,包含数据流id,上传数据流的成员名称等 -EMCallStream.h - -// 多人实时通话会议方法调用部分,比如添加代理,移除代理,创建并加入会议,上传数据流,订阅其他人的数据流等 -IEMConferenceManager.h - -// 多人实时通话会议的协议回调方法部分,比如监听有人加入会议,有新的数据流上传回调方法等 -EMConferenceManagerDelegate.h -``` - -创建音视频通信的过程简单来说,可以分为以下几步: - -``` - 1. 初始化 SDK,设置监听代理 - 2. create: 创建会议 - 3. join: 加入会议 - 4. pub: 发布音视频数据流 - 5. sub: 订阅并播放音视频数据流 - 6. leave: 离开会议 -``` - -### 1. 环信后台注册appkey - -在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。 - -### 2. 创建项目 - -参考以下步骤创建一个iOS 应用项目,如果已有项目,可以直接进行下一步集成。创建过程如下: - -- 打开 Xcode 并点击 Create a new Xcode project。 -- 选择项目类型为 Single View App,并点击 Next。 -- 输入项目信息,如项目名称、开发团队信息、组织名称和语言,语言为Object-C,并点击 Next。 -- 选择项目存储路径,并点击 Create。 -- 进入工程设置页面的Signing & Capaabilities菜单,选择 Automatically manage signing,并在弹出菜单中点击 Enable Automatic。 - -### 3. 导入SDK到工程 - -集成SDK有两种方法,分别是使用cocoapods和手动导入SDK - -#### 使用cocoapods导入SDK - -开始前确保你已安装 Cocoapods。 - -- 在 Terminal 里进入项目根目录,并运行 pod init 命令。项目文件夹下会生成一个 Podfile 文本文件。 -- 打开 Podfile 文件,修改文件为如下内容。注意将 AppName 替换为你的 Target 名称,并将 version 替换为你需集成的 SDK 版本,如3.7.1。 - -``` -target 'AppName' do - pod 'Hyphenate', '~> version' -end -``` - -- 在 Terminal 内运行 pod update 命令更新本地库版本。 -- 运行 pod install 命令安装Hyphenate SDK。成功安装后,Terminal 中会显示 Pod installation complete!,此时项目文件夹下会生成一个 xcworkspace 文件。 -- 打开新生成的 xcworkspace 文件。 - -#### 手动导入SDK - -- 将在跑通Demo阶段下载的HyphenateFullSDK下的Hyphenate.framework拷贝到项目工程目录下 -- 打开工程设置/Genaral菜单下,将Hyphenate.framework拖拽到Frameworks,libraries,and Embedded Content下,并设置为Embed and Signed - -工程中引入SDK,需要引用头文件Hyphenate.h - -``` -#import -``` - -### 4. 添加权限 - -应用需要音频设备及摄像头权限,在 info.plist 文件中,点击 + 图标,添加如下信息。 - -| Key | Type | Value | -| :------------------------------------- | :----- | :----------------------------------- | -| Privacy - Microphone Usage Description | String | 描述信息,如“环信需要使用您的麦克风” | -| Privacy - Camera Usage Description | String | 描述信息,如“环信需要使用您的摄像头” | - -如果希望在后台运行,还需要添加后台运行音视频权限,在info.plist文件中,点击 + 图标,添加Required background modes ,Type为Array,在Array下添加元素App plays audio or streams audio/video using AirPlay。 - -### 5. 创建UI - -video视图参考Demo中的EMStreamView,会议控制界面展示参考Demo中的ConferenceViewController。 - -### 6. 初始化SDK - -初始化HyhpenateSDK使用initializeSDKWithOptions:接口,需要设置自己的appkey,调用如下: - -``` -// 这里替换成自己的appkey -EMOptions *retOpt = [EMOptions optionsWithAppkey:@"easemob-demo#chatdemoui"]; -// 这里打开日志输出 -retOpt.enableConsoleLog = YES; -[[EMClient sharedClient] initializeSDKWithOptions:retOpt]; -``` - -### 7. 环信ID注册、登录 - -在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/android/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。
-若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/android/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7)。
- -### 8. 音视频功能初始化 - -账号登录成功后,需要进行音视频通话功能的初始化,设置监听类。 - -``` -[[EMClient sharedClient].conferenceManager addDelegate:self delegateQueue:nil]; -``` - -### 9. 加入会议 - -用户可以根据房间名和密码,快速加入一个会议,若该会议不存在,服务器将会自动创建。 - -加入房间使用的接口在IEMConferenceManager.h中,用户加入时可以选择使用的角色为观众还是主播,主播可以发布自己的音视频,观众只能订阅音视频。 - -加入房间时,可以选择房间的会议类型,是否开启服务端录制,是否混音以及是否支持小程序。调用方法如下: - -``` -//Objective-C - RoomConfig* roomConfig = [[RoomConfig alloc] init]; - roomConfig.confrType = EMConferenceTypeCommunication; - roomConfig.nickName = @"昵称"; - //是否开启服务端录制 - roomConfig.isRecord = YES; - //录制时是否合并数据流 - roomConfig.isMerge = YES; - [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) { - self.conference = aCall; - }]; -``` - -加入房间成功后,返回的回调中有EMCallConference会议实例,需要本地保存下来。 - -其中RoomConfig定义如下: - -``` -//Objective-C -@interface RoomConfig:NSObject -/*! -* \~chinese -* 会议类型 -*/ -@property (nonatomic) EMConferenceType confrType; -/*! -* \~chinese -* 录制时是否合并数据流 -*/ -@property (nonatomic) BOOL isMerge; -/*! -* \~chinese -* 是否开启服务端录制 -*/ -@property (nonatomic) BOOL isRecord; -/*! -* \~chinese -* 是否支持微信小程序 -*/ -@property (nonatomic) BOOL isSupportWechatMiniProgram; -/*! -* \~chinese -* 会议中使用的昵称 -*/ -@property (nonatomic) NSString* nickName; -/*! -* \~chinese -* 成员扩展信息 -*/ -@property (nonatomic) NSString* ext; -/*! -* \~chinese -* 会议最大主播数 -*/ -@property (nonatomic) NSInteger maxTalkerCount ; -/*! -* \~chinese -* 会议最大视频上传数 -*/ -@property (nonatomic) NSInteger maxVideoCount; -/*! -* \~chinese -* 会议最大观众数 -*/ -@property (nonatomic) NSInteger maxAudienceCount; -/*! -* \~chinese -* cdn 直播推流配置 -*/ -@property (nonatomic) LiveConfig* liveConfig; -@end -``` - -注:RoomConfig中的ext表示会议成员的扩展信息,一般用于存储头像等信息,与pub流的接口中的ext信息是不同的。 - -加入会议后,会议中的其他人员会收到回调通知,如下: - -``` -- (void)memberDidJoin:(EMCallConference *)aConference - member:(EMCallMember *)aMember -{ - // aMember中包含加入用户的信息,如ID,昵称等 -} -``` - -### 10. 发布流 - -成员加入会议后,可以在会议中发布音视频流,发流过程如下: - -``` -EMStreamParam *pubConfig = [[EMStreamParam alloc] init]; -EMCallLocalView *localView = [[EMCallLocalView alloc] init]; -//显示本地视频的页面 -pubConfig.localView = localView; -//上传本地摄像头的数据流 - [[EMClient sharedClient].conferenceManager publishConference:[EMDemoOption sharedOptions].conference streamParam:pubConfig completion:^(NSString *aPubId, EMError *aError) { -// 若发流成功,aError应为nil,否则为失败信息。 -// 发流成功时,aPubId为本地流的pubId,此时应把localView添加到界面上,pubId需要在本地保存,用于操作音视频流 -}]; -streamParam参数提供了更丰富的发流选项 - -当成员发流成功后,会议中的其他成员会收到有流加入的回调通知,通知如下: - -//有新的数据流上传 -- (void)streamDidUpdate:(EMCallConference *)aConference - addStream:(EMCallStream *)aStream -{ - // aStream中包含了流信息,此时应该订阅流 -} -``` - -### 11. 订阅流 - -成员收到有数据流加入的通知后,可以订阅该流,订阅后可以接收到流内的音视频,订阅过程如下: - -``` -// remoteView用于在UI上展示对方的视频 - EMCallRemoteView *remoteView = [[EMCallRemoteView alloc] init]; - //订阅其他人的数据流,,即订阅当前会议上麦主播的数据流 - [[EMClient sharedClient].conferenceManager subscribeConference:[EMDemoOption sharedOptions].conference streamId:aStream.streamId remoteVideoView:remoteView completion:^(EMError *aError) { - // 若订阅成功,aError应为nil,否则为失败信息。 - // 订阅成功后,应把remoteView展示到UI上 - }]; -``` - -### 12. 退出会议 - -用户退出会议的过程如下: - -``` -[[EMClient sharedClient].conferenceManager leaveConference:[EMDemoOption sharedOptions].conference completion:nil]; -``` - -用户退出会议后,会议中的其他成员会收到以下回调通知: - -``` -- (void)memberDidLeave:(EMCallConference *)aConference - member:(EMCallMember *)aMember -{ - // aMember为退出的成员信息 -} -``` - -## 进阶功能 - -### 会议管理 - -#### **取日志** - -SDK会写入日志文件到本地。日志文件路径如下:沙箱Documents/HyphenateSDK/easemoblog,以真机为例,获取过程如下: - -- 打开Xcode连接设备,前往Xcode –> Window –> Devices and Simulators -- 进入Devices选项卡,在左侧选择目标设备,界面如下: - -[![img](https://docs-im.easemob.com/_media/rtc/one2one/fetchlogfile.png?w=400&tok=6c005b)](https://docs-im.easemob.com/_detail/rtc/one2one/fetchlogfile.png?id=rtc%3Aconference%3Aios) - -日志文件easemob.log文件在下载包内容的AppData/Library/Application Support/HyphenateSDK/easemobLog目录下。 - -#### **创建会议并加入** - -除根据房间名和房间密码加入会议的api外,SDK还提供了直接创建并加入会议的api,接口如下: - -``` -//Objective-C -- (void)createAndJoinConference -{ - __weak typeof(self) weakself = self; - void (^block)(EMCallConference *aCall, NSString *aPassword, EMError *aError) = ^(EMCallConference *aCall, NSString *aPassword, EMError *aError) { - if (aError) { - //错误提示 - return ; - } - - //更新页面显示 - }; - - EMConferenceType type = EMConferenceTypeCommunication; - // record 与 mergeStream、isSupportWechatMiniProgram 根据自己场景需求设置 - [[EMClient sharedClient].conferenceManager createAndJoinConferenceWithType:type password:@"password" record:NO mergeStream:NO isSupportWechatMiniProgram:NO completion:block]; -} -``` - -调用该接口后,将拥有一个会议实例Conference,同时成员将成为该Conference的管理员。 - -用户创建会议时可以设置参数指定是否支持小程序音视频,是否需要在服务器端录制,录制时是否合并流、是否支持微信小程序。 - -创建会议成功以后,默认超时时间为三分钟,超过三分钟没有人加入,会议会自动销毁;另外当会议中所有人离开2分钟后,会议也会被销毁。 - -如果想在创建会议时指定会议中的最大视频数、最大主播数,或开启cdn推流,可以使用带RoomCofnig参数的创建会议接口,此时roomconfig中指定的会议类型无效。接口如下: - -``` -/*! - * \~chinese - * 创建并加入会议 - * - * @param aType 会议类型 - * @param aPassword 会议密码 - * @param aConfrConfig 会议属性配置 - * @param aCompletionBlock 完成的回调 - */ -- (void)createAndJoinConferenceWithType:(EMConferenceType)aType - password:(NSString *)aPassword - confrConfig:(RoomConfig*)aConfrConfig - completion:(void (^)(EMCallConference *aCall, NSString *aPassword, EMError *aError))aCompletionBlock; -``` - -#### **邀请成员加入会议** - -SDK没有提供邀请接口,可以自己实现,比如使用环信IM通过发消息邀请,比如通过发邮件邀请等等。 - -至于需要发送哪些邀请信息,可以参照SDK中的join接口,可以发送Conference的confrId和password,如果是用joinRoom接口创建的会议,也可以发送房间名和房间密码。 - -比如用环信IM发消息邀请 - -``` -//Objective-C -- (void)inviteUser:(NSString *)aUserName -{ - NSString *confrId = self.conference.confId; - NSString *password = self.password; - EMConferenceType type = self.type; - NSString *currentUser = [EMClient sharedClient].currentUsername; - EMTextMessageBody *textBody = [[EMTextMessageBody alloc] initWithText:[[NSString alloc] initWithFormat:@"%@ 邀请你加入会议: %@", currentUser, confrId]]; - EMMessage *message = [[EMMessage alloc] initWithConversationID:aUserName from:currentUser to:aUserName body:textBody ext:@{@"em_conference_op":@"invite", @"em_conference_id":confrId, @"em_conference_password":password, @"em_conference_type":@(type)}]; - message.chatType = EMChatTypeChat; - [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil]; -} -``` -:::tip - 使用环信IM邀请多个人时,建议使用群组消息。如果使用单聊发消息请注意每条消息中间的时间间隔,以防触发环信的垃圾消息防御机制。 - - 被邀请人解析出邀请消息中带的confrId和password,调用SDK的join接口加入会议,成为会议成员且角色是Speaker。 -::: -``` -//Objective-C -- (void)joinConferenceWithConfrId:(NSString *)aConfrId password:(NSString *)aPassword -{ - __weak typeof(self) weakself = self; - void (^block)(EMCallConference *aCall, EMError *aError) = ^(EMCallConference *aCall, EMError *aError) { - if (aError) { - //错误提示 - return ; - } - - //更新页面显示 - }; - - [[EMClient sharedClient].conferenceManager joinConferenceWithConfId:aConfrId password:aPassword completion:block]; -} -``` - -用户B成功加入会议后,会议中其他成员会收到回调[EMConferenceManagerDelegate memberDidJoin:member:] - -#### **管理员销毁会议** - -会议中的管理员可以主动销毁会议,销毁会议过程如下: - -``` -[[EMClient sharedClient].conferenceManager destroyConferenceWithId:self.conference.confId completion:nil]; -``` - -会议销毁后,会议中的其他成员将收到会议结束的回调通知。 - -``` -- (void)conferenceDidEnd:(EMCallConference *)aConference - reason:(EMCallEndReason)aReason - error:(EMError *)aError -{ -} -``` - -#### **设置会议人数限制** - -使用createAndJoinConference接口创建会议或者第一个使用joinRoom接口加入的成员为会议创建者,会议创建者在创建会议时可以设置会议中的最大视频数、主播数、观众数、共享桌面数的上限。
-默认最大视频数12,最大主播数100,最大观众数600,最大共享桌面数2。创建会议时使用RoomConfig参数指定人数限制,过程如下: - -``` -RoomConfig* roomConfig = [[RoomConfig alloc] init]; - roomConfig.maxVideoCount = 6; - roomConfig.maxTalkerCount = 9; - roomConfig.maxAudienceCount = 30; - roomConfig.maxPubDesktopCount = 1; - [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:block]; -``` - -若加入会议时,超过最大主播数上限,加入会议返回失败,error为EMErrorCallSpeakerFull - -若发视频流时,超过最大视频数上限,将收到如下回调通知: - -``` -- (void)streamPubDidFailed:(EMCallConference *)aConference error:(EMError*)aError -{ -} -``` - -若发共享桌面流时,超过最大数上限,将收到如下回调通知: - -``` -- (void)DesktopStreamDidPubFailed:(EMCallConference *)aConference error:(EMError*)aError -{ -} -``` - -#### **获取会议信息** - -在会议进行中,可以通过getConference 方法来查询会议信息,从而可以拿到主播列表,观众人数等信息。 - -``` -/*! - * \~chinese - * 获取会议信息 - * - * @param aConfId 会议ID(EMCallConference.confId) - * @param aPassword 会议密码 - * @param aCompletionBlock 完成的回调 - */ -- (void)getConference:(NSString *)aConfId - password:(NSString *)aPassword - completion:(void (^)(EMCallConference *aCall, EMError *aError))aCompletionBlock; -``` - -#### **会议属性** - -会议属性是会议的状态信息,由一组(key,value)组成。会议中的所有角色成员(管理员、主播、观众)都可以设置/删除会议频道属性,设置的会议属性会通知给会议中的所有人。 - -设置会议属性的api方法如下: - -``` -/** - * \~chinese - * 设置频道属性,该会议中的所有人(包括自己)都会收到 - * {@link EMConferenceManagerDelegate#conferenceAttributeUpdated:attributeAction:attributeKey:}回调. - * 该方法需要在加入会议后调用. - * - * @param attrKey - * @param attrValue - * @param aCompletionBlock - */ -- (void)setConferenceAttribute:(NSString *)attrKey - value:(NSString *)attrValue - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -删除会议属性的api方法如下: - -``` -/** - * \~chinese - * 删除频道属性,该会议中的所有人(包括自己)都会收到 - * {@link EMConferenceManagerDelegate#conferenceAttributeUpdated:attributeAction:attributeKey:}回调. - * 该方法需要在加入会议后调用. - * - * @param aKey - * @param aCompletionBlock - */ -- (void)deleteAttributeWithKey:(NSString *)aKey - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -当会议属性信息改变时,会议中的成员会收到以下通知。 - -``` -- (void)conferenceAttributeUpdated:(EMCallConference *)aConference - attributes:(NSArray *)attrs -``` - -每一个EMConferenceAttribute包括了会议属性中的key,value,以及本次修改的action,action包括ADD、UPDATE、DELETE。 - -#### **cdn合流推流** - -多人音视频支持将会议中的音视频流合并成一个流,推送到第三方的cdn直播服务器。整个合流推流过程包括开启cdn推流,更新推流布局,停止推流。 - -##### **开启cdn推流** - -会议的创建者在创建会议时使用RoomConfig的接口,可以决定是否开启cdn推流,推流配置LiveConfig是RoomConfig的一个参数,可设置cdn推流的相关信息。开启过程如下: - -``` -LiveConfig* liveconfig = [[LiveConfig alloc] init]; -CDNCanvas* canvas = [[CDNCanvas alloc] init]; -canvas.fps = 18; -canvas.kbps = 900; -canvas.codec = @"H264"; -canvas.bgclr = 0x0000ff; -canvas.width = [EMDemoOption sharedOptions].liveWidth; -canvas.height = [EMDemoOption sharedOptions].liveHeight; -liveconfig.canvas = canvas; -liveconfig.cdnUrl = [EMDemoOption sharedOptions].cdnUrl; -liveconfig.layoutStyle = CUSTOM; -liveconfig.record = YES; //是否录制推流到cdn的音视频 -roomConfig.liveConfig = liveconfig; -``` - -当canvas设置的width、height为0时,cdn推流为**纯音频推流**。 - -推流成功后,可以在EMConference对象中查看liveId,如果只有一路推流,可直接使用EMConference对象的liveId;如果存在多路推流,可访问EMConference对象的liveCfgs对象,liveCfgs存储了所有的推流信息。 - -LiveConfig可设置的参数如下: - -``` -/*! -* \~chinese -* cdn 画布设置,创建会议时使用 -*/ -@interface CDNCanvas : NSObject - /*! \~chinese 画布宽度 */ -@property (nonatomic) NSInteger width; -/*! \~chinese 画布高度 */ -@property (nonatomic) NSInteger height; -/*! \~chinese 画布的背景色,格式为 RGB 定义下的 Hex 值,不要带 # 号,如 0xFFB6C1 表示浅粉色。默认0x000000,黑色。 -*/ -@property (nonatomic) NSInteger bgclr; -/*! \~chinese 推流帧率,可设置范围10-30 */ -@property (nonatomic) NSInteger fps; -/*! \~chinese 推流码率,单位kbps,width和height较大时,码率需要提高,可设置范围1-5000 */ -@property (nonatomic) NSInteger kbps; -/*! \~chinese 推流编码格式,目前只支持"H264" */ -@property (nonatomic) NSString* codec; - -@end - -/*! -* \~chinese -* cdn推流使用的画布类型 -*/ -typedef NS_ENUM(NSInteger, LayoutStyle) { - CUSTOM, - DEMO, - GRID -}; -/*! -* \~chinese -* cdn推流设置 -*/ -@interface LiveConfig : NSObject - -/*! \~chinese 推流url地址*/ -@property (nonatomic,strong) NSString *cdnUrl; - -/*! \~chinese 推流画布的配置*/ -@property (nonatomic) CDNCanvas* canvas; - -/*! \~chinese 推流方式,GRID或者CUSTOM,GRID将由服务器设置位置信息,CUSTOM将由用户自定义流的位置信息*/ -@property (nonatomic) LayoutStyle layoutStyle; - -/*! \~chinese 是否开启自定义录制*/ -@property (nonatomic) BOOL record; - -/*! \~chinese 音频录制参数*/ -@property (nonatomic) AudioConfig* audioCfg; - -@end -``` - -##### **更新布局** - -当用户调用更新布局接口后,cdn推流方式将强制变成CUSTOM模式,所有流的位置信息都由用户自己定义。 更新布局的接口如下: - -``` -/*! -* \~chinese -* 修改会议的cdn推流位置 -* -* @param aCall 会议实例(自己创建的无效) -* @param aReagionList 媒体流的位置信息 -* @param aLiveId 推流Id -* @param aCompletionBlock 回调函数 -*/ -- (void)updateConference:(EMCallConference*)aCall - liveId:(NSString*)aLiveId - setRegions:(NSArray*)aReagionList - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -LiveRegion的结构如下: - -``` -/*! -* \~chinese -* cdn推流的每一路流的模式 -*/ -typedef NS_ENUM(NSInteger, LiveRegionStyle) { - /*! \~chinese FIt模式 */ - LiveRegionStyleFit, - /*! \~chinese FIll模式 */ - LiveRegionStyleFill -}; - -/*! -* \~chinese -* cdn推流的每一路流的区域位置信息 -*/ -@interface LiveRegion : NSObject - -/*! \~chinese 流ID */ -@property (nonatomic) NSString* streamId; - -/*! \~chinese 流的左上角在x轴坐标 */ -@property (nonatomic) NSInteger x; - -/*! \~chinese 流的左上角在y轴坐标 */ -@property (nonatomic) NSInteger y; - -/*! \~chinese 流的宽度 */ -@property (nonatomic) NSInteger w; - -/*! \~chinese 流的高度 */ -@property (nonatomic) NSInteger h; - -/*! \~chinese 流的图层顺序,越小越在底层,从1开始 */ -@property (nonatomic) NSInteger z; - -/*! \~chinese 流的显示模式,Fit或Fill */ -@property (nonatomic) LiveRegionStyle style; - -@end -``` - -使用方法如下: - -``` -NSMutableArray* regionsList = [NSMutableArray array]; -LiveRegion* region = [[LiveRegion alloc] init]; -region.streamId = _streamId; -region.style = LiveRegionStyleFill; -region.x = 80; -region.y = 60; -region.w = 320; -region.h = 240; -region.z = 9; -[regionsList addObject:region]; -[[[EMClient sharedClient] conferenceManager] updateConference:[EMDemoOption sharedOptions].conference liveId:aLiveId setRegions:regionsList completion:^(EMError *aError) { - }]; -``` - -##### **多路推流** - -多人音视频支持加入会议后,增加一路推流,只有管理员权限可进行次操作。增加一路推流的api方法如下: - -``` -/*! -* \~chinese -* 添加一路推流 -* -* @param aCall 会议实例(自己创建的无效) -* @param aLiveConfig 推流配置 -* @param aCompletionBlock 回调函数 -*/ -- (void)addConferenceLive:(EMCallConference*)aCall - LiveCfg:(LiveConfig*)aLiveConfig - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -##### **停止推流** - -管理员可以控制停止某一路推流,停止推流接口如下: - -``` -/*! -* \~chinese -* 删除一路推流 -*/ -- (void)deleteConferenceLive:(EMCallConference*)aCall - liveId:(NSString*)aLiveId - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -#### **云端录制** - -多人音视频会议支持云端录制功能,包括服务器默认录制以及自定义布局录制两种 - -##### **服务器默认录制** - -服务器默认录制为九宫格布局,在会议创建时,由创建者指定是否开启,开启方法为创建会议时指定isRecord为YES,如下: - -``` -//Objective-C - RoomConfig* roomConfig = [[RoomConfig alloc] init]; - roomConfig.isMerge = YES; - roomConfig.isRecord = YES; - [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) { - self.conference = aCall; - }]; -``` - -##### **自定义布局录制** - -在推流的LiveConfig设置里,设record为YES,可以开启自定义录制,开启后会把推流到cdn的音视频按照推流布局录制下来。如果推流时未开启,也可以在推流后进行开启/停止自定义录制布局操作。开启/停止自定义录制布局的api如下: - -``` -/*! -* \~chinese -* 启动/停止自定义录制 -* -* @param aCall 会议实例(自己创建的无效) -* @param aLiveId 推流/录制Id -* @param aEnabled 操作,启动/停止 -* @param aCompletionBlock 回调函数 -*/ -- (void)enableRecordLiveStream:(EMCallConference*)aCall - liveId:(NSString*)aLiveId - enabled:(BOOL)aEnabled - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -#### **设置昵称,头像解决方案** - -多人音视频通话提供设置昵称的接口,在加入会议时设置;不直接提供头像设置接口,但提供头像设置方案,在加入会议时将头像url设置到RoomConfig的ext中,过程如下: - -``` -//Objective-C - RoomConfig* roomConfig = [[RoomConfig alloc] init]; - roomConfig.nickName = @"昵称"; - NSMutableDictionary* extDic = [NSMutableDictionary dictionary]; - NSString* headImage = [EMDemoOption sharedOptions].headImage; - [extDic setObject:headImage forKey:@"headImage"]; - NSError *jsonError = nil; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:extDic options:NSJSONWritingPrettyPrinted error:&jsonError]; - NSString *jsonStr = @""; - if (jsonData && !jsonError) { - jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - } - roomConfig.ext = jsonStr; - [[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) { - self.conference = aCall; - }]; -``` - -#### 私有部署 - -私有部署设置方法参见[私有云sdk集成配置](../im/uc_iOS_private.md) - -### 音视频管理 - -#### **设置通话参数** - -通话之前,可以设置音频通话的最大音频码率,最小视频码率、最大视频码率、分辨率和是否清晰度优先,设置方法如下: - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -options.maxAudioKBps = 32; -options.maxVideoKBps = 3000; -options.minVideoKBps = 500; -options.maxVideoFrameRate = 20; -options.videoResolution = EMCallVideoResolution352_288; -options.isClarityFirst = YES;//若设为清晰度优先,将在弱网环境下保证视频的分辨率 -``` - -#### **停止发布流** - -成员A可以调用unpublish接口取消自己已经发布的数据流,操作成功后,会议中的其他成员会收到回调[EMConferenceManagerDelegate streamDidUpdate:removeStream:] ,将对应的数据流信息移除。 - -``` -//Objective-C -- (void)unpubStream -{ - [[EMClient sharedClient].conferenceManager unpublishConference:self.conference - streamId:self.pubStreamId completion:^(EMError *aError) - { - //code - }]; -} -``` - -#### **停止订阅流** - -成员B如果不想再看成员A的音视频,可以调用SDK接口unsubscribe。 - -``` -//Objective-C -- (void)unsubStream -{ - __weak typeof(self) weakself = self; - [[EMClient sharedClient].conferenceManager unsubscribeConference:self.conference streamId:self.pubStreamId completion:^(EMError *aError) { - //code - }]; -} -``` - -#### **操作自己订阅的流** - -对于订阅成功的流,可以有以下操作: - -``` -/** - * \~chinese - * mute远端音频 - * - * @param aStreamId 要操作的Steam id - * @param isMute 是否静音 - */ -- (void)muteRemoteAudio:(NSString *)aStreamId mute:(BOOL)isMute; - -/** - * \~chinese - * mute远端视频 - * - * @param aStreamId 要操作的Steam id - * @param isMute 是否关闭 - */ -- (void)muteRemoteVideo:(NSString *)aStreamId mute:(BOOL)isMute; -``` - -#### **通话中音视频控制** - -成员发布了自己的音视频流后,在会议过程中,可以进行以下操作: - -- 切换前后摄像头,调用如下 - -``` -[[[EMClient sharedClient] conferenceManager] updateConferenceWithSwitchCamera:self.conference]; -``` - -- 开关静音 - -``` -[[[EMClient sharedClient] conferenceManager] updateConference:self.conference isMute:YES]; -``` - -- 开关视频 - -``` -[[[EMClient sharedClient] conferenceManager] updateConference:self.conference enableVideo:YES]; -``` - -当成员对自己的数据流做开关静音/视频时,会议中的其他成员会收到回调[EMConferenceManagerDelegate streamDidUpdate:stream:] - -``` -//Objective-C -- (void)streamDidUpdate:(EMCallConference *)aConference stream:(EMCallStream *)aStream -{ - if ([aConference.callId isEqualToString:self.conference.callId] && aStream != nil) { - //判断本地缓存的EMCallStream实例与aStream有哪些属性不同,并做相应更新 - } -} -``` - -#### **音视频首帧回调** - -当成员发布流成功,发送第一帧音视频数据时,成员收到以下通知: - -``` -/*! - * \~chinese - * 发送第一帧音视频数据时,收到此回调 - * - * @param aConference 会议 - * @param aType 流类型,音频或视频 - * @param streamId 流ID -*/ -- (void)streamDidFirstFrameSended:(EMCallConference*)aConference type:(EMMediaType)aType streamId:(NSString*)streamId; -``` - -当成员订阅流成功,收到第一帧音视频数据时,成员会收到以下通知: - -``` -/*! - * \~chinese - * 接收流第一帧音视频数据时,收到此回调 - * - * @param aConference 会议 - * @param aType 流类型,音频或视频 - * @param streamId 流ID -*/ -- (void)streamDidFirstFrameReceived:(EMCallConference*)aConference type:(EMMediaType)aType streamId:(NSString*)streamId; -``` - -#### **音视频无数据回调** - -当会议中的成员A因断网或异常退出,而无音视频数据上传时,订阅该流的其他成员会收到下面的回调通知。 - -``` -/*! - * \~chinese - * 下行音频流无数据时,收到此回调 - * - * @param aConference 会议 - * @param aType 流类型,音频或视频 - * @param streamId 流ID -*/ -- (void)streamStateUpdated:(EMCallConference*)aConference type:(EMMediaType)aType state:(EMMediaState)state streamId:(NSString*)streamId; -``` - -该功能需要会议中开启质量统计(必须在创建或者加入会议成功之后,在调用此方法) - -``` -[[EMClient sharedClient].conferenceManager enableStatistics:YES]; -``` - -#### **弱网检测** - -SDK提供多人音视频会议的网络连接状态检测,当本地网络断开、重连、质量差时收到以下回调。该功能需要会议中开启质量统计。 - -``` -- (void)conferenceNetworkDidChange:(EMCallConference *)aSession - status:(EMCallNetworkStatus)aStatus - { - } -``` - -#### **通话质量** - -使用[conferenceManager enableStatistics:YES]开启视频质量统计后,用户会周期性收到视频质量数据的回调,回调函数定义如下: - -``` -/*! - * \~chinese - * 当前会议的媒体流质量报告回调 - * - * @param aConference 会议 - * @param streamId 流ID - * @param aReport 会议的质量参数 -*/ -- (void)conferenceDidUpdate:(EMCallConference*)aConference streamId:(NSString*)streamId statReport:(EMRTCStatsReport *)aReport; -``` - -[查看EMRTCStatsReport详细信息](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_r_t_c_stats_report.html) - -#### **监听谁在说话** - -多人音视频会议可以实时监听谁在说话,该功能需要开启,启动/停止控制如下: - -``` -// 开始监听说话者,参数为间隔时间 - [[[EMClient shareClient] conferenceManager] startMonitorSpeaker:(EMCallConference *)aCall - timeInterval:(long long)aTimeMillisecond - completion:(void (^)(EMError *aError))aCompletionBlock]; - - // 停止监听说话者 - [[[EMClient shareClient] conferenceManager] stopMonitorSpeaker:(EMCallConference *)aCall]; -``` - -有人说话时,会议成员会收到如下回调通知 - -``` -- (void)conferenceSpeakerDidChange:(EMCallConference *)aConference - speakingStreamIds:(NSArray *)aStreamIds -{ -} -``` - -#### **mute远端音视频流** - -会议成员可以对自己订阅的远端音视频流进行mute操作,操作后自己不接收远端的音视频流,不影响会议中的其他人。操作接口如下: - -``` -/** - * \~chinese - * mute远端音频 - * - * @param aStreamId 要操作的Steam id - * @param isMute 是否静音 - */ -- (void)muteRemoteAudio:(NSString *)aStreamId mute:(BOOL)isMute; - -/** - * \~chinese - * mute远端视频 - * - * @param aStreamId 要操作的Steam id - * @param isMute 是否显示 - */ -- (void)muteRemoteVideo:(NSString *)aStreamId mute:(BOOL)isMute; -``` - -#### **变声/自定义音频** - -用户可以通过自己采集音频数据,使用外部输入音频数据的接口进行通话,从而实现变声等音频数据加工功能。 - -##### **配置属性** - -用户使用自定义音频数据时,需要配置外部输入音频数据的开关,以及音频采样率,通道数(当前通道数只支持1),配置方法如下: - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -options.enableCustomAudioData = YES; -options.audioCustomSamples = 48000; -options.audioCustomChannels = 1; -//这里调用加入会议接口 -``` - -##### **输入音频数据** - -音频数据采集可参考1v1音视频通话Demo中的AudioRecord类实现,音频数据的输入必须在加入会议成功的回调后开始,否则会导致网络阻塞,影响通话质量。 - -``` -[[[EMClient sharedClient] conferenceManager] joinRoom:roomName password:pswd role:role roomConfig:roomConfig completion:^(EMCallConference *aCall, EMError *aError) { - self.conference = aCall; - EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; - if(options.enableCustomAudioData){ - [self audioRecorder].channels = options.audioCustomChannels; - [self audioRecorder].samples = options.audioCustomSamples; - [[self audioRecorder] startAudioDataRecord]; - } - }]; -``` - -音频采集过程开始后,在音频数据的回调里调用外部输入音频数据接口 - -``` -[[[EMClient sharedClient] conferenceManager] inputCustomAudioData:data]; -``` - -会话挂断时,停止音频采集及输入过程。 - -``` -//多人会议挂断触发事件 -- (void)hangupAction -{ - EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; - if(options.enableCustomAudioData) { - [[self audioRecorder] stopAudioDataRecord]; - } -} -``` - -#### **美颜/自定义视频** - -如果用户需要自己采集特定的数据或者对于数据需要先进行一些处理,如滤镜、美颜等,可以使用SDK的外部输入视频数据的方法进行。 - -##### **配置属性** - -使用外部输入视频数据接口前,需要先进行配置,配置参数为EMStreamParam中的enableCustomizeVideoData,设为YES可开启外部输入视频功能,开启后需要在publishConference的成功回调中开始视频数据采集。 - -``` -__block NSString *publishId = @""; -EMStreamParam *streamParam = [[EMStreamParam alloc] init]; -streamParam.enableCustomizeVideoData = YES; // 开启自定义视频流 - -[[EMClient sharedClient].conferenceManager publishConference:self.conference - streamParam:streamParam - completion:^(NSString *aPubStreamId, EMError*aError) { - if(!aError) { - publishId = aPubStreamId; - // **TODO:这里开启视频数据采集过程** - [self startCapture] - } -}]; -``` - -在视频数据采集的回调中调用外部输入视频数据接口inputVideoSampleBuffer。 - -``` -- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection -{ - if ([self.delegate respondsToSelector:@selector(videoCaptureDataCallback:)]) - { - // 输入视频流 - [[EMClient sharedClient].conferenceManager inputVideoSampleBuffer:sampleBuffer - rotation:orientation - conference:self.conference - publishedStreamId:publishId - completion:^(EMError *aError) { - }]; - } -} -``` - -在关闭视频传输或会议结束的回调中,停止视频数据的采集。 - -``` -//多人会议挂断触发事件 -- (void)hangupAction -{ - [self stopCapture]; -} -``` - -#### **共享桌面** - -使用sdk共享桌面,只能共享指定的view。 - -``` -EMStreamParam *streamParam = [[EMStreamParam alloc] init]; -streamParam.type = EMStreamTypeDesktop; -streamParam.desktopView = self.view; -[[EMClient sharedClient].conferenceManager publishConference:self.conference - streamParam:streamParam - completion:^(NSString *aPubStreamId, EMError *aError) { - -}]; -``` - -因为上面方法的实现原理是不停的截取指定view的快照,并转换成流发送,这种方式的效率并不高,ios10以上用户建议使用系统的replaykit + 自定义输入流的方式实现共享桌面,具体replaykit使用可以参考[官方文档](https://developer.apple.com/documentation/replaykit?language=objc) - -(需要集成3.6.3或以上版本的sdk) - -特别指出,如果需要在共享桌面时输入自己的流,需要修改上一步中的设置: - -``` -EMStreamParam *streamParam = [[EMStreamParam alloc] init]; -streamParam.type = EMStreamTypeDesktop; -streamParam.desktopView = nil; // 使用自定义输入流,此处需要传nil -streamParam.videoResolution = EMCallVideoResolution_Custom;//为了防止共享桌面被裁剪,需要使用自定义分辨率 -CGFloat screenX = [UIScreen mainScreen].bounds.size.width; -CGFloat screenY = [UIScreen mainScreen].bounds.size.height; -streamParam.videoWidth = screenY*[UIScreen mainScreen].scale; -streamParam.videoHeight = screenX*[UIScreen mainScreen].scale; - -[[EMClient sharedClient].conferenceManager publishConference:self.conference - streamParam:streamParam - completion:^(NSString *aPubStreamId, EMError *aError) { - if(!aError) { - publishId = aPubStreamId; - } -}]; - -// 输入视频流 -[[EMClient sharedClient].conferenceManager inputVideoSampleBuffer:sampleBuffer - rotation:orientation - conference:self.conference - publishedStreamId:publishId - completion:^(EMError *aError) { - -}]; -``` - -#### **水印** - -视频通话时,可以添加图片作为水印,添加时使用[IEMConferenceManager addVideoWatermark]接口,需要指定水印图片的NSUrl,添加位置参见[EMWaterMarkOption](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_water_mark_option.html)。 - -清除水印使用[IEMConferenceManager clearVideoWatermark]接口。 - -显示remoteVideo需要使用EMCallViewScaleModeAspectFit模式,否则对方的水印设在边缘位置可能显示不出来。 - -``` -/*! -* \~chinese -* 开启水印功能 -* -* @param option 水印配置项,包括图片URL,marginX,marginY以及起始点 -*/ -- (void)addVideoWatermark:(EMWaterMarkOption*)option; -/*! -* \~chinese -* 取消水印功能 -* -*/ -- (void)clearVideoWatermark; -// 添加水印 -NSString * imagePath = [[NSBundle mainBundle] pathForResource:@"watermark" ofType:@"png"]; -EMWaterMarkOption* option = [[EMWaterMarkOption alloc] init]; -option.marginX = 60; -option.startPoint = LEFTTOP; -option.marginY = 40; -option.enable = YES; -option.url = [NSURL fileURLWithPath:imagePath]; -[[EMClient sharedClient].conferenceManager addVideoWatermark:option]; - -// 清除水印 -[[EMClient sharedClient].conferenceManager clearVideoWatermark]; -``` - -### 角色管理 - -#### **观众申请主播** - -会议中的观众角色可以向管理员发申请成为主播,管理员可以选择同意或者拒绝。观众申请主播的接口需要管理员的memId,先通过获取会议属性接口获取到管理员的memName,然后根据memName以及成员加入的回调中获取到的EMCallMember,获取到memId。接口如下: - -``` -/*! -* \~chinese -* 观众申请连麦成为主播,观众角色调用 -* -* @param aCall 会议实例(自己创建的无效) -* @param aAdminId 管理员的memId -* @param aCompletionBlock 回调函数 -*/ -- (void)requestTobeSpeaker:(EMCallConference *)aCall adminId:(NSString *)aAdminId completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -观众发出申请后,管理员将会收到以下回调: - -``` -/*! - * \~chinese - * 收到观众申请主播的请求,只有管理员会触发 - * - * @param aConference 会议 - * @param aMemId 申请人memId - * @param aNickName 申请人昵称 - * @param aMemName 申请人memName -*/ -- (void)conferenceReqSpeaker:(EMCallConference*)aConference memId:(NSString*)aMemId nickName:(NSString*)aNickName memName:(NSString*)aMemName; -``` - -在回调中,管理员可以选择同意或者拒绝,如果同意,需要调用接口changeMemberRoleWithConfId授权,然后回复申请人;如果拒绝,则直接调用回复接口。回复接口如下: - -``` -/*! -* \~chinese -* 管理员同意/拒绝观众的上麦申请,管理员调用 -* -* @param aCall 会议实例(自己创建的无效) -* @param aMemId 上麦申请的观众的memId -* @param aResult 操作结果,0为同意,1为拒绝 -* @param aCompletionBlock 回调函数 -*/ -- (void)responseReqSpeaker:(EMCallConference *)aCall - memId:(NSString *)aMemId - result:(NSInteger)aResult - completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -#### **主播申请管理员** - -会议中的主播角色可以向管理员发申请成为管理员,管理员可以选择同意或者拒绝,成为管理员后,各管理员之间的权限是相同的。主播申请管理员的接口需要管理员的memId,先通过获取会议属性接口获取到管理员的memName,然后根据memName以及成员加入的回调中获取到的EMCallMember,获取到管理员memId,调用接口changeMemberRoleWithConfId授权,然后回复申请人,接口如下: - -``` -/*! -* \~chinese -* 主播申请成为管理员,主播角色调用 -* -* @param aCall 会议实例(自己创建的无效) -* @param aAdminId 管理员的memId -* @param aCompletionBlock 回调函数 -*/ -- (void)requestTobeAdmin:(EMCallConference *)aCall adminId:(NSString *)aAdminId completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -主播发出申请后,管理员将会收到以下回调: - -``` -/*! - * \~chinese - * 收到主播申请管理员的请求,只有管理员会触发 - * - * @param aConference 会议 - * @param aMemId 申请人memId - * @param aNickName 申请人昵称 - * @param aMemName 申请人memName -*/ -- (void)conferenceReqAdmin:(EMCallConference*)aConference memId:(NSString*)aMemId nickName:(NSString*)aNickName memName:(NSString*)aMemName; -``` - -在回调中,管理员可以选择同意或者拒绝,如果同意,需要调用改变用户权限的接口changeMemberRoleWithConfId,然后调用回复接口;如果拒绝,则直接调用回复接口。回复接口如下: - -``` -/*! -* \~chinese -* 管理员同意/拒绝主播的申请管理员请求,管理员调用 -* -* @param aCall 会议实例(自己创建的无效) -* @param aMemId 申请管理员的主播的memId -* @param aResult 操作结果,0为同意,1为拒绝 -* @param aCompletionBlock 回调函数 - */ -- (void)responseReqAdmin:(EMCallConference *)aCall memId:(NSString *)aMemId result:(NSInteger)aResult completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -管理员对其他观众、主播的角色进行升级、降级处理的接口如下: - -aMemberName 是appkey拼接环信id,例如:easemob-demo#chatdemoui_lulu1 - -**管理员/主播也可以直接使用该接口对自己进行降级** - -``` -/*! -* \~chinese -* 改变成员角色,需要管理员权限 -* 用户角色: Admin > Talker > Audience -* 当角色升级时,用户需要给管理员发送申请,管理通过该接口改变用户接口. -* 当角色降级时,用户直接调用该接口即可. -* -* @param aConfId 会议ID(EMCallConference.confId) -* @param aMemberName 成员在会议中的memName -* @param aRole 成员角色 -* @param aCompletionBlock 完成的回调 -*/ -- (void)changeMemberRoleWithConfId:(NSString *)aConfId - memberName:(NSString *)aMemberName - role:(EMConferenceRole)toRole - completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -#### **管理员踢人** - -管理员可以强制会议成员离开会议,使用接口: - -``` -/*! - * \~chinese - * 踢人,需要管理员权限 - * - * @param aConfId 会议ID(EMCallConference.confId) - * @param aMemberNameList 成员名列表 - * @param aCompletionBlock 完成的回调 - */ -- (void)kickMemberWithConfId:(NSString *)aConfId - memberNames:(NSArray *)aMemberNameList - completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -#### 全体静音/指定成员静音 - -该系列接口调用需要加入会议后,先获取一下会议信息,调用getConference接口。 - -##### **全体静音** - -管理员可以对会议进行全体静音/解除全体静音设置,设置后,会议中的主播都将处于静音状态,新加入的主播也将自动处于静音状态。只有管理员可以调用此接口。 接口API如下: - -``` -/** -* \~chinese -* 开启/停止全体静音,只有管理员可调用此接口 -* -* @param enable 是否启用全体静音 -* @param completion 回调 -*/ -- (void)muteAll:(BOOL)mute - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -管理员调用此接口后,会议中的主播将收到全体静音状态的回调,回调函数如下: - -``` -/*! - * \~chinese - * 收到全体静音/解除全体静音的回调 - * - * @param aConference 会议 - * @param aMuteAll 是否全体静音 -*/ -- (void)conferenceDidUpdated:(EMCallConference *)aConference - muteAll:(BOOL)aMuteAll; -``` - -##### **指定成员静音** - -管理员可以对会议中的指定成员进行静音/解除静音设置,被指定成员可以是主播也可以是管理员。设置后,被指定成员将静音/解除静音。只有管理员可以调用此接口。 接口API如下: - -``` -/*! -* \~chinese -* 将指定成员静音/解除静音,管理员调用 -* -* @param aCall 会议实例(自己创建的无效) -* @param aMemId 指定成员的memId -* @param aMute 操作,YES为静音,NO为解除静音 -* @param aCompletionBlock 回调函数 -*/ -- (void)setMuteMember:(EMCallConference *)aCall - memId:(NSString *)aMemId - mute:(BOOL)aMute - completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -管理员调用此接口后,被指定的成员将收到静音状态的回调,回调函数如下: - -``` -/*! - * \~chinese - * 收到静音/解除静音的回调 - * - * @param aConference 会议 - * @param aMute 是否静音 -*/ -- (void)conferenceDidUpdated:(EMCallConference*)aConference - mute:(BOOL)aMute; -``` - -#### **本身角色变更回调** - -当成员本身的角色发生变化时,收到以下回调: - -``` -/*! - * \~chinese - * 自己的角色发生变化 - * - * @param aConference 会议实例 - */ -- (void)roleDidChanged:(EMCallConference *)aConference; -``` - -#### **管理员变更回调** - -当会议中的普通成员成为管理员,或管理员降级为普通成员时,会议中的其他成员将收到管理员变更的回调。管理员变更回调分为管理员新增和管理员移除,回调接口如下: - -``` -/*! - * \~chinese - * 管理员新增 - * - * @param aConference 会议实例 - * @param adminmemid 新的管理员memid - */ -- (void)adminDidChanged:(EMCallConference *)aConference - newAdmin:(NSString*)adminmemid; - -/*! - * \~chinese - * 管理员放弃 - * - * @param aConference 会议实例 - * @param adminmemid 放弃管理员的memid - */ -- (void)adminDidChanged:(EMCallConference *)aConference - removeAdmin:(NSString*)adminmemid; -``` - -## 客户端API - -多人音视频通话的API包括以下接口: - -- EMCallOption 多人音视频通话配置类 -- EMConferenceManager 是多人音视频通话的主要管理类,提供了加入会议、退出、发流、订阅等接口 -- EMConferenceManagerDelegate 是多人音视频通话的监听回调类,多人音视频通话相关的回调 -- EMCallConference 多人音视频通话的会议实例接口 - -### EMCallOption - -| 属性 | 描述 | -| :----------------------------------------------------------- | :-------------------------------- | -| [maxAudioKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#aea45547ce623a0fd5d53a36f00334520) | 最大音频码率 | -| [maxVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a4130c8f7488d6d6f58c3783dc63be5fd) | 最大视频码率 | -| [minVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae070e260597c913634a21c03aa31826a) | 最小视频码率 | -| [maxVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a45f020f84b4513fdc0cb3f8a123fe678) | 最大视频帧率 | -| [videoResolution](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af49ac4f01b9bca538fbce40e1de5f866) | 视频分辨率 | -| [enableReportQuality](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af2129acdd0d3d73a583e8d37dfc087e2) | 是否监听通话质量 | -| [enableCustomAudioData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae927cb60d05c59b389517648941e7ec8) | 是否使用自定义音频数据 | -| [audioCustomSamples](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a76482a8e2702e1905c036142e41c8a6d) | 自定义音频数据的采样率,默认48000 | -| [enableCustomizeVideoData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a89f38b15e05ed5d6636af5fde628d114) | 是否使用自定义视频数据 | -| [isClarityFirst](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a38497058ab86b80f156ba3b362100b4e) | 是否清晰度优先 | - -### EMConferenceManager - -| 方法 | 描述 | -| :----------------------------------------------------------- | :---------------------------------------------- | -| [addDelegate:delegateQueue:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a2b985523160a8a9f47346e1065667dfb) | 添加回调代理 | -| [removeDelegate:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#acc88916806c943608d41c307012d2113) | 移除回调代理 | -| [setAppkey:username:token:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a16c1d9b53642b97e07e6ae1c55925519) | 设置应用Appkey, 环信ID, 环信ID对应的Token | -| [getConference:password:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a53da60e7a584697191b52734c4517669) | 获取会议信息 | -| [createAndJoinConferenceWithType:password:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a838273c88e5264cbf0508de0d0e3aeef) | 创建并加入会议 | -| [createAndJoinConferenceWithType:password:confrConfig:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a0f5820f9c560ca0a6ccfee963c423185) | 创建并加入会议 | -| [joinConferenceWithConfId:password:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#acead28618cffee8a9068897bbb238df8) | 加入已有会议 | -| [joinConferenceWithTicket:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a1a81bcafde9fa0d9a826a80dee15f981) | 加入已有会议 | -| [joinRoom:password:role:roomConfig:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a9dc56f6f8c505322baff4074964640d8) | 加入房间 | -| [publishConference:streamParam:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a45cb75e64fd0abd04d71ae7cbaa39668) | 上传音视频数据流 | -| [unpublishConference:streamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ab80d817ea9953a75d59284bece48e7ac) | 取消上传本地音视频数据流 | -| [subscribeConference:streamId:remoteVideoView:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a5bc905bb6427f586c18ea6a3b87fb58a) | 订阅其他人的数据流 | -| [unsubscribeConference:streamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#af95a48dc945a95062e868db32615b1d0) | 取消订阅的数据流 | -| [changeMemberRoleWithConfId:memberName:role:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac6df4fd1e2b16c98e4f515d45aa08d21) | 改变成员角色,需要管理员权限 | -| [kickMemberWithConfId:memberNames:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a094785f9b5ee245226399234bd72fe58) | 踢人,需要管理员权限 | -| [destroyConferenceWithId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac3c7426a3b6dc1b50bad419d2f722ee8) | 销毁会议,需要管理员权限 | -| [leaveConference:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ae54239e73e21df83450961a8263a14f7) | 离开会议 | -| [startMonitorSpeaker:timeInterval:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28726fcdc8ce28006a30d713f40227c0) | 开始监听说话者 | -| [stopMonitorSpeaker:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#aa67291522b649278e770c7bb1b3ee9b3) | 结束监听说话者 | -| [updateConference:liveId:setRegions:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a00098d155bc5b6b8a0941f2b7b140b3f) | 修改会议的cdn推流布局 | -| [addConferenceLive:LiveCfg:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ad36907936af8fcf74f64cd311d6456c7) | 添加一路推流 | -| [enableRecordLiveStream:liveId:enabled:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a391e86342e05c90345c6f0594008c368) | 启动/停止自定义录制 | -| [deleteConferenceLive:liveId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ad879b9caafabcfcbc271e5e23937805a) | 删除一路推流 | -| [requestTobeSpeaker:adminId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a94e5010c1349d40fddde33b7cc489274) | 观众申请连麦成为主播 | -| [requestTobeAdmin:adminId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#af2e99d266d5d3f67490903b17818b17c) | 主播申请成为管理员, | -| [responseReqSpeaker:memId:result:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a097c52f9ea833b9ac289290247c25860) | 管理员同意/拒绝观众的上麦申请,管理员调用 | -| [responseReqAdmin:memId:result:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a34ff57a1a78c507d5118249e4863b8ff) | 管理员同意/拒绝主播的申请管理员请求,管理员调用 | -| [setMuteMember:memId: mute:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a6432c2f2a68760b1cad2dabb6e9cba6d) | 将指定成员静音/解除静音,管理员调用 | -| [updateConferenceWithSwitchCamera:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28bd7490cb8e238a07a5aec62d164cea) | 切换前后摄像头 | -| [updateConference:isMute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | 设置是否静音 | -| [updateConference:enableVideo:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a478c1c8b08758a55fdea520d6772ae9e) | 设置视频是否可用 | -| [updateConference:maxVideoKbps:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ab57a72f199fa779b7b3158712e2d0a0a) | 更新视频最大码率 | -| [inputVideoSampleBuffer:rotation:conference:publishedStreamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#af906e2f6de9ca0d9005bf6c46c9d46e8) | 输入自定义本地视频数据 | -| [inputVideoPixelBuffer:sampleBufferTime:rotation:conference:publishedStreamId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a544a757e0f2a16c9b265243c784f1fd4) | 输入自定义本地视频数据 | -| [setConferenceAttribute:value:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ae98d762cb6aed35de22da40779455fcb) | 设置会议属性, | -| [deleteAttributeWithKey:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a226dbe5816201a32fa3850dd1bb3c991) | 删除频道属性 | -| [startAudioMixing: loop:sendMix:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#aa7e7d1a088f746f98b796d94b3eb631d) | 开启本地伴音功能 | -| [stopAudioMixing](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a703c15925f723cc3c4ec59f347226a91) | 关闭本地混音功能 | -| [adjustAudioMixingVolume:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a9b9a168a7e160ff08b5ccf13d2b8ab2f) | 设置伴奏音量 | -| [muteRemoteAudio: mute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28f9297ad2411c6aa9bdbb291bb8df26) | mute远端音频 | -| [muteRemoteVideo: mute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a870a36303635529c953194b9d240521b) | mute远端视频 | -| [enableStatistics:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#aa57d7c7aaec58f84fb0f81b38f36a2e4) | 启用统计 | -| [muteAll:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a0a7340e4fe935143ba0ff529858ad295) | 全体静音 | -| [inputCustomAudioData:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a2fb9faf9d767ed2e58315c1db354df37) | 输入自定义外部音频数据 | -| [addVideoWatermark:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a64ed13e19b65e3c8fb06113a96da37c5) | 开启水印功能 | -| [clearVideoWatermark](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a950faf99db0d40e2a89c62fd8113f34d) | 取消水印功能 | - -### EMConferenceManagerDelegate - -| 回调事件 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------------------- | -| [memberDidJoin:member:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a35ae6bcf830548162cc9c7e6f6df0cd8) | 有人加入会议 | -| [memberDidLeave:member:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a2349384a054912620858346dff81eb41) | 有人离开会议 | -| [roleDidChanged:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ada8c07dac796d492a5165b28b50fb02c) | 自己的角色发生变化 | -| [adminDidChanged:newAdmin:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0532f12f9e7ae6cf5f7837793062f4ea) | 管理员新增 | -| [adminDidChanged:removeAdmin:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a56cc91df21df41aad12e33940bff987c) | 管理员放弃 | -| [streamPubDidFailed:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a99ce878eb647a0ae04b8de3829e41f9b) | 本地pub流失败 | -| [DesktopStreamDidPubFailed:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a3d7f3ca91389d95c6fe29f15d3d41fbb) | 发布共享桌面流失败 | -| [streamUpdateDidFailed:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0ac987ff2ecb9e34dc786f1da50466df) | 本地update流失败,视频超限 | -| [streamDidUpdate:addStream:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aaec86cf13eaa8930fa5261c1f3848785) | 有新的数据流上传 | -| [streamDidUpdate:stream:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#adee2f6109508e383000d5e99e33b9bde) | 数据流有更新(是否静音,视频是否可用) | -| [streamDidUpdate:removeStream:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a4a92350f846d00e913c48a3286e9da77) | 有数据流移除 | -| [conferenceDidEnd:reason:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a9e35574e2e6fcedcc5cf3d4f0f9a26e6) | 会议已经结束 | -| [streamStartTransmitting:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a37025ed1fda0ff26798c31aabbcf7105) | 数据流已经开始传输数据 | -| [conferenceDidUpdated:muteAll:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a2db2fd8d67522325ecb8412479842ccd) | 收到全体静音/解除全体静音的回调 | -| [conferenceSpeakerDidChange:speakingStreamIds:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0917065a18ca3ce9433d6677288830c3) | 用户A用户B在同一个会议中,用户A开始说话时,用户B会收到该回调 | -| [conferenceAttributeUpdated:attributes:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a0917065a18ca3ce9433d6677288830c3) | 会议属性变更 | -| [conferenceReqSpeaker:memId:nickName:memName:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#afca1af08d628fd0be0ddd1bed1bf9138) | 收到观众申请主播的请求,只有管理员会触发 | -| [conferenceReqAdmin:memId:nickName:memName:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ad90e5d598c1b8cb57a02cd6b81fc929e) | 收到主播申请管理员的请求,只有管理员会触发 | -| [conferenceDidUpdated: mute:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a2b09dd5dbb6144cc561027378bc3f1e7) | 收到静音/解除静音的回调 | -| [conferenceReqSpeakerRefused:adminId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ae598e6c668121780573ce2402be3d745) | 收到申请主播请求被拒绝的回调 | -| [conferenceReqAdminRefused:adminId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aa285cef35bc14db40ef17be9245798ed) | 收到申请管理员请求被拒绝的回调 | -| [conferenceDidUpdated:liveCfg:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#acccb25d9f4eef388781be85cfeefb5ff) | 会议开启cdn推流或自定义录制,收到LiveCfg的回调,只有管理员能收到 | -| [streamIdDidUpdate:rtcId:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#adde6567323a5ffaf249841da585174b8) | 收到本地流streamId的回调,发布流成功后收到此回调 | -| [streamStateUpdated:type:state:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aff906c9db5f6be3685a44e5c83d0ca0e) | 下行音频流无数据时,收到此回调 | -| [streamDidFirstFrameSended:type:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ab7ce7a7c76c5dca0918c8f8b5875b5e9) | 发送第一帧音视频数据时,收到此回调 | -| [streamDidFirstFrameReceived:type:streamId:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a1879f50eea95cdabbf0e265bc1a03fef) | 接收流第一帧音视频数据时,收到此回调 | -| [confrenceDidUpdated:state:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ac03c8bd548fd6ae0623eb0b6f99f8b80) | 会议状态改变时,收到此回调 | -| [onferenceDidUpdate:streamId:statReport:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#a8940c01890169f6c5a68f8d6787264e9) | 当前会议的媒体流质量报告回调 | - -### EMCallConference - -参见http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_conference.html \ No newline at end of file diff --git a/docs/private/media/conference_pcdesktop.md b/docs/private/media/conference_pcdesktop.md deleted file mode 100644 index e288e50a..00000000 --- a/docs/private/media/conference_pcdesktop.md +++ /dev/null @@ -1,15 +0,0 @@ -# PC桌面集成多人通话 - -## Demo下载 - -windows: [下载](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/rtcdemo/%E7%8E%AF%E4%BF%A1%E8%A7%86%E9%A2%91%E4%BC%9A%E8%AE%AE.2.0.1.win.setup.exe) - -macOS: [下载](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/rtcdemo/%E7%8E%AF%E4%BF%A1%E8%A7%86%E9%A2%91%E4%BC%9A%E8%AE%AE.2.0.1.mac.dmg) - -## 技术实现: - -外部使用 [electorn.js教程](http://www.electronjs.org/)包装 - -内部load web 端页面 - -参考 [Web集成多人通话](conference_web.html) \ No newline at end of file diff --git a/docs/private/media/conference_uniapp.md b/docs/private/media/conference_uniapp.md deleted file mode 100644 index f1176761..00000000 --- a/docs/private/media/conference_uniapp.md +++ /dev/null @@ -1,485 +0,0 @@ -# uni-app集成多人音视频通话 - -## 前言 - -[uni-app](https://uniapp.dcloud.io/README)是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台,uni-app需要使用[hbuilderX](https://www.dcloud.io/hbuilderx.html)进行开发。 - -环信为用户使用uni-app开发原生应用并拥有音视频功能,特别提供了适配uni-app的音视频SDK和[uni-app原生插件](https://ext.dcloud.net.cn/plugin?id=3507),用户可以集成后快速在android和ios原生客户端使用音视频功能。 - -:::tip -目前音视频插件仅支持运行在iOS以及Android,暂不支持运行在微信小程序使用。如需运行到微信小程序我们为此提供了小程序音视频SDK,请移步小程序集成多人音视频文档部分。 -::: -使用 uni-app 集成多人音视频SDK,需要下载环信uni-app原生插件**emlive-pusher**、**emlive-player**配合一起使用。音视频SDK依赖IM SDK, 所以要先集成IM,并把IM SDK实例挂载在全局变量下:uni.WebIM = websdk, 可以参考[uni-app demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-uniapp-demo.zip) utils/WebIM 文件。 - ------- - -## 运行demo - -下载好[uni-app demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-uniapp-demo.zip)后,导入hbuilderX,需要检查manifest.json/原生插件配置中是否选中了插件,否则需要自己选择nativeplugins中的EMLiveplugin插件,然后点击hbuilderX的运行→运行到手机或模拟器→制作自定义调试基座。 此时hbuilderX会进行打包,等打包成功后,点击运行→运行到手机或模拟器→运行基座选择→自定义调试基座,选择好后重新点击运行→运行到手机或模拟器→找到自己的设备 等安装好后,就可以在群组聊天中点击电话的icon,发起多人会议。 - ------- - -## uniapp音视频插件 - -### 导入插件 - -在[插件市场](https://ext.dcloud.net.cn/plugin?id=3507)下载好插件后,放到uniapp工程的nativeplugins目录下,如果没有此目录需要自己创建。导入好插件后需要在工程目录manifest.json中选择:App原生插件配置/本地插件中选择刚导入的插件[EMLivePlugin(适用平台: Android,IOS)],最后需要在hbuilderX上选择: 运行→运行到手机或模拟器→制作自定义调试基座,这样插件就导入成功了,下次运行时在运行→运行到手机或模拟器→运行基座选择中选择自定义调试基座。 - -### 插件参数说明 - -**emlive-pusher**插件参数说明: - -| 属性名称 | 类型 | 描述 | -| :-------------- | :---------- | :----------------------------------------------------------- | -| ref | string | 页面根据ref找到该组件 | -| style | string | 组件样式,参考原生组件支持样式 | -| muted | boolean | 是否静音 | -| enableCamera | boolean | 是否打开摄像头 | -| devicePosition | string | 默认使用摄像头,front为前置,back为后置 | -| videoWidth | number | 视频分辨率宽 | -| videoHeight | number | 视频分辨率高 | -| minBitrate | number | 最小视频码率 | -| maxBitrate | number | 最大视频码率 | -| mirror | boolean | 是否镜像,Android独有,iOS没有 | -| objectFit | string | 填充方式,fit和fill | -| isClarityFirst | boolean | 是否清晰度优先 | -| rtcLogToConsole | boolean | 是否将Rtc日志输出到控制台 | -| bindstatechange | eventhandle | 状态变化事件,detail={code, info} | -| bindnetstatus | eventhandle | 网络状态通知,detail={code, info} | -| callbackData | eventhandle | 数据回调通知,需要将回调出来的数据传给SDK | -| callbackStats | eventhandle | 通话质量统计,detail={data},data为通话质量数据,包括视频分辨率、码率、丢包率等 | - -示例代码: - -``` - - ref="livePlayer" - style="width:350px;height:300px" - :muted="false" - :enable-camera="true" - object-fit="fill" - :rtcLogToConsole="true" - @bindstatechange="onStateChange" - @bindnetstatus="onNetStatusChange" - @callbackData="onData" - @callbackStats="onStats"> - -``` - -**emlive-player**插件参数说明: - -| 属性名称 | 类型 | 描述 | -| :-------------- | :---------- | :----------------------------------------------------------- | -| ref | string | 页面根据ref找到该组件 | -| style | string | 组件样式,参考原生组件支持样式 | -| muted | boolean | 是否静音 | -| enableCamera | boolean | 是否打开视频 | -| openSpeaker | boolean | 是否打开扬声器 | -| objectFit | string | 填充方式,fit和fill | -| rtcLogToConsole | boolean | 是否将Rtc日志输出到控制台 | -| bindstatechange | eventhandle | 状态变化事件,detail={code, info} | -| bindnetstatus | eventhandle | 网络状态通知,detail={code, info} | -| callbackData | eventhandle | 数据回调通知,需要将回调出来的数据传给SDK | -| callbackStats | eventhandle | 通话质量统计,detail={data},data为通话质量数据,包括视频分辨率、码率、丢包率等 | - -示例代码: - -``` - - ref="livePlayer" - style="width:350px;height:300px" - :muted="false" - :enable-camera="true" - object-fit="fill" - :rtcLogToConsole="true" - @bindstatechange="onStateChange" - @bindnetstatus="onNetStatusChange" - @callbackData="onData" - @callbackStats="onStats"> - -``` - -**bindstatechange**回调参数说明: - -| code值 | info | 描述 | -| :----- | :-------------------------------- | :----------------- | -| 2000 | RTCIceConnectionStateNew | 建立流媒体链接 | -| 2001 | RTCIceConnectionStateChecking | 检测流媒体连接状态 | -| 2002 | RTCIceConnectionStateConnected | 流媒体连接成功 | -| 2003 | RTCIceConnectionStateCompleted | 流媒体连接过程完成 | -| 2004 | RTCIceConnectionStateFailed | 流媒体连接失败 | -| 2005 | RTCIceConnectionStateDisconnected | 流媒体断开连接 | -| 2006 | RTCIceConnectionStateClosed | 流媒体关闭连接 | -| 2102 | receive first audio frame | 接收到音频首帧 | -| 2102 | receive first audio frame | 接收到音频首帧 | -| 2103 | receive first video frame | 接收到视频首帧 | -| 2104 | audio has no data | 音频无数据 | -| 2105 | video has no data | 视频无数据 | - -**bindnetstatus**回调参数说明: - -| code值 | info | 描述 | -| :----- | :--------------- | :--------- | -| 4000 | net connected | 网络已连接 | -| 4001 | net poor quality | 网络不稳定 | -| 4002 | net disconnected | 网络已断开 | - ------- - -## 音视频SDK集成 - -uniapp音视频SDK的集成和微信小程序音视频SDK的集成类似,主要分为以下几个步骤: - -- 1、引入SDK -- 2、创建会议 -- 3、自己加入会议并发出邀请(邀请方式为:发送携带会议信息的邀请信息,可以是文本消息亦可以是自定义消息等方式。) -- 4、发布自己的音视频流 -- 5、其他人收到邀请加入会议 -- 6、其他人发布音视频流 -- 7、监听SDK onMemberJoined、onStreamAdded事件,收到其他人的流之后订阅流 -- 8、监听插件 callbackData、bindstatechange事件,将数据传给SDK -- 9、显示画面 -- 10、退出会议 - ------- - -### 引入SDK - -SDK下载地址: - -- 通过github[仓库地址]() - -音视频SDK在emediaSDK/emedia_for_miniProgram.js - -引入: - -``` -let emedia = uni.emedia = require("./emediaSDK/emedia_for_miniProgram"); - emedia.config({useUniappPlugin: true}) // 设置使用uniapp插件 -``` - ------- - -### 创建会议 - -调用createConference创建会议,示例代码: - -``` -/** - * @param {number} confrType - 会议类型, 建议使用 10 - * @param {string} password - 会议密码 - * @param {boolean} rec - 是否录制 - * @param {boolean} recMerge 是否合并录制 - */ -uni.emedia.mgr.createConference(confrType, password, rec, recMerge).then( (data) => { - let ticket = data.data.ticket - let ticketJosn = JSON.parse(ticket) - let confrId = ticketJosn.confrId -}) -``` - ------- - -### 加入会议 - -调用joinConference加入会议,示例代码: - -``` -/** - * @param {string} confrId - 会议id - * @param {string} password - 会议密码 - */ -uni.emedia.mgr.joinConference(confrId, password) -``` - ------- - -### 发布流 - -调用publish加入会议,示例代码: - -``` -/** - * @param {string} confrId - 会议id - * @param {object} livePusher - emlivePusher 插件 - */ -uni.emedia.mgr.publish(confrId, this.$refs.livePusher) -``` - ------- - -### 监听有人加入会议 - -使用onMemberJoined监听有人加入会议,示例代码: - -``` -uni.emedia.mgr.onMemberJoined = function(member){ - // member 人员信息 -} -``` - ------- - -### 监听有媒体流加入 - -使用onStreamAdded回调监听有媒体流加入,示例代码: - -``` -uni.emedia.mgr.onStreamAdded = function(stream) { - // stream 媒体流 -} -``` - ------- - -### 订阅流 - -调用subscribe订阅媒体流,示例代码: - -``` -/** - * @prama {string} confrId - 会议id - * @prama {object} stream - 媒体流 - * @prama {object} livePlayer - emlivePlayer 插件 - */ -uni.emedia.mgr.subscribe(confrId, stream, this.$refs.livePlayer) -``` - ------- - -### 将插件数据传给SDK - -将插件callbackData 和 bindstatechange 返回的数据传给SDK,示例代码: - -``` - - - ref="livePusher" - objectFit="fill" - :videoWidth="640" - :videoHeight="480" - :muted="muted" - :enableCamera="enableCamera" - :devicePosition="devicePosition" - :rtcLogToConsole="true" - @bindnetstatus="netstatus" - @bindstatechange="statechange" - @callbackData="onData" - > - - - - ref="livePlayer" - objectFit="fit" - @bindstatechange="playerStateChange" - @bindnetstatus="playerNetChange" - :muted="false" - :enableCamera="true" - :openSpeaker="openSpeaker" - @callbackData="onPlayerData" - > - -// script -onData(data){ - uni.emedia.mgr.postMessage(confrId, data, this.$refs.livePusher) -} -onPlayerData(data){ - uni.emedia.mgr.postMessage(confrId, data, this.$refs.livePlayer) -} -statechange(state){ - uni.emedia.mgr.onStateChange(state) -} -``` - ------- - -## SDK APIs - -### 常量 - -``` -// 会议类型 -emedia.mgr.ConfrType = { - COMMUNICATION: 10, //普通会议模式 - COMMUNICATION_MIX: 11, //大会议模式 - LIVE: 12, //直播模式 -}; - -// 角色 -emedia.mgr.Role = { - ADMIN: 7, //管理员(可推送视频、可解散会议、可踢人、可变更其他人角色,会议创建者默认为管理员) - TALKER: 3, // 主播(可发言、可观看) - AUDIENCE: 1 // 观众(仅可以观看) -}; -``` - -### APIs - -1、创建会议 - -``` -/** - * @method createConference 创建会议 - * @param {string} confrType - 会议类型 - * @param {string} password - 会议密码 - * @param {boolean} rec - 是否录制 默认false - * @param {boolean} recMerge - 是否合并 默认false - */ -emedia.mgr.createConference(confrType, password, rec, recMerge) -``` - -2、加入会议 - -``` -/** - * @method joinConference 加入会议 - * @param {string} confrId - 会议id - * @param {string} password - 会议密码 - */ -uni.emedia.mgr.joinConference(confrId, password) -``` - -3、发布流 - -``` -/** - * @method publish 发布流 - * @param {string} confrId - 会议id - * @param {object} livePusher - emlivePusher 插件 - */ -uni.emedia.mgr.publish(confrId, this.$refs.livePusher) -``` - -4、订阅流 - -``` -/** - * @method publish 订阅流 - * @param {string} confrId - 会议id - * @param {object} livePusher - emlivePusher 插件 - */ -uni.emedia.mgr.subscribe(confrId, stream, this.$refs.livePlayer) -``` - -5、把插件callbackData返回的数据传给SDK - -``` -/** - * @method postMessage 把插件数据传给SDK - * @param {string} confrId - 会议id - * @param {object} data - 插件会烦数据 - * @param {object} emlivePlugin - emlivePusher 或者 emlivePlayer - */ -uni.emedia.mgr.postMessage(confrId, data, emlivePlugin) -``` - -6、将插件bindstatechange返回的数据传给SDK - -``` -/** - * @method onStateChange 把插件state数据传给SDK - * @param {object} state - 插件状态 - */ -uni.emedia.mgr.postMessage(state) -``` - -7、退出会议 - -``` -/** - * @method exitConference 退出会议 - * @param {string} confrId - 会议id - */ -uni.emedia.mgr.exitConference(confrId) -``` - -8、解散会议 - -``` -/** - * @method destroyConference 解散会议 - * @param {string} confrId - 会议id - */ -uni.emedia.mgr.destroyConference(confrId) -``` - -9、踢人 - -``` -/** - * @method kickMembersById 解散会议 - * @param {string} confrId - 会议id - * @param {Array} memberNames 踢出的人 - */ -uni.emedia.mgr.kickMembersById(confrId, memberNames) -``` - -10、改变角色 - -``` -/** - * @method grantRole 改变角色 - * @param {string} confrId 会议id - * @param {Array} memberNames 人员 - * @param {string} role 角色 - */ -emedia.mgr.grantRole(confrId, memberNames, role) -``` - -### 回调 - -1、有人加入会议,已经在会议中的人将会收到回调 - -``` -emedia.mgr.onMemberJoined = function (member) {}; -``` - -2、有人退出会议,已经在会议中的人将会收到回调 - -``` -emedia.mgr.onMemberExited = function (member) {}; -``` - -3、有媒体流加入,如有人推流之后 - -``` -emedia.mgr.onStreamAdded = function (stream) {}; -``` - -4、有媒体流移除,如有人退出之后 - -``` -emedia.mgr.onStreamRemoved = function (stream) {}; -``` - -5、角色改变 - -``` -emedia.mgr.onRoleChanged = function (role) {}; -``` - -6、媒体流发生变化,比如有人关闭摄像头 - -``` -emedia.mgr.onMediaChanaged = function (stream) {}; -``` - -7、会议退出,自己主动退出,服务端主动关闭 - -``` -emedia.mgr.onConferenceExit = function (reason) {}; -``` - -## 温馨提示 - -1、如何排查问题? - -- 将插件的rtcLogToConsole设置为true, 在bindstatechange、callbackData可以查看到相关日志 - -2、demo基于hbuilderX版本? - -- demo基于hbuilderX 2.9.10版本 - -3、使用插件报错? - -- 插件是原生插件,需要在nvue页面里使用(uni-app不容许做成组件使用,只容许作为单独页面使用) \ No newline at end of file diff --git a/docs/private/media/conference_vxmini.md b/docs/private/media/conference_vxmini.md deleted file mode 100644 index 28ab3ac3..00000000 --- a/docs/private/media/conference_vxmini.md +++ /dev/null @@ -1,404 +0,0 @@ -# 微信小程序集成多人通话 - ------- - -**多人音视频SDK**基于微信小程序live-pusher、live-player组件, 音视频SDK依赖IM SDK,所以集成前要先集成IM,把IM SDK放在全局变量wx下,可以参考[demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-weixin-xcx.zip)中src/comps/chat/multiEmedia的集成:
let WebIM = wx.WebIM = require('sdk/connection') - -**注意:** 小程序创建的会议支持其他端加入(Android,iOS,Web,桌面端), 但是其他端创建的会议要在创建时选择支持小程序,小程序端才可以加入会议,否则无法互通。 - -## 准备 - -- 下载微信开发者工具 -- 在微信公众平台配置自己服务器域名(在私有部署后提供) -- 确保微信小程序符合使用媒体组件相应的类目并开通实时音视频权限 -- 使用微信小程序基础库 1.7.0 及以上版本 - -## 下载 - -音视频SDK在src/emedia/emedia_for_miniProgram.js,[下载客户端SDK及Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webim-weixin-xcx.zip)。 - - -## 集成 - -直接引用js: 拷贝文件 emedia_for_miniProgram 到小程序工程文件夹,使用 require 将 SDK 集成到项目中即可: - -``` -var emedia = require("../emedia/emedia_for_miniProgram.js"); -``` - -### 集成步骤 -#### **发起会议** - -1. 调用 createConference,在回调中可以得到confr对象,创建者默认为管理员 - -``` -emedia.mgr.createConference(confrType, password).then(function(confr){ - //confr 即为创建的会议 - //将ID password 发送给其他人 -}) -``` - -**请注意:在其他端创建会议时,需要指定支持小程序音视频,才能与小程序互通。** - -2. 加入会议,调用加入会议的API joinConferenceWithTicket 加入会议 - -``` -emedia.mgr.joinConferenceWithTicket(confrId, ticket, ext).then(function(confr){ - //confr 即为创建的会议 -}) -``` - -调用joinRoom加入房间(会议),可以指定房间的名称,并且在房间不存在时会自动创建,另外可以在加入会议时指定角色。 - -``` -let params = { - roomName: 'test', - password: '', - role: 7, //admin - config: {} -} -wx.emedia.mgr.joinRoom(params).then((res) => { - let confrId = res.confrId -}) -``` - -3. 发布本地视频流 - -``` -emedia.mgr.pubStream(rtcId).then(function(res){ - // 将返回的res.data.rtmp 赋值给live-pusher的src就可以推流了 -}) -``` - -4. sdk调用emedia.mgr.onMemberJoin(member, stream) 告知进入的人 - -5. sdk调用emedia.mgr.onStreamAdded(member, stream) 告知进入的人发布的流情况,在这个回调里拿到视频流去调subStream订阅流 - -6. 可根据需要进行订阅emedia.mgr.subStream(streamId) - -7. onMemberExited:当有人离开会议,onRoleChanged自己在会议中角色改变;onStreamRemoved某人取消流发布;onConferenceExit会议退出 - -#### **其他人进入会议** - -1. 调用 joinConference,在回调中可以得到confr对象,创建者默认为管理员 - -``` -emedia.mgr.joinConference(confrId, password, ext).then(function(confr){ - //confr 加入会议 -}) -``` - -2. sdk调用emedia.mgr.onMemberJoin(member, stream) 告知进入的人 - -3. sdk调用emedia.mgr.onStreamAdded(member, stream) 告知进入的人发布的流情况 - -4. 可根据需要进行订阅 - -``` -emedia.mgr.subStream(streamId).then(function(res){ - //将返回的res.data.rtmp赋值给live-player的src就可以播放了 -}) -``` - -5. onMemberExited:当有人离开会议,onRoleChanged自己在会议中角色改变;onStreamRemoved某人取消流发布;onConferenceExit会议退出 - -### SDK回调 - -1. 有人加入会议,其他人调用joinXX等方法,如果加入成功,已经在会议中的人将会收到 - -``` -emedia.mgr.onMemberJoined = function (member) {}; -``` - -2. 有人退出会议 - -``` -emedia.mgr.onMemberExited = function (member) {}; -``` - -3. 有媒体流添加,比如有人调用pubStream之后 - -``` -emedia.mgr.onStreamAdded = function (stream) {}; -``` - -4. 有媒体流移除 - -``` -emedia.mgr.onStreamRemoved = function (stream) {}; -``` - -5. 角色改变 - -``` -emedia.mgr.onRoleChanged = function (role) {}; -``` - -6. 媒体流发生变化 (比如有人关闭摄像头) - -``` -emedia.mgr.onMediaChanaged = function (stream) {}; -``` - -7. 会议退出,自己主动退出,服务端主动关闭 - -``` -emedia.mgr.onConferenceExit = function (reason, failed) { - reason = (reason || 0); - switch (reason){ - case 0: - reason = "正常挂断"; - break; - case 1: - reason = "没响应"; - break; - case 2: - reason = "服务器拒绝"; - break; - case 3: - reason = "对方忙"; - break; - case 4: - reason = "失败,可能是网络或服务器拒绝"; - if(failed === -9527){ - reason = "失败,网络原因"; - } - if(failed === -500){ - reason = "Ticket失效"; - } - if(failed === -502){ - reason = "Ticket过期"; - } - if(failed === -504){ - reason = "链接已失效"; - } - if(failed === -508){ - reason = "会议无效"; - } - if(failed === -510){ - reason = "服务端限制"; - } - break; - case 5: - reason = "不支持"; - break; - case 10: - reason = "其他设备登录"; - break; - case 11: - reason = "会议关闭"; - break; - } -}; -``` - -### 接口说明 - -1. 常量 - -``` -// 会议类型 -emedia.mgr.ConfrType = { - COMMUNICATION: 10, //普通会议模式 - COMMUNICATION_MIX: 11, //大会议模式 - LIVE: 12, //直播模式 -}; - -// 角色 -emedia.mgr.Role = { - ADMIN: 7, //管理员(可推送视频、可解散会议、可踢人、可变更其他人角色,会议创建者默认为管理员) - TALKER: 3, // 主播(可发言、可观看) - AUDIENCE: 1 // 观众(仅可以观看) -}; -``` - -2. conference|confr - -``` -// 会议对象 -{ - confrId:"TS_X296786295944036352C27", - id:"TS_X296786295944036352C27", - password: "password123", - roleToken:"roleToken", - ticket:"ticket", - type:12 -} -``` - -3. member - -``` -// 成员对象 -{ - "ext":{ //emedia.mgr.joinConference(confrId, password, {role: 'admin'})/* 用户可自定义扩展字段*/); - "role":"admin" - }, - "id":"MS_X197721744293023744C19M197756407719972865VISITOR", - "globalName":"easemob-demo#chatdemoui_yss000@easemob.com", - "name": "yss000" -} -``` - -4. stream - -``` -// 视频流对象 -{ - "id":"RTC2__Of_C19M197756407719972865VISITOR", - "voff":0, //1 视频关闭 - "aoff":0, //1 音频关闭 - "memId":"MS_X197721744293023744C19M197756407719972865VISITOR", - "owner": member ,//member对象 - "rtcId":"RTC1" -} -``` - -5. 创建会议 - -``` -/** - * @method createConference 创建会议 - * @param {string} confrType 会议类型 - * @param {string} password 会议密码 - * @param {boolean} rec 是否录制 默认false - * @param {boolean} recMerge 是否合并 默认false - */ -emedia.mgr.createConference(confrType, password).then(function(confr){ - //confr 即为创建的会议 -}) -``` - -6. 获取加入会议ticket - -``` -/** - * @method getConferenceTkt 申请tickit - * @param {string} confrId 会议id - * @param {string} password 会议密码 - */ -emedia.mgr.getConferenceTkt(confrId, password).then(function(tickit){ - -}) -``` - -7. 销毁会议 - -``` -/** - * @method destroyConference 解散会议 - * @param {string} confrId 会议id - */ -emedia.mgr.destroyConference(confrId).then(function(){ - -}) -``` - -8. 踢人 - -``` -/** - * @method kickMembersById 踢人 - * @param {string} confrId 会议id - * @param {Array} memberNames 踢出的人 - */ -emedia.mgr.kickMembersById(confrId, memberNames).then(function(){ - -}) -``` - -9. 改变角色 - -``` -/** - * @method grantRole 改变角色 - * @param {string} confrId 会议id - * @param {Array} memberNames 人员 - * @param {string} role 角色 - */ -emedia.mgr.grantRole(confrId, memberNames, role).then(function(){ - -}) -``` - -10. 使用用户名密码加入会议,可自定义ext,其他会议成员将会看到 - -``` -/** - * @method joinConference 加入会议 - * @param {string} confrId 会议id - * @param {string} password 会议密码 - * @param {Object} ext 扩展 - */ -emedia.mgr.joinConference(confrId, password, ext).then(function(){ - -}) -``` - -11. 使用ticket加入会议,可自定义ext,其他会议成员将会看到 - -``` -/** - * @method joinConferenceWithTicket 加入会议 - * @param {string} confrId 会议id - * @param {string} ticket 会议ticket - * @param {Object} ext 扩展 - */ -emedia.mgr.joinConferenceWithTicket(confrId, ticket, ext).then(function(){ - -}) -``` - -12. 调用joinRoom加入房间(会议),可以指定房间的名称,并且在房间不存在时会自动创建。 另外可以在加入会议时指定角色。 - -``` -/** - * @method joinRoom 加入房间(会议) - * @param {Object} option - * @param {string} option.roomName - 房间名称 - * @param {string} option.password - 房间密码 - * @param {number} option.role - 进入房间时的角色 - * @param {object} option.config - 扩展能力 可设置以下参数 - * @param {string} option.config.nickName - 进入会议的昵称 - * @param {boolean} option.config.rec - 是否开启录制 - * @param {boolean} option.config.recMerge - 是否开启合并 - * @param {number} option.config.maxTalkerCount - 自定义会议最大主播人数 - * @param {number} option.config.maxVideoCount - 自定义会议最大视频数 - * @param {number} option.config.maxAudienceCount - 自定义会议最大观众数 - * @param {number} option.config.maxPubDesktopCount - 自定义会议共享屏幕最大数 - * @param {object} option.config.ext - 扩展字段 用于自定义 - */ -wx.emedia.mgr.joinRoom(option).then((res) => { - let confrId = res.confrId -}) -``` - -13. 退出会议 - -``` -emedia.mgr.exitConference(confrId); -``` - -14. 发布媒体流 - -``` -/** - * @method pubStream 发布视频流 - * @param {string} rtcId 视频流id 自己发布流时rtcId = wx.emedia.util.getRtcId() - */ -emedia.mgr.pubStream(rtcId).then(function(res){ - // res.data.rtmp 为要推流的url -}) -``` - -15. 订阅媒体流 - -``` -/** - * @method subStream 订阅视频流 - * @param {string} streamId 视频流id 可以在onStreamAdded中获取其他人的视频流id - */ -emedia.mgr.subStream(streamId).then(function(res){ - // res.data.rtmp 为要播放的src -}) -``` \ No newline at end of file diff --git a/docs/private/media/conference_web.md b/docs/private/media/conference_web.md deleted file mode 100644 index ac19362a..00000000 --- a/docs/private/media/conference_web.md +++ /dev/null @@ -1,1164 +0,0 @@ -# Web集成多人通话 - -## 跑通Demo - -### 1. 示例代码 - -- [下载视频会议Demo代码 ](https://github.com/easemob/videocall-web) -- [体验Demo](https://zim-rtc.easemob.com:12007/) - -或进入环信[客户端下载](common_clientsdk.html#场景demo及源码下载)页面,选择下载Web端视频会议 Demo。 - -### 2. 前提条件 - -- 安装一款 Easemob Web SDK [支持的浏览器](common_introduction.html#兼容性说明) -- 本地安装 node 环境 >= 6.3.0 -- 必须为https+webkit内核浏览器 - -### 3. 运行 Demo - -1. 下载Demo -2. 进入 videocall-web 文件夹 -3. 安装依赖包 - -``` -npm install -``` - -4. 启动项目 - -``` -HTTPS=true npm start -``` - -## 快速集成 - -### 1. 环信后台注册 appkey - -在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。 - -### 2. 创建项目 - -``` -a.可以简单的写一个 html,引入 SDK 测试 -b.或者使用 脚手架搭建一个项目 -``` - -### 3. 引入 SDK - -#### 3.1 通过 scrpit 标签的 src 引入 - -[获取静态SDK 文件](#_3-4-获取sdk静态资源文件) - -``` - -``` - -#### 3.2 使用 npm 获取 SDK - -``` -npm install easemob-emedia -``` - -#### 3.3 在文件内引入 SDK - -``` -import emedia from 'easemob-emedia'; -``` - -#### 3.4 获取SDK静态资源文件 - -1. 首先 [下载 WebIM Demo 包](common_clientsdk.html#音视频sdk下载)
-![img](/images/privitization/wechatimg_download.png) -2. 从Demo 中选取 SDK 文件**EMedia_sdk-dev.js**
-![img](/images/privitization/wechatimg_path.png) - - -### 4. 初始化SDK - -``` -emedia.config({ - appkey, // 从环信后台 获取的appkey、必填 - consoleLogger: true, // boolean 是否开启打印日志,默认true - ... 其他的一些配置 -}); -``` - -### 5. 环信ID注册、登录 - -在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/web/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。
-若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/web/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7)。
- -### 6. 进入会议 - -:::tip -加入会议之前必须先要调用 emedia.mgr.setIdentity 方法设置 emedia 对象的memName 、token。 -::: -``` -emedia.mgr.setIdentity(memName, token); //memName:appkey +'_'+ 环信ID, token: 环信ID登录后返回的access_token -``` - -**params** 为进入会议需要的参数 - -``` -var params = { - roomName, // string 房间名称 必需 - password, // string 房间密码 必需 - role // number 进入会议的角色 1: 观众 3:主播 必需 - config:{ - rec:false, //是否开启录制会议 - recMerge:false, //是否开启合并录制 - supportWechatMiniProgram: true //是否允许小程序加入会议 - } -} -``` - -调用 **emedia.mgr.joinRoom** 进入会议,若该会议不存在,服务器将会自动创建。 - -``` -const user_room = await emedia.mgr.joinRoom(params); -``` - -返回的参数 **user_room** ,组成如下: - -``` -user_room: { - confrId: "IM3U9Z0AHDYQTF8KNDAAD00C147" 会议ID - id: "IM3U9Z0AHDYQTF8KNDAAD00C147" - joinId: "IM3U9Z0AHDYQTF8KNDAAD00C147M2" 在会议中的唯一ID - role: 1|3|7 //角色 1观众 3主播 7管理员 - roleToken:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlYXNlbW9iLWRlbW8j..." - ticket: "{\"tktId\":\"IM3U9Z0AHDYQTF8KNDAAD00C147TK1\",..." - type: 10 //会议类型 -} -``` - -### 7. 发布本地流 - -加入会议之后 调用 **emedia.publish** 发布流。 - -``` -var constaints = { // 发布音频流的配置参数, Object 必需。 video或audio属性 至少存在一个 - audio: true, // 是否发布音频 - video: true // 是否发布视频 -} -var ext = {} // 发布流的扩展信息 Object 非必需。会议其他成员可接收到 - -const pushedStream = await emedia.mgr.publish(constaints, ext); -``` - -发布本地流成功后, 调用 emedia.mgr.streamBindVideo 用于在video标签显示流。 - -``` -var videoTag = document.getElementById('#xxx') //需要显示本地流的 video 标签 -emedia.mgr.streamBindVideo(pushedStream, videoTag); -``` - -### 8. 订阅远端流 - -当远端流加入频道时,会触发 emedia.mgr.onStreamAdded 方法,我们需要给 emedia.mgr 赋值 onStreamAdded 用来接收 stream - -**我们建议项目初始化后,立即设置[常用监听函数](#_10-会议常用监听函数)** - -#### 8.1 监听 onStreamAdded 方法 -场景:当有远端流加入时。 - -:::tip -自己发布的本地流也会触发 onStreamAdded 方法, -stream.located() == true 为自己发的本地流, -也可以在这里绑定 video标签,显示本地流。 -::: - -``` -emedia.mgr.onStreamAdded = function(member, stream) { - // member:发布流人员的信息、stream:流信息 - if(!stream.located()) { - var option = { - member: member, - stream: stream, - subVideo: true, - subAudio: true, - videoTag: document.getElementById('#xxx') - } - emedia.mgr.subscribe(option.member, option.stream, option.subVideo, option.subAudio, option.videoTag) - } -} -``` - -在emedia.mgr.subscribe 方法中注意以下参数的设置: - -- option.member:发布流人员的信息,必需。也就是 onStreamAdded 方法的 member -- option.stream:流信息,必需。也就是 onStreamAdded 方法的 stream -- option.subVideo: 是否订阅视频,必需 -- option.subAudio: 是否订阅音频,必需 -- option.videotag: 需要显示流的 video 标签,必需 - -#### 8.2 监听 onStreamRemoved 方法 -场景:当远端流被移除时(例如远端用户调用了 Stream.unpublish), 停止订阅该流并移除它的画面。 - -``` -emedia.mgr.onStreamRemoved = function(member, stream) { - // member:发布流人员的信息、stream:流信息 - emedia.mgr.unsubscribe(stream) // 停止订阅流 - removeView(stream.id) // 移除video标签,removeView方法需自己实现 -} -``` - -### 9. 退出会议 - -调用 emedia.mgr.exitConference 方法退出会议。 - -``` -emedia.mgr.exitConference() //无参数 -``` - -### 10. 会议常用监听函数 -:::tip -`强烈建议:` 在加入会议之前定义需要的 SDK 回调函数 -::: -``` -//有人加入会议 -emedia.mgr.onMemberJoined = function (member) { } // member: 加入会议成员信息 - -//有人退出会议 -emedia.mgr.onMemberExited = function (member) {} // member: 退出会议成员信息 - -//有媒体流添加 (自己发布的流也会触发 stream.located() == true ) -emedia.mgr.onStreamAdded = function (member, stream) { }; // member: 发布流的成员信息,stream:流信息 - -//有媒体流移除 -emedia.mgr.onStreamRemoved = function (member, stream) { } // member: 移除流的成员信息,stream:流信息 - -//自己角色变更 -emedia.mgr.onRoleChanged = role => {} // role: 变更后的角色 - -//会议退出;自己主动退 或 服务端主动关闭; -emedia.mgr.onConferenceExit = function (reason, failed) { - reason = (reason || 0); - switch (reason){ - case 0: - reason = "正常挂断"; - break; - case 1: - reason = "没响应"; - break; - case 2: - reason = "服务器拒绝"; - break; - case 3: - reason = "对方忙"; - break; - case 4: - reason = "失败,可能是网络或服务器拒绝"; - if(failed === -9527){ - reason = "失败,网络原因"; - } - if(failed === -500){ - reason = "Ticket失效"; - } - if(failed === -502){ - reason = "Ticket过期"; - } - if(failed === -504){ - reason = "链接已失效"; - } - if(failed === -508){ - reason = "会议无效"; - } - if(failed === -510){ - reason = "服务端限制"; - } - break; - case 5: - reason = "不支持"; - break; - case 10: - reason = "其他设备登录"; - break; - case 11: - reason = "会议关闭"; - break; - } -}; -//管理员变更 -emedia.mgr.onAdminChanged = admin => {} //admin 管理员信息 - -//监听弱网状态 -emedia.mgr.onNetworkWeak = streamId => {} //streamId 会议中的流 ID - -//监听断网状态 -emedia.mgr.onNetworkDisconnect = streamId => {} //streamId 会议中的流 ID -``` - -## 进阶功能 - -### 会议管理 - -#### **1. 创建会议并加入** - -这里的创建会议 不同于快速集成中的加入会议,这里的是属于另一套逻辑,建议使用快速集成中的加入会议 - -:::tip -如果只单纯的创建,没进行操作,则创建者不是会议的成员,没有相应的角色,不能进行其他操作。 -::: -##### **1.1 调用 emedia.mgr.createConference 方法创建会议** - -``` -let params = { - confrType, - password, - rec, - recMerge, - supportWechatMiniProgram - ... 其他参数 -} - -const confr = await emedia.mgr.createConference(params); -``` - -在 emedia.mgr.createConference 方法中,注意以下参数的设置: - -- confrType 会议类型 10:普通会议模式、11:大会议模式、12:直播模式。number 必需 -- password 会议密码 string 必需 -- rec 是否开启通话录制 boolean 非必需 -- recMerge 是否开启通话录制合并 boolean 非必需 -- supportWechatMiniProgram 会议是否支持小程序端 boolean 非必需, 默认不支持 - -创建会议成功后,返回的参数 confr 结构如下: - -``` -confr:{ - error: 0, - confrId: "LBJ13H9WJJEVJTGL1U1PIQ00C2", // 会议id - password: "xxxx", // 创建会议时设置的密码 - role: 7, // 在会议中的角色 这里因为是创建者,所以是 7: 管理员 - roleToken:"eyJ0eXAiOiJKV1QiLCJhbG *** f1gg_QJWxhs-jqmuFok", //创建者的token - type: 10 // 会议类型 -} -``` - -##### **1.2 调用 emedia.mgr.joinUsePassword 方法加入会议** - -``` -const join_result = await this.emedia.joinUsePassword(confrId, password) // 参数为 创建会议成功后返回的 confrId和password -``` - -加入会议成功后返回的结果,结构如下: - -``` -join_result: { - confrId: "LBJ13H9WJJEVJTGL1U1PIQ00C7", // 会议id - joinId: "LBJ13H9WJJEVJTGL1U1PIQ00C7M9", //创建会议时设置的密码 - password: "0.010568535799199363", // 会议成员在会议中的身份id(唯一) - role, // 在会议中的角色 创建者加入会议永远是 7: 管理员,其他人加入返回的是 3: 主播 - roleToken: "eyJ0eXAiOiJK *** FaXuMVlqPOTofRRdE", // 加入会议者的token - type: 10 // 会议类型 - } -``` - -#### **2. 开启录制、录制合并** - -##### **2.1 调用 emedia.mgr.createConference 创建会议时配置** - -``` -let params = { - ... - rec: true, - recMerge: true, - ... 其他参数 -} - -const confr = await emedia.mgr.createConference(params); -``` - -##### **2.2 调用 emedia.mgr.joinRoom 加入会议时配置** -:::tip -只有第一个加入会议的人,配置的才有效,参数需要放到 config 对象中。 -::: -``` -let params = { - ... 其他参数 - config: { - rec: true, - recMerge: true - } -} - -const confr = await emedia.mgr.createConference(params); -``` - -- rec: 是否开启录制,默认 false -- recMerge: 是否开启录制合并,默认false - -#### **3. 邀请成员加入会议** - -``` -SDK 不提供邀请接口。邀请的形式,完全可以由用户自行定义,可以是条文本消息,也可以是个控制消息等等。SDK 不做限制。实现方式可以参考官方 demo,通过群组消息邀请,具体代码 可查询 demo/src/components/webrtc/AddAVMemberModal.js 中的 70-89 行。 -``` - -##### **3.1 成员收到邀请加入会议** - -解析出邀请消息中带的 confrId 和 password ,调用 **emedia.mgr.joinUsePassword** 加入会议 - -#### **4. 管理员销毁会议** - -调用 emedia.mgr.destroyConference 方法, **注意:只有管理员有权限,其他角色调用不生效** - -``` -await emedia.mgr.destroyConference(confrId); //confrId: 会议Id -``` - -其他人会收到会议结束的回调。 - -``` -emedia.mgr.onConferenceExit = reason => {} // reason:退出会议的原因,因为会议被销毁了,所以这里应为 11: "会议关闭" -``` - -#### **5. 设置会议人数限制** - -##### **5.1 在 emedia.mgr.joinRoom 方法中设置** -只有第一个加入房间的人员(也就是管理员),设置的才能生效 - -``` -var params = { - ... 其他参数, - config:{ // 在 config 中指定字段 - maxTalkerCount:3, - maxAudienceCount:100, - maxVideoCount:2, - maxPubDesktopCount: 1 - } -} - -const user_room = await emedia.mgr.joinRoom(params); -``` - -##### **5.2 在 emedia.mgr.createConference(创建会议) 方法中设置** - -``` -var params = { - ... 其他参数, - maxTalkerCount:3 - maxVideoCount:2 - maxAudienceCount:100 - maxPubDesktopCount: 1 - -} -const confr = await emedia.mgr.createConference(params); -``` - -以上设置会议参数的注意事项如下: - -- maxTalkerCount:自定义会议最大主播人数,默认 100 -- maxAudienceCount:自定义会议最大观众数 默认 600 -- maxVideoCount:自定义会议最大视频数, 默认 9 -- maxPubDesktopCount: 自定义会议共享屏幕最大数 默认 2 - -#### **6. 设置会议昵称** - -在 emedia.mgr.joinRoom 方法中设置 - -``` -var params = { - ... 其他参数, - config:{ - ... 其他参数, - nickName: xxx, // string - } -} -const user_room = await emedia.mgr.joinRoom(params); -``` - -#### **7. 获取会议信息** - -调用 **emedia.mgr.selectConfr** 方法获取会议信息 - -``` -const confr_info = await emedia.mgr.selectConfr(confrId, password); // confrId:会议id、password:会议密码 -// 返回的参数 confr_info 结构如下: -confr_info: { - confr: { - id: "LBJ13H05522QATGIJKXUF800C45639", // 会议id - type: 10, // 会议类型 - memTotal: 1, // 会议中总人数 主播和观众 - audienceTotal: 0, // 观众人数 - talkers: ["018ae39 *** 663282d7495"] // 主播的memName集合 - } - error: 0 -} -``` - -#### **8. CDN合流推流** - -CDN推流是指将会议画面,合并到一张画布推送到远程CDN,其他人可以从CDN拉流而不用加入会议。 - -##### **8.1 开启CDN推流** - -CDN推流参数 **liveCfg为必需** 结构如下: - -``` -let liveCfg = { - cdn:'', //推流地址、字符串;必需 - layoutStyle: 'GRID' | 'CUSTOM', // 格子显示 | 自定义,必需 - canvas :{// canvas 参数在 layoutStyle == 'CUSTOM' 必填 - bgclr : 0x980000,//背景色 980000 为 十六进制色值 - w : 640, //宽度 - h : 480, //高度 - fps: 20, //输出帧率 - bps: 1200000, //输出码率 - codec: "H264" //视频编码,现在必须是H264 - } -} -``` - -**1.创建会议时指定 CDN推流** - -``` -let option = { - ... - liveCfg // 创建CDN推流参数 -} -emedia.mgr.createConference(option) -``` - -**2.加入房间时 指定CDN推流** - -``` -// 只有第一个加入房间的人才能创建 CDN、以后加入的人指定CDN也无效 -let params = { - config:{ - ... - liveCfg // 创建CDN推流参数 - } -} -emedia.mgr.joinRoom(params); -``` - -##### **8.2 多路推流** - -通过 **emedia.mgr.addLive** 方法指定一路推流CDN,需要几路CDN,就调用几次方法 -**注意:只有管理员,可创建 CDN** - -``` -// confrId: 会议id, 必需 -// liveCfg: cdn 配置,必需 -media.mgr.addLive(confrId, liveCfg); -``` - -##### **8.3 更新CDN布局** - -``` -// 只有管理员才能 更新布局。更新布局会 将layoutStyle 变为 CUSTOM 而且不可逆 -emedia.mgr.updateLiveLayout(confrId, liveId, regions) - -// confrId 会议id 必需 -// liveId 推流CDN id, 必需 可通过 emedia.config.liveCfgs 获取 Array - -regions:[ // 希望定义视频流 显示的配置集合 - { - "sid": stream_id,//视频流的id - "x": 320,//距离 x 轴的距离 Number - "y": 240,//距离 y 轴的距离 Number - "w": 960,//宽度 Number - "h": 720,//高度 Number - "style": "fill" | "AspectFit" //视频显示模式 fill:铺满、AspectFit:原比例显示 - }, - .... 其他视频流配置(数组有几个项,就显示几个视频流) -] -``` - -##### **8.4 删除CDN** - -``` -// 只有管理员可操作 -//confrId 会议id 必需 -// liveId 推流CDN id, 必需 可通过 emedia.config.liveCfgs 获取 Array -emedia.mgr.deleteLive(confrId, liveId) -``` - - -#### **9. 取日志** - -在浏览器控制台,输入 **emedia.fileReport** ,敲下回车键会下载下一份日志文件 - -``` -emedia.fileReport() //无参数 -``` - -#### **10. 会议属性** - -``` -// 用来自定义一些属性,广播给会议中的成员 - // 有人设置会议属性,所有的成员都能收到 - let options = { - key:username, - val:'request_tobe_speaker' - } - // a. 设置会议属性 - emedia.mgr.setConferenceAttrs(options) - // b. 删除会议属性 - emedia.mgr.deleteConferenceAttrs(options) - // c. 会议属性变更回调 - emedia.mgr.onConfrAttrsUpdated = attrs => {} //attrs 会议属性集合 Array -``` - -#### **11. 私有部署** - -私有部署设置方法参见[私有云sdk集成配置](../im/uc_Web_private.md)。 - -### 音视频管理 - -#### **1. 设置通话参数** - -发布本地媒体流时,可指定音视频的码率和分辨率非必需。 **共享桌面不可指定** - -``` -var constaints = { - audio: {bitrate: 100},// 指定音频码率 - video: { - width: { // 指定视频分辨率宽度 - exact: 1280 - }, - height: { // 指定视频分辨率高度 - exact: 720 - }, - bitrate: 200,// 指定视频码率 - } -} -emedia.mgr.publish(constaints) -``` - -#### **2. 指定设备打开音视频** - -``` -const devices = await emedia.mgr.mediaDevices(); //获取设备列表 - - // 设备信息 - device: Object { - deviceId: "529a6fe76467d****9498ab22f5f362cd" // 设备ID - groupId: "2b74c9b9ab99*****d513fbabc1e86b3c5d99f7f8a0c16" - kind: "audioinput" | audiooutput | videoinput | videooutput // 设备类型 - label: "Internal Microphone (Built-in)" - } - constraints: { // 选择设备, 然后指定设备(只需要传入设备信息中的deviceId属性,为String类型,其他的属性在推流时暂时用不到) - audio: {deviceId: deviceId ? {exact: deviceId} : undefined}, //判断如果deviceId存在那么就传入对象。 - video: {deviceId: deviceId ? {exact: deviceId} : undefined} - }, - -const stream = await emedia.mgr.publish(constraints) // 推流 -``` - -#### **3. 停止发布流** - -调用 **emedia.mgr.unpublish** 方法停止自己已经发布的流。 - -``` -emedia.mgr.unpublish(pushedStream); // pushedStream:自己发布的流 -``` - -会议中人员(包括自己)会收到 流被移除的回调函数 **emedia.mgr.onStreamRemoved**。 - -``` -emedia.mgr.onStreamRemoved = function (member, stream) { - // member: 停止发布流人员信息 - // stream:流的信息,stream.located() == true 代表是自己的流,false则为其他人的流 -}; -``` - -#### **4. 停止订阅流** - -调用 **emedia.mgr.unsubscribe** 方法停止订阅别人的流。 - -``` -emedia.mgr.unsubscribe(stream); // stream:已经订阅的流 -``` - -#### **5. 通话过程中音视频控制** - -##### **5.1 打开/关闭自己的视频** - -``` -const res_stream = await emedia.mgr.pauseVideo(own_stream) //关闭视频 -const res_stream = await emedia.mgr.resumeVideo(own_stream) //开启视频 -``` - -##### **5.2 打开/关闭自己的音频** - -``` -const res_stream = await emedia.mgr.pauseAudio(own_stream) // 关闭音频 -const res_stream = await emedia.mgr.resumeAudio(own_stream) // 开启音频 -执行开启/关闭音视频方法时, -* own_stream:自己已经发布的媒体流(不能是桌面流) -* res_stream:设置音视频成功后返回的流对象 -``` - -**执行上述操作后,会议中其他人员会收到流变化的回调 emedia.mgr.onMediaChanaged**
-emedia.mgr.onMediaChanaged 应该在流变化之前监听。 - -``` -var videoTag = document.getElementById('#xxx') // 获取 video 标签 -emedia.mgr.onMediaChanaged(videoTag, function(constaints, stream) { - -}); -// 回调函数中 constaints、stream -constaints: { - audio: true // true: 开启了音频,false:关闭了音频 - video: true // true: 开启了视频,false:关闭了视频 -} -stream:媒体流变化后的 stream 对象 -``` - -##### **5.3 切换摄像头** - -``` -// 随机切换摄像头 -emedia.mgr.changeCamera(confrId).then(function(){ - // 无参数 -}).catch(function(){ - -}) -// 切换手机前后摄像头 -emedia.mgr.switchMobileCamera(confrId).then(function(){ - // 无参数 -}).catch(function(){ - -}) -``` - -#### **6. 音视频网络状态监听** - -:::tip -建议进入会议之前绑定网络状态监听函数 -::: -``` -//监听弱网状态 -emedia.mgr.onNetworkWeak = streamId => {} //streamId 会议中的流 ID - -//监听断网状态 -emedia.mgr.onNetworkDisconnect = streamId => {} //streamId 会议中的流 ID -``` - -#### 7. 监听谁在说话 - -这是监听的video标签。 -:::tip -建议:在将video标签与stream绑定时(emedia.mgr.streamBindVideo), 调用 emedia.mgr.onSoundChanaged 方法。 -::: -``` -var videoTag = getElementById('#xxx'); -emedia.mgr.onSoundChanaged(videoTag,, function (meterData) {}); - -// 返回的参数 meterData 结构如下: -meterData: { - instant: 0.26280892641627845 // instant 大约每50毫秒变化一次, 小于1的浮点数 - slow: 0.06802768487276245 // slow大约是一秒钟内的平均音量,小于1的浮点数 - clip: 0 -} -``` - -#### **8. 共享桌面** - -仅支持PC Chrome浏览器或electron平台。
- -**>>SDK 3.2.1 版本 文档** -##### **8.1 无插件共享** - -需要 SDK 3.2.1 版本开始支持,并且 Chrome 72 或以上版本。 - -``` -const screenStream = await emedia.mgr.shareDesktopWithAudio({ - confrId: confrId, // 会议ID, 必须 - audio: false, -}); -``` - -##### **8.2 有插件共享** - -``` -//在 sdk 内部会自动判断,浏览器是否含有 navigator.mediaDevices.getDisplayMedia API, -//如果没有,将会跳转至 使用 插件的 API,如果没有安装插件将给出提示 -``` - -##### **8.3 分享音频** - -``` -//1. 版本起支持在 Windows 平台的 Chrome 浏览器 74 及以上版本同时共享屏幕和本地播放的背景音, -//2. 将 audio 设置为 true 即可 -``` - -##### **8.4 Electron 屏幕共享** - -``` -//1. sdk 内部会判断是否是在 electron 平台内 -//2. electron 平台 会默认选择 第一个屏幕 -//3. 如果需要自定义选择框,请重新定义 emedia.chooseElectronDesktopMedia 方法 -emedia.chooseElectronDesktopMedia = function(sources, accessApproved, accessDenied){ - sources // Array 获取到的屏幕列表 - accessApproved(source)// 选中的 source 对象,进行分享 - accessDenied()// 取消分享,关闭自定义框需要调用此方法 -} -``` - -##### **8.5 停止共享桌面** - -``` -停止共享桌面,执行 取消流的发布 emedia.mgr.unpublish(screenStream) -``` - -**>>SDK 3.2.1 之前版本 文档** - -``` -/** - * let params = { - * videoConstaints, - * withAudio, - * videoTag, - * ext, - * confrId, - * stopSharedCallback - * } - */ - -/** - * videoConstaints {screenOptions: ['screen', 'window', 'tab']} or true - * withAudio: true 携带语音,false不携带 如携带语音,需自己调用关闭流,不会执行 stopSharedCallback 回调 - * ext 用户自定义扩展,其他成员可以看到这个字段 - * stopSharedCallback 共享插件 点击【停止共享】的回调函数,做相应的处理(比如删除流...) - */ -emedia.mgr.shareDesktopWithAudio(params).then(function(pushedStream){ - //stream 对象 -}).catch(function(error){ - -}); - -//electron平台 默认选择第一个屏幕,如果需要选择其他,需要重写方法 -emedia.chooseElectronDesktopMedia = function(sources, accessApproved){ - var firstSources = sources[0]; - accessApproved(firstSources); -} -``` - -**注意:** 在chrome浏览器中使用时,需要从[chrome store](https://chrome.google.com/webstore/detail/rtc-share-desktop/ccahbcjalpomijfpjemdgpnbogofnlgl) 或者从[环信服务器](https://download-sdk.oss-cn-beijing.aliyuncs.com/rtc_desktop_share.zip) 中下载插件,解压后在chrome浏览器中输入 chrome://extensions/,选择“Load unpacked” 选择解压后的文件夹中的1.0_0文件夹,加载插件。 - -### 角色管理 - -可通过 emedia.mgr.Role 获取会议中的角色类型。 - -``` -emedia.mgr.Role: { - ADMIN: 7, // 会议管理员: 能创建会议,销毁会议,移除会议成员,切换其他成员的角色 - TALKER: 3, // 主播: 能上传自己的音视频,能观看收听其他主播的音视频,即能发布流和订阅流) - AUDIENCE: 1 // 观众: 只能观看收听音视频,即只能订阅流 -}; -// 可在会议中定义更加语义化的判断: -if(member.role == emedia.mgr.Role.ADMIN){ } -等同于 -if(member.role == 7){ } -在以下申请主播和申请管理员的过程,请注意: -1.从发起申请到管理员回复(同意或拒绝),是一个完整的过程 -2.因此可以认为:当管理员收到请求,会收到两个函数参数(同意和拒绝),用于管理员调用 -3.当管理员处理了请求(同意或拒绝),申请者会收到处理结果(同意或拒绝),未处理则不会收到 -``` - -**以下方法非回调函数均为异步函数** - -``` -try { - await emedia.mgr.xxx; - } catch(error) { } - -// 以下出现的参数注解 - confrId: 会议id - memberId: 与会人员的id,member 中的id - nickName: 昵称 -``` - -#### **1. 观众申请成为主播** - -观众通过调用 **emedia.mgr.requestToTalker** 方法申请主播。 - -``` -// 观众上麦申请方法 -emedia.mgr.requestToTalker(confrId) - -// 管理员收到上麦申请的回调 (主播不会收到这个回调) -emedia.mgr.onRequestToTalker = function(applicat, agreeCallback, refuseCallback) { - /* - * applicat { memberId, nickName } object 申请者信息 - * agreeCallback 管理员同意的回调 示例:agreeCallback(memberId) memberId 申请者 id 必需 - * refuseCallback 管理员拒绝的回调 示例:refuseCallback(memberId) memberId 申请者 id必需 - */ -} - -// 观众收到 上麦申请的回复 -emedia.mgr.onRequestToTalkerReply = function(result) { - // result 0: 同意 1: 拒绝 -} -``` - -#### **2. 主播申请成为管理员** - -``` -// 主播申请管理员 -emedia.mgr.requestToAdmin(confrId); - -//管理员收到申请管理员的回调 (主播不会收到这个回调) -emedia.mgr.onRequestToAdmin = function(applicat, agreeCallback, refuseCallback) { - /* - * applicat { memberId, nickName } object 申请者信息 - * agreeCallback 管理员同意的回调 示例:agreeCallback(memberId) memberId 申请者 id 必需 - * refuseCallback 管理员拒绝的回调 示例:refuseCallback(memberId) memberId 申请者 id必需 - */ -} - -// 主播收到 申请管理员的回复 -emedia.mgr.onRequestToAdminReply = function(result) { - // result 0: 同意 1: 拒绝 -} -``` - -#### **3. 授权** - -**只有管理员有权限授权** -调用方法改变与会人员的角色(可升可降)。 - -``` -var option = { - confr:, //会议对象 Object 必需 - memberNames: // 被授权人员的memberName集合(可同时给多人授权)Array - role: // 需要授权成什么角色 Number 必需 -} -emedia.mgr.grantRole(option.confr, option.memberNames, option.role) -``` - -#### **4. 角色降级** - -:::tip -注意:只能角色降级 从管理员到主播、从主播到观众、从管理员到观众,不可逆向操作 -::: -与会成员调用 **emedia.mgr.degradeRole** 方法就会角色降级。 - -``` -//[memName] 与会人员的memName、 toRole 想要 达到的角色 -emedia.mgr.degradeRole(confrId, [memName], toRole); -``` - -#### **5. 管理员踢人** - -:::tip -只有管理员可踢人 -::: -``` -// confr: 会议对象,必需 Object -// memberNames: 被踢掉人员的 memberName, 必需 Array -emedia.mgr.kickMembersById(confr, memberNames) -``` - -#### **6. 管理员执行全体静音/取消全体静音** - -:::tip -只有管理员可操作,其他角色操作不生效,管理员不会被静音 -::: - -##### **6.1 管理员静音全体** - -``` -await emedia.mgr.muteAll(confrId); // confrId: 会议Id - -// 主播收到回调 -emedia.mgr.onMuteAll = () => { - // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.pauseAudio(own_stream)) -} -``` - -##### **6.2 取消全体静音** - -``` -await emedia.mgr.unmuteAll(confrId); // confrId: 会议Id - -//主播收到回调 -emedia.mgr.onUnMuteAll = () => { - // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.resumeAudio(own_stream)) -} -``` - -#### **7. 管理员指定成员静音/取消指定成员静音** - -:::tip -只有管理员可操作,其他角色操作不生效 -::: - -##### **7.1 管理员指定成员静音** - -``` -emedia.mgr.muteBymemberId(confrId, memberId);// memberId 被静音主播的memberId - -// 单个主播被管理员静音的回调(只他自己收到回调) -emedia.mgr.onMuted = () => { - // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.pauseAudio(own_stream)) -} -``` - -##### **7.2 管理员取消指定成员静音** - -``` -emedia.mgr.unmuteBymemberId(confrId, memberId);// memberId 被取消静音主播的memberId - -// 单个主播被管理员取消静音的回调 (只他自己收到回调) -emedia.mgr.onUnmuted = () => { - // 在收到回调后,需要在程序中执行关闭麦克风的逻辑(emedia.mgr.resumeAudio(own_stream)) -} -``` - -#### **8. 本身角色变更回调** - -如果想要变更自己的角色,需要向管理员申请,管理员同意后,角色就会变更 -``` -emedia.mgr.onRoleChanged = function (role) { - // role: 变更后的角色 -}; -``` - -#### 9. 管理员变更回调 - -当会议中的管理员变更时,与会人员都会收到这个回调 - -``` -emedia.mgr.onAdminChanged = admin => {} //admin 管理员信息 -``` - -### 其他接口 - -#### **抓取 video图像,并保存** - -``` -emedia.mgr.captureVideo(videoTag, true, filename) -等价于 -emedia.mgr.triggerCaptureVideo(videoTag, true, filename); -``` - -#### **控制远程视频(手机端)定格** - -``` -emedia.mgr.freezeFrameRemote(stream); -等价于 -emedia.mgr.triggerFreezeFrameRemote(videoTag).catch(function(){ - alert("定格失败"); -}); -``` - -#### **控制手机闪光灯打开/关闭** - -``` -/** - * torch true 打开,否则 关闭; 可缺失 - */ -emedia.mgr.torchRemote(stream, torch); -等价于 -emedia.mgr.triggerTorchRemote(videoTag, torch).catch(function(){ - alert("Torch失败"); -}); -``` - -#### **控制手机截屏** - -``` -emedia.mgr.capturePictureRemote(stream); -等价于 -emedia.mgr.triggerCapturePictureRemote(videoTag).catch(function(){ - alert("抓图失败"); -}); -``` - -#### **控制手机摄像头放大缩小** - -``` -emedia.mgr.zoomRemote(stream, multiples); -等价于 -emedia.mgr.triggerZoomRemote(videoTag, multiples).catch(function(){ - alert("zoom失败"); -}); -``` - -#### **控制手机摄像头聚焦曝光** - -``` -/** - * clickEvent 为 videoTag的点击事件。通过event计算点击的坐标传给sdk进行控制 - * - */ -emedia.mgr.focusExpoRemote(stream, videoTag, clickEvent).catch(function(){ - alert("focusExpoRemote失败"); -}); -等价于 -/** - * event string. 如点击 “click” - * fail 失败回调;success成功回调 - */ -emedia.mgr.onFocusExpoRemoteWhenClickVideo(videoTag, event, fail, success); -``` - -#### **取消在videoTag上的事件** - -``` -//用来对onFocusExpoRemoteWhenClickVideo的撤销 -emedia.mgr.offEventAtTag(videoTag); -//视频收发数据统计 -emedia.mgr.onMediaTransmission(videoTag, function notify(trackId, type, subtype, data) { - var $iceStatsShow = $div.find("#iceStatsShow"); - var $em = $iceStatsShow.find("#"+subtype); - if(!$em.length){ - $em = $("").appendTo($iceStatsShow).attr("id", subtype); - } - - $em.text(subtype + ":" + (data*8/1000).toFixed(2)); -}); -//连接状态变化 -emedia.mgr.onIceStateChanged(videoTag, function (state) { - console.log(state); -}); -``` - -#### **支持会议属性** - -``` -// 用来自定义一些属性,广播给会议中的成员 - // 有人设置会议属性,所有的成员都能收到 - let options = { - key:username, - val:'request_tobe_speaker' - } - - // a. 设置会议属性 - emedia.mgr.setConferenceAttrs(options) - // b. 删除会议属性 - emedia.mgr.deleteConferenceAttrs(options) - // c. 会议属性变更回调 - emedia.mgr.onConfrAttrsUpdated = attrs => {} //attrs 会议属性集合 Array -``` - -## 客户端API - -多人音视频通话的API包括以下接口 - -- createConference: 创建会议 -- destroyConference:销毁会议 -- getConferenceInfo:获取会议信息 -- publish:发布媒体流 -- unpublish:取消发布媒体流 -- grantRole:改变角色 -- joinConference:通过password 加入会议 -- kickMembersById:通过id踢出成员 - -**以下方法均为 emedia.mgr 对象的属性方法:** - -| 方法 | | -| :----------------------------------------------------------- | --------------------- | -| [createConference](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#createConference) | 创建会议 | -| [destroyConference](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#destroyConference) | 销毁会议 | -| [getConferenceInfo](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#getConferenceInfo) | 获取会议信息 | -| [grantRole](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#grantRole) | 改变角色 | -| [joinConference](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#joinConference) | 通过password 加入会议 | -| [kickMembersById](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#kickMembersById) | 通过id踢出成员 | -| [publish](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#publish) | 发布媒体流 | -| [unpublish](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#unpublish) | 取消发布媒体流 | \ No newline at end of file diff --git a/docs/private/media/one2one_android.md b/docs/private/media/one2one_android.md deleted file mode 100644 index dbfa3035..00000000 --- a/docs/private/media/one2one_android.md +++ /dev/null @@ -1,698 +0,0 @@ -# Android集成1对1通话 - -## 跑通Demo - -### 1. 示例代码 - -- [下载 Android SDK + Demo 代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/easemob-sdk-3.7.6.3.zip) -- [体验Demo](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/app-prod-release.apk) - -或进入环信[客户端下载](common_clientsdk.html#音视频sdk下载)页面,选择Android SDK + Demo下载 - -### 2. 前提条件 - -- Android Studio 3.0 或以上版本 -- Android SDK API 等级 19 或以上 -- Android 4.4 或以上版本的设备 - -### 3. 运行Demo - -#### 3.1 Demo代码目录简介 - -![img](/images/privitization/android_demo.png) -源码目录如上所示,主要目录如以下介绍: -- widget是有关所有Activity的具体实现 -- permission是有关运行是有关动态权限的获取的封装 -- untils是有关工具类的封装 -- DemoHelper和DemoApplication类是全局单例,用来做一些初始化 - -#### 3.2 工程设置,SDK导入 - -选择如下任意一种方式将环信语音SDK集成到你的项目中: - -**方法一:使用 JCenter 自动集成** - -在项目的 /app/build.gradle 文件中,添加如下行 - -``` -dependencies { - ... - // x.x.x 请填写具体版本号,如:3.7.0 - // 可通过 SDK 发版说明取得最新版本号 - api 'com.hyphenate:hyphenate-sdk:x.x.x' - } -``` - -**方法二:手动复制 SDK 文件** - -前往SDK载页面,获取最新版的环信音视频SDK,然后解压;
-将SDK包内libs路径下的如下文件,拷贝到你的项目路径下:
-- hyphenatechat_3.7.0.jar 文件 /app/libs/
-- arm-v8a 文件夹 /app/src/main/jniLibs/
-- armeabi-v7a 文件夹 /app/src/main/jniLibs/
-- x86文件夹 /app/src/main/jniLibs/
-- x86_64文件夹 /app/src/main/jniLibs/
- -#### 3.3 运行项目 - -用Android Studio 运行examples\ChatDemoUI3.0 或者 连接Android 手机,直接运行即可。
-需要注意的的是项目build.gradle中的,配置成和自己Android Studio相匹配的 gradle 版本,如下所示 - -``` -dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' - } -``` - -## 快速集成 - -### 1. 环信后台注册AppKey - -环信为管理者与开发者提供了方便易用的App工作台– **环信管理后台**。
-通过环信管理后台可以完成应用创建、服务配置、企业信息修改基础功能;同时,管理后台也提供了发送消息、用户管理、群组管理、聊天室管理和数据统计等管理监控功能。
-在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。 - -### 2. 创建项目 - -- 打开 Android Studio点击Start a new Android Studio project;
-- 在Select a Project Template界面,选择 Phone and Tablet > Empty Activity;
-- 点击 Next;
-- 在 Configure Your Project界面,依次填入以下内容:Name:你的Android项目名称,如 HelloWrold;
-- Package name:你的项目包的名称,如 package.easemob.helloworld;
-- Save location:项目的存储路径;
-- Language:项目的编程语言,如 Java;
-- Minimum API level:项目的最低 API 等级;(**注意本SDK 支持API 19或以上**)
-- 点击 Finish;
-- 根据屏幕提示,安装可能需要的插件;
-上述步骤使用 Android Studio 3.6.2 示例,你也可以直接参考Android Studio 官网文档创建首个应用。 - -### 3. 导入SDK到工程 - -新建项目完成以后,可以选择以上任何一种导入SDK的方法,把环信音视频SDK集成到你的项目里面,参考[导入SDK](#_3-2-工程设置-sdk导入)。 - -### 4. 添加权限 - -根据场景需要,在 /app/src/main/AndroidManifest.xml 文件中添加如下行,获取相应的设备权限;
-在清单文件 AndroidManifest.xml 里加入以下权限,以及写上你注册的 AppKey;
-权限配置(实际开发中可能需要更多的权限,可参考 Demo); - -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ... - -``` -:::tip -在创建应用后,获取EASEMOB_APPKEY对应的value -::: - - -``` - 申请 AppKey并进行相关配置,环信Demo中AppKey为easemob-demo#chatdemoui; -``` - -### 5. 打包混淆 - -在 app/proguard-rules.pro 文件中添加如下行,防止混淆环信SDK的代码。 - -``` --keep class com.hyphenate.** {*;} - -dontwarn com.hyphenate.** - //3.6.8版本之后移除apache,无需再添加 - -keep class internal.org.apache.http.entity.** {*;} - //如果使用了实时音视频功能 - -keep class com.superrtc.** {*;} - -dontwarn com.superrtc.** -``` - -### 6. 创建UI - -根据场景需要,为你的项目创建语音通话的用户界面。若已有界面,可以直接查看导入类;
-可以参考 Demo SDK示例项目的 [em_activity_voice_call.xml](https://github.com/easemob/sdkdemoapp3.0_android/blob/sdk3.0/app/src/main/res/layout/em_activity_voice_call.xml) 文件中的代码。 - -### 7. 初始化SDK - -初始化环信SDK,可以参考使用DemoHelper中的init方法,可设置私有部署地址或者是否允许日志输出,调用如下: - -``` -public void init(Context context) { - EMOptions options = initChatOptions(context); - appContext = context; - //可设置私有服务地址 - options.setRestServer("a.b.c"); - options.setIMServer("1.2.3.4"); - options.setImPort(8081); - EMClient.getInstance().init(context, options); - //打开日志输出 - EMCallManager manager = EMClient.getInstance().callManager(); - EMClient.getInstance().setDebugMode(true); -} -``` - -### 8. 环信ID注册登录 - -在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/android/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。 - -若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/android/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7) - -### 9. 音视频功能初始化 - -账号登录成功后,需要进行音视频通话功能的初始化,设置监听类;
-主要有监听呼入通话和监听呼入通话状态;
- -通过注册相应action的BroadcastReceiver来监听呼叫过来的通话,接到广播后开发者可以调起APP里的通话Activity;
-具体调用如下代码所示: - -``` -protected void setGlobalListeners(){ - IntentFilter callFilter = new IntentFilter(EMClient.getInstance(). - callManager().getIncomingCallBroadcastAction()); - if(callReceiver == null){ - callReceiver = new CallReceiver(); - } - appContext.registerReceiver(callReceiver, callFilter); - } - private class CallReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - // 拨打方username String from = intent.getStringExtra("from"); - // call type String type = intent.getStringExtra("type"); //跳转到通话页面 - } -} -``` - - -通过addCallStateChangeListener监听通话状态,在onCreate里面增加这个监听,包括网络连接状态呼入电话状态,听电话状态等都可以在这监听。
-:::tip -在收到 DISCONNECTED回调时才能finish当前页面保证通话所占用的资源都释放完,然后开始下一个通话; -::: - -调用如下代码所示: - -``` -void addCallStateListener() { - callStateListener = new EMCallStateChangeListener() { - - @Override - public void EMCallStateChangeListener(CallState callState, final CallError error) { - // Message msg = handler.obtainMessage(); - EMLog.d("EMCallManager", "onCallStateChanged:" + callState); - switch (callState) { - case CONNECTING: //正在连接 - break; - case CONNECTED: //已经连接 等等状态 - break; - ..... - } - - //增加监听 - EMClient.getInstance().callManager().addCallStateChangeListener(callStateListener); - } -``` - -### 10. 发起通话请求 - -当A方给B方进行视频通话时候,A可以调用下面三个方法中的任意一个来发起通话,后边两个是多参的。 - -``` -try {//单参数 - EMClient.getInstance().callManager().makeVideoCall(username); - } catch (EMServiceNotReadyException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - try {//多参数 - EMClient.getInstance().callManager().makeVideoCall(username,"ext 扩展内容"); - } catch (EMServiceNotReadyException e) { - / / TODO Auto-generated catch block - e.printStackTrace(); - } - try {//多参数, recordOnServer:是否在服务器端录制该通话, mergeStream:服务器端录制时是否合并流 - EMClient.getInstance().callManager().makeVideoCall(username,"ext 扩展内容", recordOnServer, mergeStream); - } catch (EMServiceNotReadyException e) { - // TODO Auto-generated catch block - e.printStackTrace(); -} -``` - -### 11. 接听通话 - -当A方给B方进行视频通话时候,B可以调用下面的方法,去接通视频,B视频电话以后,A会收到上面已经注册好的EMCallStateChangeListener回调里边的 ACCEPTED 状态,表示B已经接通视频。 - -``` -try { -EMClient.getInstance().callManager().answerCall(); -} catch (EMNoActiveCallException e) { -// TODO Auto-generated catch block -e.printStackTrace(); -} catch (EMNetworkUnconnectedException e) { -// TODO Auto-generated catch block -e.printStackTrace(); -} -``` - -### 12. 拒绝通话 - -当A方给B方进行通话时候,B可以调用下面的方法拒绝通话,B拒绝以后,A会收到上面已经注册好的EMCallStateChangeListener 回调里边的 DISCONNECTED 状态,具体原因为 CallError 中的 REJECTED 表示B拒绝视频。 - -``` -try { - EMClient.getInstance().callManager().rejectCall(); - -} catch (EMNoActiveCallException e) { - - // TODO Auto-generated catch block - - e.printStackTrace(); - -} -``` - -### 13. 结束通话 - -A方给B方进行语音通话时候,通话过程中任意一方可以调用下面的方法去挂断电话,另一方会收到已经注册好的EMCallStateChangeListener回调里边的DISCONNECTED状态,
-具体原因为 CallError 中的 ERROR_NONE 表示对方正常挂断电话。 - -``` -EMClient.getInstance().callManager().endCall(); -``` - -## 进阶功能 - -### 取日志 - -SDK会写入日志文件到本地,日志文件路径如下:sdcard/Android/data/(自己App包名)/(appkey)/core_log/easemob.log。
-以Demo为例,通过adb命令获取本地的log: - -``` -adb pull /sdcard/Android/data/com.hyphenate.chatuidemo/easemob-demo#chatdemoui/core_log/easemob.log -``` - -### 通话中音视频控制 - -#### 音频管理 - -在视频通话过程中可以暂停和恢复语音传输,具体方法如下:
-A和B通话,当A停止或恢复语音传输时候,B会收到已经注册好的EMCallStateChangeListener回调里边的VOICE_PAUSE或者VOICE_RESUME状态,表示A的音频传输暂停或者恢复,
-方法如下所示: - -``` -暂停音频数据传输: -EMClient.getInstance().callManager().pauseVoiceTransfer(); -恢复音频数据传输: -EMClient.getInstance().callManager().resumeVoiceTransfer(); -``` - -#### 视频管理 - -在语音通话过程中可以暂停和恢复视频传输,具体方法如下:
-A和B通话,当A停止或恢复视频传输时候,B会收到已经注册好的 EMCallStateChangeListener回调里边的VIDEO_PAUSE 或者 VIDEO_RESUME 状态,表示A的音频传输暂停或者恢复。
-方法如下所示: - -``` -暂停视频数据传输: -EMClient.getInstance().callManager().pauseVideoTransfer(); -恢复视频数据传输: -EMClient.getInstance().callManager().resumeVideoTransfer(); -``` - -#### 切换摄像头 - -视频通话时如果有前置摄像头,默认使用前置的,提供切换 API 切换到后置或者前置摄像头。 - -``` -EMClient.getInstance().callManager().switchCamera(); -``` - -### 设置通话参数 - -#### 最大音频码率 - -通话之前,可以设置通话音频的最大音频码率,设置方法如下 -:::tip -设置最大音频比特率,取值范围 6 ~ 510。 -::: - - -``` -EMClient.getInstance().callManager().getCallOptions().setMaxAudioKbps(50); -``` - -#### 设置视频分辨率 - -可以通过以下方法设置本地视频通话分辨率 默认是(640, 480),例如设置720P分辨率。 - -``` -EMClient.getInstance().callManager().getCallOptions().setVideoResolution(1280, 720); -``` - -#### 设置通话最大帧率 - -可以通过以下方法设置本地通话最大帧率,SDK 最大支持(30),默认(20),例如以下设置为25。 - -``` -EMClient.getInstance().callManager().getCallOptions().setMaxVideoFrameRate(25); -``` - -#### 设置视频比特率 - -可以通过以下方法设置视频通话最大和最小比特率(可以不设置,SDK会根据手机分辨率和网络情况自动适配), -最大值默认800,最小值默认80 - -``` -EMClient.getInstance().callManager().getCallOptions().setMaxVideoKbps(800); -EMClient.getInstance().callManager().getCallOptions().setMinVideoKbps(80); -``` - -#### 设置流畅度或者清晰度优先 - -可以通过以下方法设置视频流畅度优先还是清晰度优先(true 为清晰度优先,false为流畅度优先)。 - -``` -EMClient.getInstance().callManager().getCallOptions().setClarityFirst(true); -``` - -### 离线推送 - -**场景描述**:A,B都开启离线推送后,当A呼叫B,而B离线时,B会收到推送消息,点击推送消息可以打开APP,进入通话页面(true推送,false不推送)。
-目前小米、魅族、OPPO、VIVO推送的主要实现集成在了环信 IM SDK 中,尽量提供给开发者最简单的集成三方推送的形式。
-Google FCM 和华为推送的实现仍在 Demo 层,需要开发者自己集成,详情请参考环信的 Google FCM 和华为的推送集成文档,有个集成, 关于第三方推送集成,大家可以参考:[设置推送](https://docs-im.easemob.com/im/android/push/thirdpartypush)。 - -``` -//开启离线推送 - EMClient.getInstance().callManager().getCallOptions().setIsSendPushIfOffline(true); -``` - -### 云端录制 - -呼叫方呼叫时可以指定是否开启服务器录制,如要录制, -使用以下方法呼叫(recordOnServer 是否在服务器端录制该通话 ; mergeStream 服务器端录制时是否合并流)。 - -``` -EMClient.getInstance().callManager().makeVoiceCall(username, "", recordOnServer , mergeStream); -``` - -### 通话统计数据 - -通话数据的数据统计功能, -可以从保存的会话callSession中获取到通话的实时码率、帧率、分辨率等数据。 - -### 弱网监测 - -语音通话中会实时监测通话网络状态,有变化时通过回调通知应用, -会收到已经注册好的 EMCallStateChangeListener中有关网络状态的回调,有以下几种状态。 - -``` -enum CallState{ - NETWORK_UNSTABLE("network_unstable"), //网络不稳定,丢包率较高的场景下提示 - NETWORK_NORMAL("network_normal"), //网络正常 - NETWORK_DISCONNECTED("network_disconnected"); //对方的视频流断开,一般是断网或者app被kill等 -}; -enum CallError{ - ERROR_TRANSPORT("error_transport"), - ERROR_UNAVAILABLE("error_unavailable"), - ERROR_NO_DATA("error_no_data"),//传输无数据 -}; -``` - -### 本地视频镜像显示 - -设置本地view预览是否开启镜像显示,前置摄像头默认为开启镜像。 - -``` -EMClient.getInstance().callManager().getCallOptions().setLocalVideoViewMirror(EMMirror.OFF); -``` - -### 变声/自定义音频 - -#### 开启外边音频输入 - -用户使用自定义音频数据时,需要配置外部输入音频数据的开关,以及音频采样率,通道数(当前通道数只支持1),开启方式如下(true 为开启,false为不开启)。 - -``` -EMClient.getInstance().callManager().getCallOptions().setExternalAudioParam(true, 44100,1); -``` - -#### 输入音频数据 - -音频数据采集可参考Demo中的ExternalAudioInputRecord.java类实现,音频数据的输入必须在会话接通后开始,否则会导致网络阻塞,影响通话质量。
-建议用户将音频数据采集的开始放在会话接通的回调及callDidAccept回调中。 - -``` -callStateListener = new EMCallStateChangeListener() { - - @Override - public void onCallStateChanged(CallState callState, final CallError error) { - case ACCEPTED: - //启动外部音频输入 - if(PreferenceManager.getInstance().isExternalAudioInputResolution()){ - ExternalAudioInputRecord.getInstance().startRecording(); - } - .... - break; - } -``` - -音频采集过程参考Demo中的ExternalAudioInputRecord类实现,音频采集过程开始后,在音频数据采集线程里调用外部输入音频数据接口,具体参考Demo中的实现。 - -``` -EMClient.getInstance().conferenceManager().inputExternalAudioData(byteBuffer.array(), byteBuffer.capacity()); -``` - -#### 停止音频输入 - -会话挂断时,停止音频采集及输入过程 - -``` -if(PreferenceManager.getInstance().isExternalAudioInputResolution()){ - ExternalAudioInputRecord.getInstance().stopRecording(); - } -``` - -### 美颜/自定义视频 - -如果用户需要自己采集特定的数据或者对于数据需要先进行一些处理,可以使用SDK的外部输入数据的方法进行。
-例如:如果想要使用美颜等功能,需要用户使用系统的摄像头,然后启动监听系统设备,获取到数据后进行处理,处理后再调用我们输入数据的api发布出去。
-使用自定义视频接口如下:开启外边视频输入;
-用户使用自定义视频数据时,需要配置外部输入数据数据的开关(true 为开启,false为不开启)。 - -``` -EMClient.getInstance().callManager().getCallOptions().setEnableExternalVideoData(true); -``` - -输入视频数据 - -然后就是自己获取视频数据,进行美颜等处理,循环调用以下方法输入数据就行了, -这个调用频率就相当于你的帧率,调用间隔可以自己进行控制,一般最大30帧/秒) -输入视频数据的方法如下: - -``` -/** - * - * 视频数据的格式是摄像头采集的格式即:NV21 420sp 自己手动传入时需要将自己处理的数据转为 yuv 格式输入 - */ - EMClient.getInstance().callManager().inputExternalVideoData(data, width, height, rotate); -``` - -### 视频水印 - -在Android系统可以将图片资源设置为视频流的水印。首先将图片资源转换为Bitmap对象, -然后设置WaterMarkOption中的属性,比如位置,分辨率及距离边缘的margin等。 - -``` -try { - InputStream in = this.getResources().getAssets().open("watermark.png"); - watermarkbitmap = BitmapFactory.decodeStream(in); -} catch (Exception e) { - e.printStackTrace(); -} -watermark = new WaterMarkOption(watermarkbitmap, 75, 25, WaterMarkPosition.TOP_RIGHT, 8, 8); -//设置水印 -EMClient.getInstance().callManager().setWaterMark(watermark); -``` - - -### 私有部署 - -私有部署设置方法参见[私有云 Android SDK集成配置](../im/uc_android_private.md)。 - -## 客户端API - -1V1音视频通话的API包括以下接口 - -- EMCallOptions 视频通话配置类 -- EMACallManager 视频通话的主要管理类,提供了语音通话的拨打、接听、挂断等接口 -- EMCallStateChangeListener 视频通话的监听回调类,实时语音通话相关的回调 -- EMCallSession 视频通话的会话实例接口类 -- EMVideoCallHelper 视频通话获取通话统计信息类 -- EMCallSurfaceView 视频通话UI显示视图类 -- EMWaterMarkOption 视频通话水印对象类 -- EMWaterMarkPosition 视频通话水印位置设置类 - -### EMCallOptions - -| 方法 | 描述 | -| :----------------------------------------------------------- | :-------------------------------------------- | -| [pingInterval](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#adcda2ab5ab431592ef906983c8a9df26) | 心跳时间间隔,单位秒,默认30s,最小10s | -| [setIsSendPushIfOffline](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a8f99a36fbbb6190a2f911d5e9d8ee331) | 被叫方不在线时,是否开启推送 | -| [setLocalVideoViewMirror](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a4cb1cfe6a11e21a99eb28df1c660c9da) | 是否开启镜像模式 | -| [setMaxAudioKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a90b11b4c40bbbc4757287efdb8312ec4) | 最大音频码率 | -| [setIsSendPushIfOffline](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a0acf32a7afc578f477a3dbb6272c93ae) | 是否开启外部音频输入 | -| [setAudioSampleRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#ae7725792786081e688e785c910f98e03) | 自定义音频数据的采样率,默认48000 | -| [setRotation](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a94d9a6abe6925507eac4451b31c460cf) | 设置视频旋转角度,启动前和视频通话中均可设置 | -| [setEnableExternalVideoData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#abd8146585edd2f4f38dcfdb8ae50f619) | 是否开启外部输入视频 | -| [setVideoResolution](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a10ffc50fd622524d2e07def0c9e602f9) | 设置传输视频分辨率 | -| [setMaxVideoKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a237df350c5e19dbb5f596b6d78e895fb) | 设置最大视频码率 | -| [setMinVideoKbps](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a7ab32f5b511ee467a727e943a08ff2a9) | 设置最小视频码率 | -| [setMaxVideoFrameRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a334a5bfb414903da4b919539eac4dde4) | 设置最大的视频帧率 | -| [setUse2channelsInput](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a334a5bfb414903da4b919539eac4dde4:~:text=setUse2channelsInput) | 是否开启双声道,当前只支持单通道,必须为false | -| [setClarityFirst](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallOptions.html#a334a5bfb414903da4b919539eac4dde4:~:text=void%20com.hyphenate.chat.EMCallOptions.setClarityFirst) | 设置清晰度还是流畅度优先 | - -### EMACallManager - -| 方法 | 描述 | -| :----------------------------------------------------------- | :------------------------------------------- | -| [addCallStateChangeListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a80b224a48a9019501bc724c5ff65a267) | 增加通话监听 | -| [removeCallStateChangeListener](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#ab2023190fb75c661343e0b0b8443ab29) | 移除通话监听 | -| [setPushProvider](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#ab186d489c2779e2984498f79b63432fd) | 添加离线推送回调代理,该代理只能设置一个 | -| [pauseVoiceTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a13470d6e6725c31285f97b4ed0b7217e) | 暂停音频数据传输 | -| [resumeVoiceTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#ae294c324c0fa3a08e83111c3cb5207b1) | 恢复音频数据传输 | -| [pauseVideoTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 暂停视频数据传输 | -| [resumeVideoTransfer](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a4c0c6ba346d7432185d49dc594c5fe72) | 恢复视频数据传输 | -| [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19d8c3b170bed1359226861f45be39d9) | mute远端音频 | -| [muteRemoteVideo](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#ac0ec72a6bbd6f19f8c78f28df6b0cb20) | mute远端视频 | -| [makeVideoCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a3e49344c1ff527960e8978f2ba6858db) | 发起视频通话(有多参数方法,可选择是否录制) | -| [makeVoiceCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a0dab7508a3592c17c2d3c4023c73c3d3) | 发起语音通话(有多参数方法,可选择是否录制) | -| [setSurfaceView](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a1d49e876527c6e79e25ffe4ee19516f8) | 设置视频通话本地和对端视频显示视图 | -| [isDirectCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a866daea70ddec39101b7da293f254eb9) | 当前通话时是否为P2P直连 | -| [setCameraFacing](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a2982d7b6c6f870568b0fdd2bc6e487c2) | 开启相机拍摄 | -| switchCamera | 切换前后摄像头 | -| [inputExternalVideoData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a75c1911842e876ffe2cff7619072e7e1) | 外部输入视频数据(有多参方法) | -| [inputExternalAudioData](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a1dd9ce23f11e6e7aff53d1e151396368) | 自定义外部音频数据 | -| setWaterMark | 通话设置水印 | -| [answerCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a51fa517af552f757d716c29492a11064) | 接受方同意通话请求 | -| [endCall](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a1e48d8764d6ffa3b0fc26ea29dca8689) | 结束通话 | -| getCallOptions | 获取视频通话配置 | -| getVideoCallHelper | 获取视频通话统计信息 | -| getCallState | 获取当前通话状态 | -| getCurrentCallSession | 获取当前通话Session | - -### EMCallStateChangeListener - -| CallState 回调状态 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------------------- | -| [CONNECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallState.html#a4d71b0fb259693e52a4a5edb27971eb7) | 通话通道建立完成,用户A和用户B都会收到这个回调 | -| [ACCEPTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallState.html#a6904d6921621f2f91cb1ac9fecbe871e) | 用户B同意用户A拨打的通话后,用户A和B会收到这个回调 | -| [DISCONNECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallState.html#a9d270eeeddaedf1259c127d0e563f41b) | 用户A或用户B结束通话后 或者 通话出现错误,双方都会收到该回调 | -| [VOICE_PAUSE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中断音频传输时,用户B会收到该回调 | -| [VOICE_RESUME](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中恢复音频传输时,用户B会收到该回调 | -| [VIDEO_PAUSE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中断视频传输时,用户B会收到该回调 | -| [VIDEO_RESUME](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户A和用户B正在通话中,用户A中恢复视频传输时,用户B会收到该回调 | -| [NETWORK_UNSTABLE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户网络状态不可用 | -| [NETWORK_NORMAL](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户网络状态正常 | -| [NETWORK_DISCONNECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMCallManager.html#a19e6305d014c0cc0f19e94c40cee7c63) | 用户网络状态断开 | - -| CallError 回调状态 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------------- | -| [ERROR_NONE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#a05e939dde5b09411416d444918cc46df) | 用户正常挂断或者结束通话 | -| [ERROR_TRANSPORT](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#a9d445232fbf19ab6b97999ecf3432c0b) | P2P连接失败 | -| [ERROR_UNAVAILABLE](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#ad9aa8a289a588b0c4ecea5ceb81bd047) | P2P连接不可用 | -| [REJECTED](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#a9b6779b9b6d22aefc61d626b480db2af) | 用户A拨打用户B,用户B拒绝语音通话,用户A会收到这个回调 | -| [ERROR_BUSY](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#aabd50d9ec74067b4a02aa9421239912f) | 用户A拨打用户B,用户B忙线中 | -| [ERROR_NO_DATA](http://sdkdocs.easemob.com/apidoc/android/chat3.0/enumcom_1_1hyphenate_1_1chat_1_1EMCallStateChangeListener_1_1CallError.html#ac53371aa3c3342b8dab4fea366df51af) | 无音频数据传输状态 | - -### EMCallPushProvider - -| 回调事件 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------------------- | -| [onRemoteOffline](http://sdkdocs.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1chat_1_1EMCallManager_1_1EMCallPushProvider.html#a2f7eb2e385bb767d19c523e35541b7b0) | 用户A给用户B拨打实时通话,用户B不在线,并且用户A启用了推送功能,则用户A会收到该回调 | - -### EMCallSession - -| 方法 | 描述 | -| :---------------- | :--------------------- | -| getCallId | 获取会话标识符 | -| getLocalName | 获取通话本地的username | -| getType | 获取通话的类型 | -| getIscaller | 是否为主叫方 | -| getRemoteName | 获取对方的username | -| getConnectType | 连接类型 | -| isRecordOnServer | 是否启用服务器录制 | -| getServerRecordId | 获取录制ID | -| getExt | 获取消息扩展 | - -### EMVideoCallHelper - -| 方法 | 描述 | -| :----------------------------------------------------------- | :--------------------- | -| [setPreferMovFormatEnable](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#ae195a239bbdae089eaa88bb55982dd55) | 录制的视频文件的路径 | -| [getVideoLatency](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a433e891df1e8fbb2e8535c744cecba3e) | 视频发送时延 | -| [getVideoFrameRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#ac83387d292e78d7d9fca7c5a8820385f) | 视频帧率 | -| [getVideoLostRate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a0fff93c903d00dcf03d79410cb68a1bb) | 每一百个包中丢包个数 | -| [getVideoWidth](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a0d5a9060d753f057228b5f1bb17382fd) | 对端视频宽度 | -| [getVideoHeight](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#ac9987c9e7f672feadc600edcc11312d0) | 对端视频高度 | -| [getRemoteBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a9f025b264ccc6adfefd66ec7c278de41) | 接收视频比特率(kbps) | -| [getLocalBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a6c10265ec15af009a0b21017652edc1a) | 发送视频比特率(kbps) | -| [getLocalAudioBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#af76d7ce55e0121872f2d2b62f071ffaf) | 发送音频比特率(kbps) | -| [getRemoteAudioBitrate](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMVideoCallHelper.html#a490453dbb94cc50750f654c5dde8b170) | 接收音频比特率 (kbps) | - -### EMWaterMarkOption - -| 方法 | 描述 | -| :------------- | :-------------------------- | -| setMarkImg | 水印图片资源 (格式为bitmap) | -| setOrientation | 水印位置 | -| setHeight | 水印高度 | -| setWeight | 水印宽度 | -| setwMargin | 距离边缘水平距离 | -| sethMargin | 距离边缘垂直距离 | - -### EMWaterMarkPosition - -| 方法 | 描述 | -| :----------- | :----- | -| TOP_LEFT | 左上角 | -| TOP_RIGHT | 右上角 | -| BOTTOM_LEFT | 左下角 | -| BOTTOM_RIGHT | 右下角 | \ No newline at end of file diff --git a/docs/private/media/one2one_introduction.md b/docs/private/media/one2one_introduction.md deleted file mode 100644 index c5d6a24b..00000000 --- a/docs/private/media/one2one_introduction.md +++ /dev/null @@ -1,44 +0,0 @@ -# 1对1通话简介 - -## 适用场景 - -1对1通话API用于实现1对1语音通话和1对1视频通话,典型场景包括社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。 - -其API设计思想类似于传统的电话通话,呼叫过程使用了即时通讯的消息机制,所以和即时通讯功能是紧耦合的。 - -## 功能列表 - -| 功能 | android 原生 | iOS 原生 | Web | PC桌面 | -| :------------- | :----------- | :------- | :----- | :----- | -| 1对1音频通话 | 支持 | 支持 | 支持 | 支持 | -| 1对1视频通话 | 支持 | 支持 | 支持 | 支持 | -| 静音自己 | 支持 | 支持 | 支持 | 支持 | -| 不听他人 | 支持 | 支持 | 支持 | 支持 | -| 外部视频源输入 | 支持 | 支持 | 不支持 | 不支持 | -| 伴音 | 支持 | 支持 | 不支持 | 不支持 | -| 视频流水印 | 支持 | 支持 | 不支持 | 不支持 | -| 开启云录制 | 支持 | 支持 | 支持 | 支持 | - -:::tip -1对1通话场景,也可以用多人通话API来实现,开发者使用即时通讯消息机制来实现呼叫应答等。 -::: - -## 通话流程 - -- 发起方调用SDK接口发起呼叫 -- 接收方收到SDK回调通知“收到一个呼叫”,展示振铃页面 -- 接收方用户点击接听按钮,调用SDK接口接听 -- 发起方收到SDK回调通知“对方已接听”,展示通话界面,双方开始通话 -- 一方调用SDK接口挂断通话,另一方收到SDK回调“对方挂断”,结束通话 - -## 客户端下载 - -[>>下载音视频SDK及Demo](common_clientsdk.html#音视频sdk下载) - -体验Demo:打开Demo,打开联系人,选择视频通话或语音通话,即可体验。 - -![img](/images/privitization/1v1-demo.png) - -## 计费说明 - -环信私有化音视频服务计费规则及功能详情,请联系商务经理程先生(Tel:17611319060) \ No newline at end of file diff --git a/docs/private/media/one2one_ios.md b/docs/private/media/one2one_ios.md deleted file mode 100644 index ea98d977..00000000 --- a/docs/private/media/one2one_ios.md +++ /dev/null @@ -1,694 +0,0 @@ -# iOS集成1对1通话 - -## 跑通Demo - -### 1. 示例代码 - -- [下载 iOS SDK + Demo 代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/iOS_IM_SDK_V3.7.4.7.zip) - -或进入环信[客户端下载](common_clientsdk.html#音视频sdk下载)页面,选择iOS SDK + Demo下载 - -### 2. 前提条件 - -运行Demo前你需要具备以下条件 - -- mac操作系统10.11以上 -- 安装Xcode 11以上 -- iPhone设备iPhone 6以上,安装系统iOS 9.0以上 - -### 3. 运行Demo - -#### 3.1 Demo代码目录简介 - -目录 EaseIM —>Class 中的 Demo 目录介绍 - -![img](/images/privitization/ios_demo.png) - -- Account:主要是 demo 的注册,登录 -- AppDelegate:主要是 demo 中初始化环信SDK,注册推送等 -- Chat:demo 的聊天功能页面 -- Contact:demo 的好友功能页面 -- Conversation:demo 的会话列表功能页面 -- EMIMHelper:demo 的单例类,包含全局监听接收消息,好友,群组,聊天室等相关事件的回调,从而进行对应的处理 -- Group:demo 的群组功能页面 -- Helper:demo 的功能性文件,全局通用的配置 -- Home:demo 的根控制器页面 -- Settings:demo 的功能设置页面 - -#### 3.2 工程设置 - -进入iOS Demo目录,打开EMiOSDemo.xcworkspace ,进入工程设置的Signing & Capaabilities菜单,修改签名Team和bundleId为自己的团队开发。 - -#### 3.3 运行 - -连接iPhone手机,选择目标设备,点击运行 - -## 快速集成 - -本章节介绍如何使用HyhpenateSDK 快速实现1v1音视频通话 - -### 1. 环信后台注册appkey - -在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。 - -### 2. 创建项目 - -参考以下步骤创建一个iOS 应用项目,如果已有项目,可以直接进行下一步集成。创建过程如下: - -- 打开 Xcode 并点击 Create a new Xcode project。 -- 选择项目类型为 Single View App,并点击 Next。 -- 输入项目信息,如项目名称、开发团队信息、组织名称和语言,语言为Object-C,并点击 Next。 -- 选择项目存储路径,并点击 Create。 -- 进入工程设置页面的Signing & Capaabilities菜单,选择 Automatically manage signing,并在弹出菜单中点击 Enable Automatic - -### 3. 导入SDK到工程 - -集成SDK有两种方法,分别是使用cocoapods和手动导入SDK - -#### 使用cocoapods导入SDK - -开始前确保你已安装 Cocoapods。 - -- 在 Terminal 里进入项目根目录,并运行 pod init 命令。项目文件夹下会生成一个 Podfile 文本文件。 -- 打开 Podfile 文件,修改文件为如下内容。注意将 AppName 替换为你的 Target 名称,并将 version 替换为你需集成的 SDK 版本,如3.7.0。 - -``` -target 'AppName' do - pod 'Hyphenate', '~> version' -end -``` - -- 在 Terminal 内运行 pod update 命令更新本地库版本。 -- 运行 pod install 命令安装 Agora SDK。成功安装后,Terminal 中会显示 Pod installation complete!,此时项目文件夹下会生成一个 xcworkspace 文件。 -- 打开新生成的 xcworkspace 文件。 - -#### 手动导入SDK - -- 将在跑通Demo阶段下载的HyphenateFullSDK下的Hyphenate.framework拷贝到项目工程目录下 -- 打开工程设置/Genaral菜单下,将Hyphenate.framework拖拽到Frameworks,libraries,and Embedded Content下,并设置为Embed and Signed - -工程中引入SDK,需要引用头文件Hyphenate.h - -``` -#import -``` - -### 4. 添加权限 - -应用需要音频设备及摄像头权限,在 info.plist 文件中,点击 + 图标,添加如下信息 - -| Key | Type | Value | -| :------------------------------------- | :----- | :----------------------------------- | -| Privacy - Microphone Usage Description | String | 描述信息,如“环信需要使用您的麦克风” | -| Privacy - Camera Usage Description | String | 描述信息,如“环信需要使用您的摄像头” | - -如果希望在后台运行,还需要添加后台运行音视频权限,在info.plist文件中,点击 + 图标,添加Required background modes,Type为Array,在Array下添加元素App plays audio or streams audio/video using AirPlay - -### 5. 创建UI - -音视频通话窗口中,一般包括以下几个UI控件 - -- 暂停/恢复语音按钮 -- 结束通话按钮 -- 扬声器/耳机切换按钮 -- 后置摄像头切换按钮(视频) -- 打开/关闭摄像头按钮(视频) -- 本地图像显示与对端图像显示(视频) - -通话界面可以参考Demo中Call1v1VideoViewController,效果如下: - -![img](/images/privitization/1v1video.png) - -### 6. 初始化SDK - -初始化HyhpenateSDK使用initializeSDKWithOptions:接口,需要设置自己的appkey,调用如下: - -``` -// 这里替换成自己的appkey -EMOptions *retOpt = [EMOptions optionsWithAppkey:@"easemob-demo#chatdemoui"]; -// 这里打开日志输出 -retOpt.enableConsoleLog = YES; -[[EMClient sharedClient] initializeSDKWithOptions:retOpt]; -``` - -### 7. 环信ID注册、登录 - -在进行音视频通话前,需要首先登录IM账户,登录过程参见[账号登录](http://doc.easemob.com/document/ios/overview.html#%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95)。 - -若您还没有IM账户,需要先注册账户,注册过程参见[账号注册](http://doc.easemob.com/document/ios/overview.html#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7) - -### 8. 音视频功能初始化 - -账号登录成功后,需要进行音视频通话功能的初始化,设置监听类 - -``` -[[EMClient sharedClient].callManager addDelegate:self delegateQueue:nil]; -``` - -### 9. 发起通话请求 - -主叫方发起呼叫通话请求的过程如下: - -``` -[[EMClient sharedClient].callManager startCall:EMCallTypeVideo - remoteName:aUsername - ext:@"123" - completion:^(EMCallSession *aCallSession, EMError *aError) { - self.callSession = aCallSession; -}]; -``` - -回调的aCallSession为本次会话session,需要在本地保存下来。 - -在发起视频通话,等待对方接听过程中,已经可以显示本地图像,显示本地图像的过程如下 - -``` -self.callSession.localVideoView = [[EMCallLocalView alloc] init]; - self.callSession.localVideoView.scaleMode = EMCallViewScaleModeAspectFill; - [self.minVideoView addSubview:self.callSession.localVideoView]; - [self.view bringSubviewToFront:self.minVideoView]; - [self.callSession.localVideoView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.minVideoView); - }]; -``` - -主叫方发起通话请求后,被叫方若已登录,将会收到如下回调通知 - -``` -- (void)callDidReceive:(EMCallSession *)aSession -{ - self.callSession = aSession; -} -``` - -aSession为本次通话的session,被叫方应该在本地保存。 - -### 10. 接听通话 - -被叫方在收到通话请求回调后,可以选择接听/拒绝通话,若选择接听通话,调用如下: - -``` -[[EMClient sharedClient].callManager answerIncomingCall:self.callSession.callId]; -``` - -此时被叫方可以显示本地视频图像 - -``` -self.callSession.localVideoView = [[EMCallLocalView alloc] init]; - self.callSession.localVideoView.scaleMode = EMCallViewScaleModeAspectFill; - [self.minVideoView addSubview:self.callSession.localVideoView]; - [self.view bringSubviewToFront:self.minVideoView]; - [self.callSession.localVideoView mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo(self.minVideoView); - }]; -``` - -当通话接通后,双方会收到callDidAccept回调通知,在这里可以设置远端图像 - -``` -if (self.callSession.remoteVideoView == nil) { - self.callSession.remoteVideoView = [[EMCallRemoteView alloc] init]; - self.callSession.remoteVideoView.backgroundColor = [UIColor clearColor]; - self.callSession.remoteVideoView.scaleMode = EMCallViewScaleModeAspectFit; - self.callSession.remoteVideoView.userInteractionEnabled = YES; - } -``` - -### 11. 拒绝通话 - -被叫方收到呼叫请求后,可以选择拒绝通话,调用过程如下: - -``` -[[EMClient sharedClient].callManager endCall:self.callSession.callId reason:EMCallEndReasonDecline]; -``` - -拒绝后,主叫方收到如下回调, aReason为EMCallEndReasonDecline - -``` -- (void)callDidEnd:(EMCallSession *)aSession - reason:(EMCallEndReason)aReason - error:(EMError *)aError -``` - -### 12. 结束通话 - -通话中双方随时都可以结束通话,调用过程如下: - -``` -[[EMClient sharedClient].callManager endCall:@"callId" reason:EMCallEndReasonHangup]; -``` - -结束后双方收到以下回调: - -``` -- (void)callDidEnd:(EMCallSession *)aSession - reason:(EMCallEndReason)aReason - error:(EMError *)aError -``` - -## 进阶功能 - -在实现基本视频通话的基础上,SDK提供更为丰富的API,可以实现更为复杂的音视频通话场景 - -### 取日志 - -SDK会写入日志文件到本地。日志文件路径如下:沙箱Documents/HyphenateSDK/easemoblog,以真机为例,获取过程如下: - -- 打开Xcode连接设备,前往Xcode –> Window –> Devices and Simulators -- 进入Devices选项卡,在左侧选择目标设备,界面如下: - -[![img](https://docs-im.easemob.com/_media/rtc/one2one/fetchlogfile.png?w=400&tok=6c005b)](https://docs-im.easemob.com/_detail/rtc/one2one/fetchlogfile.png?id=rtc%3Aone2one%3Aios) - -日志文件easemob.log文件在下载包内容的AppData/Library/Application Support/HyphenateSDK/easemobLog目录下 - -### 音视频控制 - -使用通话过程中保存的EMCallSession的对象,可以分别进行音频、视频的开关控制,切换前后摄像头等操作,操作过程如下 - -``` -/*! - * 暂停语音数据传输 - * - * @result 错误 - */ -- (EMError *)pauseVoice; - -// 调用: -[aCallSession pauseVoice]; - -/*! - * 恢复语音数据传输 - * - * @result 错误 - */ -- (EMError *)resumeVoice; - -// 调用: -[aCallSession resumeVoice]; - -/*! - * 暂停视频图像数据传输 - * - * @result 错误 - */ -- (EMError *)pauseVideo; - -// 调用: -[aCallSession pauseVideo]; - -/*! - * 恢复视频图像数据传输 - * - * @result 错误 - */ -- (EMError *)resumeVideo; - -// 调用: -[aCallSession resumeVideo]; -``` - -通话过程中可以切换前后摄像头 - -``` -#pragma mark - Camera - -/*! - * 设置使用前置摄像头还是后置摄像头,默认使用前置摄像头 - * - * @param aIsFrontCamera 是否使用前置摄像头, YES使用前置, NO使用后置 - */ -- (void)switchCameraPosition:(BOOL)aIsFrontCamera; - -// 调用: -[aCallSession switchCameraPosition:YES]; -``` - -当通话一方进行音频、视频的开关控制时,另一方会收到如下回调通知 - -``` -/*! - * 用户A和用户B正在通话中,用户A中断或者继续数据流传输时,用户B会收到该回调 - * - * @param aSession 会话实例 - * @param aType 改变类型 - */ -- (void)callStateDidChange:(EMCallSession *)aSession - type:(EMCallStreamingStatus)aType; -``` - -### 设置通话参数 - -通话之前,可以设置音频通话的最大音频码率,最小视频码率、最大视频码率、分辨率和是否清晰度优先,设置方法如下 - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -options.maxAudioKBps = 32; -options.maxVideoKBps = 3000; -options.minVideoKBps = 500; -options.maxVideoFrameRate = 20; -options.videoResolution = EMCallVideoResolution352_288; -options.isClarityFirst = YES;//若设为清晰度优先,将在弱网环境下保证视频的分辨率 -``` - -### 离线推送 - -iOS离线推送分为pushKit强推送和APNs普通推送,开启离线推送需要上传推送证书,参见[APNs推送证书上传](http://docs-im.easemob.com/im/ios/apns/deploy)和[pushKit推送集成](http://docs-im.easemob.com/knowledge/pushkit) - -配置属性(在登录环信服务器成功之后设置) - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -//当对方不在线时,是否给对方发送离线消息和推送,并等待对方回应 -options.isSendPushIfOffline = YES; -[[EMClient sharedClient].callManager setCallOptions:options]; -``` - -协议 - -``` - -``` - -添加代理 - -``` -[[EMClient sharedClient].callManager setBuilderDelegate:self]; -``` - -监听回调 - -``` -- (void)callRemoteOffline:(NSString *)aRemoteName -{ - NSString *text = [[EMClient sharedClient].callManager getCallOptions].offlineMessageText; - EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:text]; - NSString *fromStr = [EMClient sharedClient].currentUsername; - EMMessage *message = [[EMMessage alloc] initWithConversationID:aRemoteName from:fromStr to:aRemoteName body:body ext:@{@"em_apns_ext":@{@"em_push_title":text}}]; - message.chatType = EMChatTypeChat; - // 通过消息的ext来自定义提示铃声,其中customSound.caf为自定义铃声名称 - message.ext = @{ - @"em_apns_ext":@{ - @"em_push_sound":@"customSound.caf" - } - }; - [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil]; -} -``` - -因为该消息为提示铃声,所以使用自定义铃声来播放,时长需要控制在30秒以内,此处可以参考文档[自定义铃声](http://docs-im.easemob.com/im/ios/apns/content#自定义推送提示音) - -协议,代理,回调方法建议写到工程的根控制器或者appdelegate中监听,起到全局监听的作用。 - -### 云端录制 - -主叫方呼叫时可以指定是否开启服务器录制,如要录制,使用以下方法呼叫,isRecord输入YES,isMerge为是否录制合流,根据需要进行设置 - -``` -- (void)startCall:(EMCallType)aType - remoteName:(NSString *)aRemoteName - record:(BOOL)isRecord - mergeStream:(BOOL)isMerge - ext:(NSString *)aExt - completion:(void (^)(EMCallSession *aCallSession, EMError *aError))aCompletionBlock; -``` - -### 通话统计数据 - -通话数据的统计功能需要主动开启,开启方法为在通话前进行如下设置 - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -options.enableReportQuality = YES; -``` - -开启后可以从保存的会话callSession中获取到通话的实时码率、帧率、分辨率等数据 - -### 弱网检测 - -SDK提供实时检测通话网络质量的功能,同样需要开启通话数据统计,开启方法同上。开启后,可以通过回调通知应用当前实时通话网络状态。 - -``` -typedef enum{ - EMCallNetworkStatusNormal = 0, /*! 正常 */ - EMCallNetworkStatusUnstable, /*! 不稳定 */ - EMCallNetworkStatusNoData, /*! 没有数据 */ -}EMCallNetworkStatus; - -/*! - * 用户A和用户B正在通话中,用户A的网络状态出现不稳定,用户A会收到该回调 - * - * @param aSession 会话实例 - * @param aStatus 当前状态 - */ -- (void)callNetworkDidChange:(EMCallSession *)aSession - status:(EMCallNetworkStatus)aStatus -``` - -### 变声/自定义音频 - -用户可以通过自己采集音频数据,使用外部输入音频数据的接口进行通话,从而实现变声等音频数据加工功能 - -##### 配置属性 - -用户使用自定义音频数据时,需要配置外部输入音频数据的开关,以及音频采样率,通道数(当前通道数只支持1),配置方法如下: - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -options.enableCustomAudioData = YES; -options.audioCustomSamples = 48000; -options.audioCustomChannels = 1; -[[EMClient sharedClient].callManager startCall:aType remoteName:aUsername ext:@"123" completion:^(EMCallSession *aCallSession, EMError *aError) { - completionBlock(aCallSession, aError); -}]; -``` - -##### 输入音频数据 - -音频数据采集可参考Demo中的AudioRecord类实现,音频数据的输入必须在会话接通后开始,否则会导致网络阻塞,影响通话质量。建议用户将音频数据采集的开始放在会话接通的回调里,及callDidAccept回调中 - -``` -- (void)callDidAccept:(EMCallSession *)aSession -{ - if ([aSession.callId isEqualToString:self.currentCall.callId]) { - [self _stopCallTimeoutTimer]; - self.currentController.callStatus = EMCallSessionStatusAccepted; - } - EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; - if(options.enableCustomAudioData){ - [self audioRecorder].channels = options.audioCustomChannels; - [self audioRecorder].samples = options.audioCustomSamples; - [[self audioRecorder] startAudioDataRecord]; - } -} -``` - -音频采集过程开始后,在音频数据的回调里调用外部输入音频数据接口 - -``` -[[[EMClient sharedClient] callManager] inputCustomAudioData:data -``` - -会话挂断时,停止音频采集及输入过程 - -``` -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -if(options.enableCustomAudioData) { - [[self audioRecorder] stopAudioDataRecord]; -} -``` - -### 美颜/自定义视频 - -用户可以通过自己采集视频数据,使用外部输入视频数据的接口,实现自定义视频传输功能,可以对视频数据进行添加滤镜、美颜等功能。 - -##### 配置属性 - -使用外部输入视频数据接口前,需要先进行配置,配置如下 - -``` -//进行1v1自定义视频之前,必须设置 EMCallOptions.enableCustomizeVideoData=YES -EMCallOptions *options = [[EMClient sharedClient].callManager getCallOptions]; -options.enableCustomizeVideoData = YES; -[[EMClient sharedClient].callManager startCall:aType remoteName:aUsername ext:@"123" completion:^(EMCallSession *aCallSession, EMError *aError) { - completionBlock(aCallSession, aError); -}]; -``` - -##### 自定义摄像头数据 - -设置 **EMCallOptions.enableCustomizeVideoData=YES** 后,必须自定义摄像头数据。采集视频数据可使用AVCaptureSession实现,呼叫方的视频数据采集可以在呼叫对方时开始,而接听方的数据采集可以在按下接听按钮后开始。 外部输入视频数据的接口如下: - -``` -/*! - * \~chinese - * 自定义本地视频数据 - * - * @param aSampleBuffer 视频采样缓冲区 - * @param aRotation 旋转方向 - * @param aCallId 1v1会话实例ID,即[EMCallSession callId] - * @param aCompletionBlock 完成后的回调 - */ -- (void)inputVideoSampleBuffer:(CMSampleBufferRef)aSampleBuffer - rotation:(UIDeviceOrientation)aRotation - callId:(NSString *)aCallId - completion:(void (^)(EMError *aError))aCompletionBlock; - -/*! - * \~chinese - * 自定义本地视频数据 - * - * @param aPixelBuffer 视频像素缓冲区 - * @param aCallId 1v1会话实例ID,即[EMCallSession callId] - * @param aTime 视频原始数据时间戳,CMTime time = CMSampleBufferGetPresentationTimeStamp((CMSampleBufferRef)sampleBuffer); - * @param aRotation 旋转方向 - * @param aCompletionBlock 完成后的回调 - */ -- (void)inputVideoPixelBuffer:(CVPixelBufferRef)aPixelBuffer - sampleBufferTime:(CMTime)aTime - rotation:(UIDeviceOrientation)aRotation - callId:(NSString *)aCallId - completion:(void (^)(EMError *aError))aCompletionBlock; -``` - -接口的调用在视频数据的回调中,即captureOutput:didOutputSampleBuffer:fromConnection中调用,调用前需要判断当前会话通话状态,若状态为EMCallSessionStatusAccepted,则可以调用外部输入视频数据接口。 - -当视频通话挂断时,需要终止视频数据采集过程 - -### 水印 - -视频通话时,可以添加图片作为水印,添加时使用[IEMCallManager addVideoWatermark]接口,需要指定水印图片的NSUrl,添加位置.参见[EMWaterMarkOption](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_water_mark_option.html)。 - -清除水印使用[IEMCallManager clearVideoWatermark]接口。 - -显示remoteVideo需要使用EMCallViewScaleModeAspectFit模式,否则对方的水印设在边缘位置可能显示不出来。 - -##### 接口 - -``` -/*! -* \~chinese -* 开启水印功能 -* -* @param option 水印配置项,包括图片URL,marginX,marginY以及起始点 -* -* \~english -* Enable water mark feature -* -* @param option the option of watermark picture,include url,margingX,marginY,margin point - */ -- (void)addVideoWatermark:(EMWaterMarkOption*)option; -/*! -* \~chinese -* 取消水印功能 -* -* \~english -* Disable water mark feature -* - */ -- (void)clearVideoWatermark; -``` - - -### 私有部署 - -私有部署设置方法参见[私有云sdk集成配置](../im/uc_iOS_private.md) - -## 客户端API - -1V1音视频通话的API包括以下接口 - -- EMCallOption 视频通话配置类 -- EMCallManager 是视频通话的主要管理类,提供了语音通话的拨打、接听、挂断等接口 -- EMCallManagerDelegate 是视频通话的监听回调类,实时语音通话相关的回调 -- EMCallBuilderDelegate 提供了拨打视频通话时对方不在线的回调 -- EMCallSession 语音通话的会话实例接口类 - -### EMCallOption - -| 属性 | 描述 | -| :----------------------------------------------------------- | :--------------------------------------------------- | -| [pingInterval](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a3186d2e45fcd6c5697c724679d0affc7) | 心跳时间间隔,单位秒,默认30s,最小10s | -| [isSendPushIfOffline](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a387a20ee25e1d735b61b0c31bf834556) | 被叫方不在线时,是否推送来电通知 | -| [offlineMessageText](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a62d88c4b292cdfb13b4ea8d723ba2f65) | 当isSendPushIfOffline=YES时起作用,离线推送显示的内容 | -| [maxAudioKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#aea45547ce623a0fd5d53a36f00334520) | 最大音频码率 | -| [maxVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a4130c8f7488d6d6f58c3783dc63be5fd) | 最大视频码率 | -| [minVideoKbps](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae070e260597c913634a21c03aa31826a) | 最小视频码率 | -| [maxVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a45f020f84b4513fdc0cb3f8a123fe678) | 最大视频帧率 | -| [videoResolution](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af49ac4f01b9bca538fbce40e1de5f866) | 视频分辨率 | -| [enableReportQuality](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#af2129acdd0d3d73a583e8d37dfc087e2) | 是否监听通话质量 | -| [enableCustomAudioData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#ae927cb60d05c59b389517648941e7ec8) | 是否使用自定义音频数据 | -| [audioCustomSamples](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a76482a8e2702e1905c036142e41c8a6d) | 自定义音频数据的采样率,默认48000 | -| [enableCustomizeVideoData](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_options.html#a89f38b15e05ed5d6636af5fde628d114) | 是否使用自定义视频数据 | - -### EMCallManager - -| 方法 | 功能 | -| :----------------------------------------------------------- | :--------------------------------------- | -| [addDelegate:delegateQueue:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a367328bcd0bf83a51dc08ddaec68872f) | 添加回调代理 | -| [removeDelegate:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#aa9b3da07b69c09e892f828791b1370cb) | 移除回调代理 | -| [setBuilderDelegate:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#ab186d489c2779e2984498f79b63432fd) | 添加离线推送回调代理,该代理只能设置一个 | -| [setCallOptions:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a8bdffc278012912e6b647496f950f2d0) | 配置设置项 | -| [getCallOptions](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#aa57c5e2e99d712a9e228fa4a3456cab4) | 获取设置项 | -| [startCall:remoteName:ext:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#afb034d6e9e45e8712f6ce152c83cde51) | 发起实时会话 | -| [startCall:remoteName:record:mergeStream:ext:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a96844b40a066c066bc0e1dd99d98c535) | 发起实时会话,可选择是否录制 | -| [answerIncomingCall:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#acc32a00500f5ff029035a723fc4234c2) | 接收方同意通话请求 | -| [endCall:reason:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a3964f06814f26a3f3f9b435f59ee3385) | 结束通话 | -| [inputCustomAudioData:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a39f332f19d39159b7fdcb5667e38db5d) | 自定义外部音频数据 | -| [inputVideoSampleBuffer:rotation:callId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a09537a70ba5c40c1de38db2398b9bd95) | 自定义本地视频数据 | -| [inputVideoPixelBuffer:sampleBufferTime:rotation:callId:completion:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a04e9c0e4e1bdbe060552865e39daab73) | 自定义本地视频数据 | -| [addVideoWatermark:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a5618360f7593b6acc429fd2318962724) | 开启水印 | -| [clearVideoWatermark](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a16bddaff9383df6da73e08919019d322) | 清除水印 | - -### EMCallManagerDelegate - -| 回调事件 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------------------- | -| [callDidReceive:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a3eba09d467fd76b4af04e5bf47154b77) | 用户A拨打用户B,用户B会收到这个回调 | -| [callDidConnect:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a5203fbf604e29cacedf483c5f52b9923) | 通话通道建立完成,用户A和用户B都会收到这个回调 | -| [callDidAccept:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#aa0f4c7b3f5a9c6613f6726420910e76c) | 用户B同意用户A拨打的通话后,用户A和B会收到这个回调 | -| [callDidEnd:reason:error:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a82a5133f2175c94c4b39cf6f42010601) | 1. 用户A或用户B结束通话后,双方会收到该回调. 2. 通话出现错误,双方都会收到该回调 | -| [callStateDidChange: type:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#a3b78b91a87d76a4ec5f79f60cb213228) | 用户A和用户B正在通话中,用户A中断或者继续数据流传输时,用户B会收到该回调 | -| [callNetworkDidChange:status:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_manager_delegate-p.html#aae5150a53d6c69c278b9bdde4cac2022) | 用户A和用户B正在通话中,用户A的网络状态出现不稳定,用户A会收到该回调。若未开启录制,用户B也会收到该回调 | - -### EMCallBuilderDelegate - -| 回调事件 | 描述 | -| :----------------------------------------------------------- | :----------------------------------------------------------- | -| [callRemoteOffline:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_e_m_call_builder_delegate-p.html#a14ac31090d0283a3229cc665aa1b34d2) | 用户A给用户B拨打实时通话,用户B不在线,并且用户A设置了[EMCallOptions.isSendPushIfOffline == YES],则用户A会收到该回调 | - -### EMCallSession - -属性 - -| 属性 | 描述 | -| :----------------------------------------------------------- | :---------------------------------------------------- | -| [callId](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a66283c44edfc5ae767b382f63176d953) | 会话标识符 | -| [localName](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a97e3bea964a2228e08cbc77587f5402e) | 通话本地的username | -| [type](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#aa12fc9a028f5ae16869a302894ffdb4f) | 通话的类型 | -| [isCaller](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a782bad856c936638349d96e8520cc0ef) | 是否为主叫方 | -| [remoteName](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a0652ad964df50c2bafe76281026cde69) | 对方的username | -| [status](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a7ac723de33f96d1f05777c5e53001636) | 通话的状态 | -| [localVideoView](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ad8ed75a4fedb8ae9573d8c5ce296867a) | 视频通话时本地的图像显示区域 | -| [remoteVideoView](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a74cf99cc4f08c2694459b878b04f3829) | 视频通话时对方的图像显示区域 | -| [connectType](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ab31443f1605498f4bb80a4e98925fecb) | 连接类型 | -| [videoLatency](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a218b700793cbd72fb0bd1a5556bf0e06) | 视频的延迟时间,单位是毫秒 | -| [localVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a6d05d54be6d7508b959f2ef020ca0eee) | 本地视频的帧率,实时变化 未获取到返回-1 | -| [remoteVideoFrameRate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ac1e60bc6f19f4cf2d50c2264702928dd) | 对方视频丢包率,实时变化 未获取到返回-1 | -| [localVideoBitrate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#aecc7d56536bfedcb924e19e0bc860109) | 本地视频通话对方的比特率kbps,实时变化 未获取到返回-1 | -| [remoteVideoBitrate](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#adf4ac941a4a002e5025b78d01b98b2c0) | 对方视频通话对方的比特率kbps,实时变化 未获取到返回-1 | -| [localVideoLostRateInPercent](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ab42eb2571e0bb1111ab33f84c80588a0) | 本地视频丢包率,实时变化 未获取到返回-1 | -| [remoteVideoLostRateInPercent](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#aea427d3dd20376f3a9a5f37fb157358a) | 对方视频丢包率,实时变化 未获取到返回-1 | -| [remoteVideoResolution](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a3ef044730afda942a2e7955b23bc9d75) | 对方视频分辨率 未获取到返回 (-1,-1) | -| [serverVideoId](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#ac0aa89265a9e30dbb23d3d605cf91172) | 服务端录制文件的id | -| [willRecord](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a6b76c8b2df03bcf4fab8b459fcc60407) | 是否启用服务器录制 | -| [ext](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a7c446f7fa3e2d23fd3cb2c8eb448dcd1) | 消息扩展 | - -方法 - -| 方法 | 功能 | -| :----------------------------------------------------------- | :--------------- | -| [pauseVoice](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a42467f8c736ca48b7d97d0281e52e0c7) | 暂停语音数据传输 | -| [resumeVoice](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a52119fa0310787b4041fab33248abf0e) | 恢复语音数据传输 | -| [pauseVideo](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a36946520d5b65fbe1900c3fc87d7d6c9) | 暂停视频传输 | -| [resumeVideo](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a5529c28cebfd1959f37934028464b2a6) | 恢复视频传输 | -| [switchCameraPosition:](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/interface_e_m_call_session.html#a5c3eb19b609b57c4842a4ef8900c984b) | 切换前后摄像头 | \ No newline at end of file diff --git a/docs/private/media/one2one_pcdesktop.md b/docs/private/media/one2one_pcdesktop.md deleted file mode 100644 index 3a5c0fb4..00000000 --- a/docs/private/media/one2one_pcdesktop.md +++ /dev/null @@ -1,187 +0,0 @@ -# PC桌面集成1对1通话 - ------- - -1v1实时通话允许用户发起、接听、挂断单人的音视频会话,可以在会话过程中进行暂停、恢复,并对会话过程进行监听。 - -1v1实时通话管理模块为EMCallManager,由EMClient模块加载时主动创建,可以使用EMClient模块的getCallManager方法获取,代码如下 - -``` -var callManager = emclient.getCallManager(); -``` - -## 注册消息回调监听 - -``` -function setCallManagerListener(callManager, listener) { -// 收到会话请求 -listener.onRecvCallIncoming((callsession) => { -// 在这里可以选择接通或者拒绝会话 -}); -// 会话连接上 -listener.onRecvCallConnected((callsession) => { -// 会话连接上之后,如果是应答方,需要Answer信息 -if(!callsession.getIsCaller()) -callManager.sendAnswer(callsession.getCallId()); -}); -// 会话已接通 -listener.onRecvCallAccepted((callsession) => {}); -// 会话挂断,reason为挂断原因,0挂掉,1无响应,2拒绝,3忙碌,4失败,5不支持,6离线 -listener.onRecvCallEnded((callsession,reason,error) => {}); -// 网络状态变化,toStatus状态:0连接,1不稳定,2断开 -listener.onRecvCallNetworkStatusChanged((callsession,toStatus) => {}); -// 对方会话状态变化,type值:0音频暂停,1音频恢复,2视频暂停,3视频恢复 -listener.onRecvCallStateChanged((callsession,type) => {}); -} -var managerlistener = new easemob.EMCallManagerListener(); -setCallManagerListener(callManager, managerlistener); -// 添加回调监听 -callManager.addListener(managerlistener); -//移除回调监听 -callManager.removeListener(managerlistener); -``` - -## 发起音视频会话 - -用户可以主动发起单人会话,方法如下 - -``` -/** -* 发起音视频会话asyncMakeCall -* @param remoteName Srign,对方用户ID,输入参数 -* @param type Number,会话类型,0为音频,1为视频,输入参数 -* @param ext String,会话扩展信息,应答方可见 -* return {code:{Number},description:{String},data:{EMCallSession}} -*/ -let result = callManager.asyncMakeCall(remoteName,type,ext); -``` - -## 接听音视频会话 - -接听会话方法一般在收到onRecvCallIncoming后调用,方法如下 - -``` -/** -* 接听音视频会话asyncAnswerCall -* @param callId,String,呼叫方ID,输入参数 -*/ -callManager.asyncAnswerCall(callId); -``` - -callId可以通过callsession的getCallId()方法获取。 - -## 发送Answer消息 - -发送Answer消息由接听方在会话连接上之后调用,即onRecvCallConnected中调用,只有接听方才需要调用此接口,方法如下 - -``` -/** -* 发送Answer消息 -* @param callId,String,呼叫方ID,输入参数 -*/ -callManager.sendAnswer(callId); -``` - -## 挂断音视频会话 - -用户可以在收到会话请求时,直接挂断会话,也可以在通话过程中挂断,调用挂断电话API时,需要传入挂断原因 - -``` -/** -* 接听音视频会话asyncEndCall -* @param callId,String,呼叫方ID,输入参数 -* @param reason,Number 结束原因,0挂掉,1无响应,2拒绝,3忙碌,4失败,5不支持,6离线 -*/ -callManager.asyncEndCall(callId,reason); -``` - -## 切换语音视频状态 - -``` -/** -* 修改会话类型,切换语音视频状态 -* @param {String} callId 呼叫方Id -* @param {Number} controlType 修改后的类型,0语音暂停,1为语音继续,2视频暂停,3视频继续 -*/ -callManager.updateCal(callId,controlType); -``` - -## 音视频配置 - -获取配置 - -``` -let emcallconfigs = callManager.getCallConfigs(); -// 呼叫时,若对方不在线,是否发送离线通知 -console.log("IsSendPushIfOffline:" + emcallconfigs.getIsSendPushIfOffline()); -// 视频宽度 -console.log("VideoResolutionWidth:" + emcallconfigs.getVideoResolutionWidth()); -// 视频高度 -console.log("VideoResolutionHeight:" + emcallconfigs.getVideoResolutionHeight()); -// 音视频心跳周期 -console.log("PingInterval:" + emcallconfigs.getPingInterval()); -``` - -设置配置 - -``` -// 呼叫时,若对方不在线,是否发送离线通知 -emcallconfigs.setIsSendPushIfOffline(true); -// 视频宽度,高度 -emcallconfigs.setVideoResolution(640,480); -// 音视频心跳周期 -emcallconfigs.setPingInterval(60); -callManager.setCallConfigs(emcallconfigs); -``` - -## 注册媒体流回调 - -会话接通后,需要使用音视频控件展示通话的音视频流,音视频流可通过注册回调得到,注册过程在注册消息回调监听时设置一次即可 - -``` -// 处理对方的音视频流,回调函数参数:remoteStream为对方音视频流,type为类型,0音频,1视频 -callManager.getRemoteStream((remoteStream,type) => {}); -// 处理本地的音视频流,回调函数参数:remoteStream为本地音视频流,type为类型,0音频,1视频 -callManager.getLocalStream((localStream,type) => {}); -``` - -## 发送离线通知 - -设置了若呼叫时,对方处于离线状态,执行的回调。当配置中设置了setIsSendPushIfOffline(true),该API可以应用。应用方法如下: - -``` -// 传入回调函数,回调函数的三个参数分别为本地发送方ID,对方ID,呼叫类型(0语音,1视频) -callManager.setSendPushMessage((from,to,type) => { -let textMsgBody = new easemob.EMTextMessageBody(type == 0?"语音请求":"视频请求"); -let textMsg = easemob.createSendMessage(from, to, textMsgBody); -let callback = new easemob.EMCallback(); - -textMsg.setCallback(callback) -emclient.getChatManager().sendMessage(textMsg); -}) -``` - -## 会话控制接口 - -音视频会话控制模块为EMCallSesssion,呼叫方通过asyncMakeCall返回,接听方通过监听回调的onRecvCallIncoming获取到。通过会话控制模块可以获取到以下会话信息 - -``` -// 获取CallId -console.log(callsession.getCallId()); -// 获取本地名称 -console.log(callsession.getLocalName()); -// 获取会话类型,0音频,1视频 -console.log(callsession.getType()); -// 获取对方名称 -console.log(callsession.getRemoteName()); -// 获取是否呼叫方 -console.log(callsession.getIsCaller()); -// 获取会话状态,0断开,1振铃,2正在连接,3已连接,4已接听 -console.log(callsession.getStatus()); -// 获取会话详情EMCallSessionStatistics -console.log(callsession.getStatistics()); -// 获取会话扩展信息 -console.log(callsession.getExt()); -// 修改会话状态,0音频暂停,1音频恢复,2视频暂停,3视频恢复 -console.log(callsession.update(controltype)); -``` \ No newline at end of file diff --git a/docs/private/media/one2one_vxmini.md b/docs/private/media/one2one_vxmini.md deleted file mode 100644 index 055aa16d..00000000 --- a/docs/private/media/one2one_vxmini.md +++ /dev/null @@ -1,17 +0,0 @@ -# 微信小程序集成1对1音视频通话 - ------- - -目前,微信小程序尚不支持1对1音视频通话; 如果需要1对1功能,可以通过多人音视频会议的方式来实现。 - -实现流程: - -1. 发起方创建一个会议; -2. 发起方加入会议; -3. 发起方发送一条消息给接收方(邀请消息),消息里包含会议Id和会议密码信息; -4. 接收方收到邀请消息后,也加入会议; -5. 结束通话时,直接退出会议,另一方收到对方退出会议事件,也退出会议 - -注意:用多人音视频会议实现1对1通话的方案,和android、iOS端的1对1通话是不能够互通的;如果需要互通,在android和iOS端也需要采用一样的方案。 - -请参考: [多人音视频会议](conference_vxmini.html) \ No newline at end of file diff --git a/docs/private/media/one2one_web.md b/docs/private/media/one2one_web.md deleted file mode 100644 index f4771f43..00000000 --- a/docs/private/media/one2one_web.md +++ /dev/null @@ -1,365 +0,0 @@ -# Web集成1对1通话 - -## 跑通Demo - -### 1. 示例代码 - -- [下载 Web SDK + Demo 代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/downloads/webdemo-3.4.2.7.zip) -- [体验Demo](https://zim-rtc.easemob.com:12005/) - -或进入环信[客户端下载](common_clientsdk.html#音视频sdk下载)页面,选择Web SDK + Demo下载 - -### 2. 前提条件 - -``` -1.安装一款 Easemob Web SDK 支持的浏览器 -2.本地安装 node 环境 >= 6.3.0 -``` - -### 3. 运行 Demo - -1. demo 目录结构 webim/demo -2. 进入 webim/demo 文件夹 -3. 安装依赖包 - -``` -npm install -``` - -4. 启动项目 - -``` -HTTPS=true npm start -``` - -## 快速集成 - -### 1. 环信后台注册 appkey - -在开始集成前,你需要注册环信开发者账号并在后台创建应用,参见[创建应用](../im/uc_configure.html#创建应用) 。 - -### 2. 创建项目 - -``` -a.可以简单的写一个 html,引入 SDK 测试 -b.或者使用 脚手架搭建一个项目 -``` - -### 3. 引入 SDK - -**1v1 需要依赖 IM SDK 进行通信,所以首先需要引入 IM SDK** - -#### 3.1 通过 scrpit 标签的 src 引入 - -``` - //im SDK - -``` - -#### 3.2 使用 npm 获取 SDK - -``` -npm install easemob-websdk --save -npm install easemob-webrtc --save -``` - -### 4. 初始化 SDK - - -#### 4.1 引入 sdk - -``` -import webrtc from 'easemob-webrtc' -``` - -#### 4.2 初始化 WebRTC Call,用于实现 1v1 音视频通话 - -``` -var rtcCall = new webrtc.Call({ - connection: conn, // WebIM 的链接信息 - mediaStreamConstaints: { - audio: true, - video: true - /** - * 修改默认摄像头,可以按照以下设置,不支持视频过程中切换 - * video:{ 'facingMode': "user" } 调用前置摄像头 - * video: { facingMode: { exact: "environment" } } 后置 - */ - }, - - listener: { - onAcceptCall: function (from, options) { - console.log('onAcceptCall::', 'from: ', from, 'options: ', options); - }, - //通过streamType区分视频流和音频流,streamType: 'VOICE'(音频流),'VIDEO'(视频流) - onGotRemoteStream: function (stream, streamType) { - console.log('onGotRemoteStream::', 'stream: ', stream, 'streamType: ', streamType); - var video = document.getElementById('video'); - video.srcObject = stream; - }, - onGotLocalStream: function (stream, streamType) { - console.log('onGotLocalStream::', 'stream:', stream, 'streamType: ', streamType); - var video = document.getElementById('localVideo'); - video.srcObject = stream; - }, - onRinging: function (caller, streamType) { - console.log("onRinging", caller) - }, - onTermCall: function (reason) { - console.log('onTermCall::'); - console.log('reason:', reason); - }, - onIceConnectionStateChange: function (iceState) { - console.log('onIceConnectionStateChange::', 'iceState:', iceState); - }, - // 通话断网监听 - onNetWorkDisconnect(endType) { // endType: local || remote, 哪一端断网 - console.log('1v1 onNetWorkDisconnect', endType); - }, - onError: function (e) { - console.log(e); - } - } -}); -``` - -### 5. 视频呼叫 - -**整个呼叫过程:** - -1. 主叫发起呼叫 -2. 被叫收到呼叫(主叫被叫分属于两个页面,通过服务器发送消息) -3. 被叫接受呼叫或者拒绝呼叫 -4. 主叫收到被叫接受或者拒绝的回调 -5. 通话建立成功 -6. 一方挂断另一方收到挂断的回调 - -**config 参数为主动呼叫时的配置参数(该功能主要用作web端对APP端呼叫时使用)** - -``` -var config = { - push: true, // 对方(app端)不在线时是否推送 - timeoutTime: 30000, // 超时时间 - txtMsg: 'I gave you a video call.', // 给对方发送的消息 - pushMsg: 'user is calling you' //推送内容 - }; -``` - -#### 5.1 主叫发起呼叫 - -``` -callBtn.onclick = function () { - rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字 - rtcCall.makeVideoCall(callee,null,true,true,config); -}; -``` - -在 rtcCall.makeVideoCall 方法中 注意以下参数的设置 - -- 第一个参数callee: 被呼叫人名字 必需 string -- 第二个参数 指定传 null 必需 null -- 第三个参数 是否开启录制 非必需 boolean -- 第四个参数 是否开启录制合并 非必需 boolean -- 第五个参数 主动呼叫扩展配置 非必需 object - -#### 5.2 被叫方收到呼叫回调 - -``` -// 初始化的函数 -var rtcCall = new webrtc.Call({ - ... - listener: { - ... - onRinging: function (caller, streamType) { - console.log("onRinging", caller) - }, - } -}); -``` - -#### 5.3 被叫方接受呼叫 - -``` -rtcCall.acceptCall() // 无参数 -``` - -#### 5.4 主叫方收到被叫接受呼叫的回调 - -``` -// 初始化的函数 -var rtcCall = new webrtc.Call({ - ... - listener: { - ... - onGotLocalStream: function (stream, streamType) { - // stream:媒体流,streamType:流类型 VIDEO 视频流、VOICE 语音流, 可根据不同的流类型做不同的UI展示 - var video = document.getElementById('localVideo'); - video.srcObject = stream; // 将流设置给 video标签 用于显示 - }, - } -}); -``` - -### 6. 关掉/拒绝通话 - -``` -rtcCall.endCall() // 无参数 -``` - -#### 6.1 收到通话结束的回调 - -``` -// 初始化的函数 -var rtcCall = new webrtc.Call({ - ... - listener: { - ... - onTermCall: function (reason) { - - }, - } -}); -``` - -### 7. 音频通话 - -``` -音频通话步骤与视频通话一致 -回调方法共用 -只是在回调中的 streamType 不同 -结束通话方法相同 -``` - -#### 7.1 发起音频通话 - -``` -callBtn.onclick = function () { - rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字 - rtcCall.makeVoiceCall('asdfghj',null,true,true,config); -}; -``` - -## 进阶功能 - -### 取日志 - -在控制台 调用 WebIM.EMedia.fileReport 方法可下载日志文件 - -``` -WebIM.EMedia.fileReport() // 无参数 -``` - -### 通话中音视频控制 - -调用 rtcCall.controlStream 方法可以控制 音视频的打开/关闭 - -``` -rtcCall.controlStream(controlType, to) -``` - -在 rtcCall.controlStream 方法中 注意以下参数的设置 - -- controlType: 操作类型 **0:打开麦克风;1:关闭麦克风;2:关闭摄像头;3:打开摄像头** ,必需 number -- to: 对方 userId,,必需 string - -**对方会收到回调函数** - -``` -// 对方操作音频的回调 opened: true:打开音频、false:关闭音频 -onOtherUserOpenVoice: function (from, opened) { } , - -// 对方操作视频的回调 opened: true:打开视频、false:关闭视频 -onOtherUserOpenVideo: function (from, opened) { }, -``` - -### 设置通话参数 - -可以在初始化 **rtcCall** 的时候,指定 **mediaStreamConstaints** 字段 -自定义分辨率、采样率 - -``` -var rtcCall = new webrtc.Call({ - ... - mediaStreamConstaints: { - audio: { //音频采样率 - sampleRate: 44100, - sampleSize: 16 - }, - video: { // 视频分辨率 宽度和高度 - width: { - exact: 1280 - }, - height: { - exact: 720 - } - } - }, -}, -``` - -### 离线推送 - -在进行视频或者音频呼叫的时候,可指定是否推送消息 - -``` -var config = { - push: true, // 对方(app端)不在线时是否推送 - ... -}; -callBtn.onclick = function () { - rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字 - rtcCall.makeVideoCall(callee,null,true,true,config); -}; -``` - -### 云端录制 - -在进行视频或者音频呼叫的时候,可指定是否录制和录制合并 - -``` -var option = { - callee: //被叫者, - rec: //是否开启录制, - recMerge: //是否开启录制合并, - config: //其他配置参数 -} -callBtn.onclick = function () { - rtcCall.caller = 'mengyuanyuan'; // 指定呼叫方名字 - rtcCall.makeVideoCall(option.callee,null,option.rec,option.recMerge,option.config); -}; -``` - -### 断网检测 - -**在通话进行前指定监听函数 onNetWorkDisconnect** - -``` -var rtcCall = new webrtc.Call({ - ... - listener: { - ... - onNetWorkDisconnect(endType) { // endType: local || remote, 哪一端断网 - console.log('1v1 onNetWorkDisconnect', endType); - }, - } -}) -``` - - -### 私有部署 - -私有部署设置方法参见[私有云sdk集成配置](../im/uc_Web_private.md)。 - -## 客户端API - -1V1音视频通话的API包括以下接口 - -- option 创建通话类的参数配置 -- makeVideoCall 发起视频呼叫 -- makeVoiceCall 发起音频呼叫 - -| 方法 | | -| :----------------------------------------------------------- | -------------- | -| [option](http://webim-h5.easemob.com/webrtc/jsdoc/out/-_Call.html) | 创建类时的配置 | -| [makeVideoCall](http://webim-h5.easemob.com/webrtc/jsdoc/out/global.html#makeVideoCall) | 发起视频通话 | -| [makeVoiceCall](http://webim-h5.easemob.com/webrtc/jsdoc/out/global.html#makeVoiceCall) | 发起音频通话 | \ No newline at end of file diff --git a/docs/private/media/overview.md b/docs/private/media/overview.md deleted file mode 100644 index 2fb8f507..00000000 --- a/docs/private/media/overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 音视频文档 - -## 1、XXXX diff --git a/docs/private/media/rest_introduction.md b/docs/private/media/rest_introduction.md deleted file mode 100644 index 6d980bae..00000000 --- a/docs/private/media/rest_introduction.md +++ /dev/null @@ -1,6 +0,0 @@ -# REST接口简介 - - -音视频云的REST接口规则与即时通讯的REST规则是一致的,参考[服务端集成](../../document/server-side/overview.md) - -在调用音视频云的REST接口前,需获取token,参考 [获取管理员权限](../../document/server-side/easemob_app_token.html#获取管理员权限-token) \ No newline at end of file diff --git a/docs/private/media/rest_manage.md b/docs/private/media/rest_manage.md deleted file mode 100644 index 08795a61..00000000 --- a/docs/private/media/rest_manage.md +++ /dev/null @@ -1,247 +0,0 @@ -# 会议管理 - - -环信使用 REST 的方式来对音视频会议进行管理操作,包括**创建会议**,**解散会议**,**获取会议**及**从会议中踢人**。 - -**注:** - -- 原会议类型模式目前已经进行优化,用户可以直接使用普通模式, 大会议模式和直播模式将弃用。 - -- 在[语音连麦聊天室](scenario_tc.html)中,环信仅使用了**创建会议**,**解散会议**两个API,开发者可根据自身需求,选择使用。 - -# REST API - -音视频会议管理在集成过程中,可以使用以下4个接口来对会议进行管理操作。请查看以下 REST API 详细文档说明。 - -| 名称 | 请求 | Method | -| :----------------- | :---------------------------------------------------- | :----- | -| 创建一个会议 | /{orgName}/{appName}/conferences | POST | -| 解散一个会议 | /{orgName}/{appName}/conferences/{confrId} | DELETE | -| 获取会议信息 | /{orgName}/{appName}/conferences/{confrId} | GET | -| 从会议中踢掉一个人 | /{orgName}/{appName}/conferences/{confrId}/{userName} | DELETE | - -## 创建会议 - -#### HTTP Request - -| ![img](/images/privitization/post.png) | /{org_name}/{app_name}/conferences | -| :----------------------------------------------------------- | :--------------------------------- | - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### Request Body - -| 名称 | 类型 | 描述 | -| :----------------------- | :------ | :----------------------------------------------------------- | -| confrType | int | 10: 普通模式 ~~11: 大会议模式 12: 直播模式~~ | -| password | string | 指定密码时,将使用此密码;不指定,将由服务端生成 | -| confrDelayMillis | long | 会议临时保留时长,指从会议创建成功到第一个用户加入会议之间的时长,单位是毫秒。超过这个保留时间,会议将被解散。第一个人加入会议之后,此保留时间失效,当最后一人离开会议,会议会立即被销毁。此参数默认是120秒,建议不要设置超过60分钟。 | -| memDefaultRole | int | 会议成员默认角色。用户A通过会议 ID 密码获取加入会议后的角色就是这个 1:观众,3:主播,7:管理员(拥有主播权限)。 缺省时,根据会议类型设置,目前规则如下:普通模式默认主播;~~大会议模式默认主播;直播模式默认观众~~ | -| allowAudienceTalk | boolean | true 允许观众上麦 | -| creator | string | 指定创建者,creator 将会成为这个会议的管理员,拥有管理员权限 | -| rec | boolean | true 此会议将被录制 | -| recMerge | boolean | true 此会议的所有通话将被合并到一个文件 | -| supportWechatMiniProgram | boolean | true 这个会议将支持小程序,同时会议编码被强制更新为H264,VP8。注意:默认的会议是不支持小程序的,如果想要支持小程序,请手动指定这个参数为true | -| useVCodes | 数组 | 指定会议将要采用的编码方式如[“H264”,“VP8”] | -| maxTalkerCount | int | 会议主播人数 | -| maxVideoCount | int | 会议最大视频数 | -| maxAudienceCount | int | 会议中的最大人数 | - -#### Response Body - -| 名称 | 类型 | 描述 | -| :---------------- | :------ | :----------------------------------------------------------- | -| type | int | 10: 普通模式 ~~11: 大会议模式 12: 直播模式~~ | -| talkerLimit | int | 主播上限数,~~大会议模式全部是是主播~~ | -| id | string | 会议ID | -| password | string | 会议密码 | -| allowAudienceTalk | boolean | 允许观众上麦,~~大会议模式时忽略此项~~ | -| audienceLimit | int | 观众上限数,~~大会议模式无观众~~ | -| expireDate | Date | 过期时间,创建会议后,如果在 expireDate 之前没有人加入会议,将会被系统强制解散 | - -#### 请求示例 - -``` -curl -L -X POST 'http://127.0.0.1:9090/easemob-demo/hcl/conferences' \ ---header 'Content-Type: application/json' \ ---header 'Authorization: Bearer YWMtaJszCI5vEemOhnkmxEo52QAAAAAAAAAAAAAAAAAAAAHmqirKW28R6ZB2cYf5QmSUAQMAAAFrVLgKfgBPGgC863CANqOsZOAF1tnxLeMc0Z-gRFCQwqV-0MB5nVAB5A' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "confrType": 10, - "password": "", - "confrDelayMillis": 100000, - "memDefaultRole":3, - "allowAudienceTalk": false, - "confrId": "", - "creator":"122", - "rec":false, - "recMerge":false, - "supportWechatMiniProgram": true, - "useVCodes": [ - "H264", - "VP8" - ], - "maxTalkerCount":9, - "maxVideoCount":9, - "maxAudienceCount":20 - - -}' -``` - -#### 可能返回的结果示例 - -- 返回值200,表示会议创建成功 -- 返回值401,未授权[无token、token错误、token过期] -- 返回值403,没有开通音视频增值服务调用接口失败 - -``` -{ - "error": 0, - "id": "IM3SKW51SKH4TB80LV45000C7", - "type": 10, - "mixed": false, - "password": "0.37898245722568236", - "audienceLimit": 600, - "talkerLimit": 6, - "expireDate": "2019-06-14 15:41:58", - "allowAudienceTalk": true -} -``` - - - ------- - -## 解散会议 - -#### HTTP Request - -| ![img](/images/privitization/delete.png) | /{orgName}/{appName}/conferences/{confrId} | -| :----------------------------------------------------------- | :----------------------------------------- | - -需要在请求时对应填写{confrId},需要删除的会议 ID 。 - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### 请求示例 - -``` -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer YWMt7CoyjusbEeixOi3iod4eDAAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnJlhJIwBPGgCqtjiyVnR209iyr8kNbhJhhanNQDdP9CMmpK2G-NIUOQ' 'http://a1.easemob.com/easemob-demo/testapp/conferences/TURN25AIYAVxASW7PL1Q00C51' -``` - -#### 可能返回的结果 - -- 返回值200,表示会议解散成功 -- 返回值404,表示该会议ID不存在 -- 返回值401,未授权[无token、token错误、token过期] -- 返回值403,没有开通音视频增值服务调用接口失败 - ------- - -## 踢掉会议中成员 - -#### HTTP Request - -| ![img](/images/privitization/delete.png) | /{orgName}/{appName}/conferences/{confrId}/{userName} | -| :----------------------------------------------------------- | :----------------------------------------- | - -需要在请求时对应填写{confrId},需要删除的会议 ID 。 - -userName为成员用户名。 - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### 请求示例 - -``` -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer YWMt7CoyjusbEeixOi3iod4eDAAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnJlhJIwBPGgCqtjiyVnR209iyr8kNbhJhhanNQDdP9CMmpK2G-NIUOQ' 'http://a1.easemob.com/easemob-demo/testapp/conferences/TURN25AIYAVxASW7PL1Q00C51/yangss' -``` - -#### 可能返回的结果 - -- 返回值200,表示会议解散成功 -- 返回值404,表示该会议ID不存在 -- 返回值401,未授权[无token、token错误、token过期] -- 返回值403,没有开通音视频增值服务调用接口失败 - ------- - -## 获取会议信息 - -#### HTTP Request - -| ![img](/images/privitization/get.png) | /{orgName}/{appName}/conferences/{confrId} | -| :----------------------------------------------------------- | :----------------------------------------- | - -需要在请求时对应填写{confrId},需要获取的会议 ID 。 - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### Response Body - -| 名称 | 类型 | 描述 | -| :---------------- | :------ | :----------------------------------------------------------- | -| type | int | 10: 普通模式 ~~11: 大会议模式 12: 直播模式~~ | -| talkerLimit | int | 主播上限数,~~大会议模式全部是是主播~~ | -| id | string | 会议ID | -| password | string | 会议密码 | -| allowAudienceTalk | boolean | 允许观众上麦,~~大会议模式时忽略此项~~ | -| audienceLimit | int | 观众上限数,~~大会议模式无观众~~ | -| expireDate | Date | 过期时间,创建会议后,如果在 expireDate 之前没有人加入会议,将会被系统强制解散 | -| mems | Array | 现有成员列表 | - -#### 请求示例 - -``` -curl -X GET \ - http://a1.easemob.com/1100181023201864/voicechatroom/conferences/IM3SKW51SKH4TB80LV45000C7 \ - -H 'Accept: */*' \ - -H 'Authorization: Bearer YWMtaJszCI5vEemOhnkmxEo52QAAAAAAAAAAAAAAAAAAAAHmqirKW28R6ZB2cYf5QmSUAQMAAAFrVLgKfgBPGgC863CANqOsZOAF1tnxLeMc0Z-gRFCQwqV-0MB5nVAB5A' -``` - -#### 可能返回的结果示例 - -- 返回值200,表示会议获取成功 -- 返回值404,表示该会议ID不存在 -- 返回值401,未授权[无token、token错误、token过期] -- 返回值403,没有开通音视频增值服务调用接口失败 - -``` -{ - "error": 0, - "id": "13H05522N8TEXW49ESW00C10618", - "type": 11, - "mixed": true, - "password": "", - "audienceLimit": 0, - "talkerLimit": 30, - "allowAudienceTalk": true, - "mems": [{ - "memberId": "13H05522N8TEXW49ESW00C10618M2", - "memName": "easemob-demo#chatdemoui_lulu3", - "role": 7 - }] -} -``` - diff --git a/docs/private/media/rest_record.md b/docs/private/media/rest_record.md deleted file mode 100644 index 28f480d0..00000000 --- a/docs/private/media/rest_record.md +++ /dev/null @@ -1,305 +0,0 @@ -# 录制及提取 - - - -环信使用 REST 的方式来获取实时音视频的录制文件,包括录制的音频文件和视频文件。 - -- 录制功能可以调用SDK接口控制开启,支持1v1录制和多人录制以及录制合成。 -- 录制文件默认仅在音视频服务器保存30天,到期后会进行删除,如需长期使用,请在部署前确认保存时长。 -- 录制系统会自动根据音视频编码选择文件格式,一般是.webm,.mkv和.mp4三种;合成录制文件固定为.mp4格式。 -- 如果需要其他格式,用户可以自己下载转换,转换工具建议用ffmpeg。 -- 获取录制文件后,如果需要下载,需要通过文件详情中的URL直接下载保存。 -- SDK开启录制 - - [Android 1v1](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_call_manager.html#af7447a6669e37d5d0bbf976b098b435b) - - [Android 多人](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#a6a9bd493a33203869d37780d7f8cdbfe) - - [iOS 1v1](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_call_manager-p.html#a429bded3e8040875d02e84936cd75521) - - [iOS 多人](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7cd6cdf1b116964fe114d700baf26dc6) - - [Web 1v1](http://webim-h5.easemob.com/webrtc/jsdoc/out/global.html#makeVideoCall) - - [Web 多人](http://webim-h5.easemob.com/emedia/jsdoc/out/global.html#createConference) -- 获取录制文件时所需要的confrId,可以从SDK中获取,下面以新版本SDK属性名称为例,老版本以各端SDK头文件内的属性名称为准。 - - 移动端: - - iOS: - - 1v1时:在监听通话建立完成的回调中 - (void)callDidConnect:(EMCallSession *)aSession,通过 aSession.serverVideoId 获取(serverVideoId为 EMCallSession 的属性,只有在通话建立完成后通过 EMCallSession 才能拿到 serverVideoId,否则在通话未建立完成时通过 EMCallSession 取到 serverVideoId 的为空); - - 多人时:在创建并加入会议 createAndJoinConferenceWithType 或者加入会议室 joinConferenceWithConfId 成功后,通过回调中的 EMCallConference 对象 aCall.confId 获取到; - - Android: - - 1v1时:在通话状态改变的监听中 void onCallStateChanged (CallState callState, CallError error),通过判断 callState 的状态为 connected 通话建立完成时,通过 EMCallSession 的 getServerRecordId () 获取到录制文件id; - - 多人时:在创建并加入会议 createAndJoinConference 或者加入会议室 joinConference 成功后,通过 callback 中的 EMConference 对象 调用 getConferenceId () 获取到; - - web端:1v1时为WebIM.call.getServerRecordId();多人时可以在createConference的回调里拿到; - -服务器端存储的是压缩后的视频。录制文件的大小(每分钟)为: - -- 240p: 0.75M ~ 3M -- 480p: 2.2M ~ 7.5M -- 720p: 6.5M ~ 18.5M -- 1080p: 15M ~ 37.5M - - - -:::tip -1、通话时长<5s可能会出现服务器录制失败的情况。
-2、生成录制文件所花的时间和通话时长有关,通话时间越长,生成录制文件的时间也越长。一般情况下,通话时间1小时以下,在通话结束后2小时可以获取到,为了保证录制文件数据完整建议在24小时后获取。 -::: - ------- - -# REST API - -服务器录制文件获取在集成过程中,可以使用以下4个接口获取录制文件。请查看以下 REST API 详细文档说明。 - -| 名称 | 请求 | -| :------------------------------- | :----------------------------------------------------------- | -| 会议ID获取全部录制文件 | {orgName}/{appName}/audio/{confrId} | -| 开始结束时间获取全部录制文件 | {orgName}/{appName}/audio/{beginTime}/{endTime}/{startId}/{length} | -| 开始结束时间获取全部合成录制文件 | {orgName}/{appName}/audio/merge/{beginTime}/{endTime}/{startId}/{length} | -| 获取会议内user全部录制文件 | {orgName}/{appName}/audio/{userName}/{confrId} | - -## 会议ID获取全部录制文件 - -通过指定会议ID获取全部的录制文件。 - -:::tip -录制的文件默认保存30天。 -::: -#### HTTP Request - -| ![img](/images/privitization/get.png) | **{orgName}/{appName}/audio/{confrId}** | -| :----------------------------------------------------------- | :-------------------------------------- | - -需要在请求时对应填写{confrId}会议ID,如果当前没有会议ID,请从其他接口获取。 - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### Response Body - -返回的文件数据列表是以文件编号id,升序排列。 - -| 参数 | 说明 | -| :------------- | :----------------------------------------------------------- | -| id | 录制文件数字编号 | -| owner | 录制文件所在的appkey | -| confrBeginTime | 录制文件所在多人会议的开始时间 | -| confrEndTime | 录制文件所在多人会议的结束时间 | -| confrType | 会议类型,“CONFR”、“COMMUNICATION”均是普通会议、~~“COMMUNICATION_MIX”混音会议最多支持30人以下的音频混合、“LIVE”互动会议~~ | -| confrId | 会议ID,全局唯一 | -| userName | 参加会议人员,以appkey_username表示(talker,直播模式下的主播) | -| memberName | 参加会议人员,以appkey_username表示(talker,直播模式下的主播)IM情况下为 JID,系统唯一的ID | -| accessId | 参加会议时链接的ID | -| pubStreamId | 推流ID | -| recordType | 录制文件类型,“ONLY_REC_ONE_AV”是单人音视频,“ONLY_REC_ONE_DESKTOP”是单人共享桌面,“MERGE_ALL”合成视频文件 | -| recordTime | 录制完成时间 | -| expireTime | URL过期时间 | -| url | 录制文件的下载链接 | - -#### 请求示例 - -``` -curl -X GET -i "http://a1.easemob.com/easemob-demo/testapp/audio/IM_X364829524644331520C14" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json' -``` - -#### 可能返回的结果示例 - -- 返回值200,表示成功获取录制文件 -- 返回结果是500,可能是服务器故障 -- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html) - -``` -{ - "id": 109, - "owner": "easemob-demo#testapp", - "confrBeginTime": "2019-02-21 17:56:04", - "confrEndTime": "2019-02-21 17:56:46", - "confrType": "LIVE", - "confrId": "IM_X364829548358926336C16", - "memberId": "IM_X364829548358926336C16M21", - "memberName": "easemob-demo#testapp_user1", - "userName": "easemob-demo#testapp_user1", - "accessId": "HI365195406759428096", - "pubStreamId": "rtc-10-xbd__Of_C16M21", - "recordType": "ONLY_REC_ONE_AV", - "recordTime": "2019-02-21 17:56:49", - "expireTime": "2019-03-23 17:56:49", - "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/1esugl4lgti4qbtle1l450gunvphf9uhi3kmb6b9rdc10cn0jf8g/20190221170556-000000410.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=tpQRDw0HS9feBkgnvmYObY2U850%3D" -} -``` - - - ------- - -## 开始结束时间获取全部录制文件 - -开始到结束时间内,以某个录制文件为起始点,获取之后一定数量的录制文件接口。 - -:::tip -录制的文件默认保存30天。 -::: - -#### HTTP Request - -| ![img](/images/privitization/get.png) | **{orgName}/{appName}/audio/{beginTime}/{endTime}/{startId}/{length}** | -| :----------------------------------------------------------- | :----------------------------------------------------------- | - - -需要在请求时对应填写{beginTime}/{endTime},起始录制文件id编号{startId},获取的数量{length}。`length限制长度是100,如果请求超过100是会返回错误`。 - - **如果要取从开始至结束时间的前100个录制文件,起始录制文件id可以为0,获取数量100;如果要继续获取后面的100个录制文件,需要将上次获取的最后一个录制文件id作为下一次请求的起始id继续发起请求。** - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### 请求示例 - -``` -curl -X GET -i "http://a1.easemob.com/easemob-demo/testapp/audio/20190101080607/20190304050607/0/2" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json' -``` - -#### 可能返回的结果示例 - -- 返回值200,表示成功获取录制文件 -- 返回结果是500,可能是服务器故障 -- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html) - - -``` -{ - "id": 112, - "owner": "easemob-demo#testapp", - "confrBeginTime": "2019-02-21 17:56:04", - "confrEndTime": "2019-02-21 17:56:46", - "confrType": "LIVE", - "confrId": "IM_X364829548358926336C16", - "memberId": "IM_X364829548358926336C16M21", - "memberName": "easemob-demo#testapp_user1", - "userName": "easemob-demo#testapp_user1", - "accessId": "HI365195406759428096", - "recordType": "ONLY_REC_ONE", - "recordTime": "2019-02-21 17:56:49", - "expireTime": "2019-03-23 17:56:49", - "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/mlgh7n0ltu09sehvst53dh8huurqrj6f5knbhfbnopppgoocr67/20190221170556-000000408.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=hZk4jJDcMsuJfioscv%2B4L1zk1aA%3D" -} -``` - - ------- - -## 开始结束时间获取全部合成录制文件 - -开始到结束时间内,以某个录制文件为起始点,获取之后一定数量的合成录制文件接口。 - -:::tip -录制的文件默认保存30天。 -::: - -#### HTTP Request - -| ![img](/images/privitization/get.png) | **{orgName}/{appName}/audio/merge/{beginTime}/{endTime}/{startId}/{length}** | -| :----------------------------------------------------------- | :----------------------------------------------------------- | - -需要在请求时对应填写{beginTime}/{endTime},起始录制文件id编号{startId},获取的数量{length}。`length限制长度是100,如果请求超过100是会返回错误`。 - -**如果要取从开始至结束时间的前100个合成录制文件,起始录制文件id可以为0,获取数量100;如果要继续获取后面的100个合成录制文件,需要将上次获取的最后一个合成录制文件id作为下一次请求的起始id继续发起请求。** - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### 请求示例 - -``` -curl -X GET -i "http://a1.easemob.com/easemob-demo/testapp/audio/merge/20190101080607/20190304050607/0/2" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json' -``` - -#### 可能返回的结果示例 - -- 返回值200,表示成功获取录制文件 -- 返回结果是500,可能是服务器故障 -- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html) - - -``` -{ - "id": 112, - "owner": "easemob-demo#testapp", - "confrBeginTime": "2019-02-21 17:56:04", - "confrEndTime": "2019-02-21 17:56:46", - "confrType": "LIVE", - "confrId": "IM_X364829548358926336C16", - "memberId": "IM_X364829548358926336C16M21", - "memberName": "easemob-demo#testapp_user1", - "userName": "easemob-demo#testapp_user1", - "accessId": "HI365195406759428096", - "recordType": "MERGE_ALL", - "recordTime": "2019-02-21 17:56:49", - "expireTime": "2019-03-23 17:56:49", - "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/mlgh7n0ltu09sehvst53dh8huurqrj6f5knbhfbnopppgoocr67/20190221170556-000000408.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=hZk4jJDcMsuJfioscv%2B4L1zk1aA%3D" -} -``` - - ------- - -## 获取会议内user全部录制文件 - -指定会议ID内的用户获取全部录制文件。 - -:::tip -录制的文件默认保存30天。 -::: - -#### HTTP Request - -| ![img](/images/privitization/get.png)| **{orgName}/{appName}/audio/{userName}/{confrId}** | -| :----------------------------------------------------------- | :------------------------------------------------- | - -需要在请求时对应填写{confrId}会议ID,如果当前没有会议ID,请从其他接口获取。以及{userName}用户名。 - -#### Request Headers - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### 请求示例 - -``` -curl -X GET "http://a1.easemob.com/easemob-demo/testapp/audio/user1/IM_X364829524644331520C14" -H 'Authorization: Bearer YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw' -H 'Content-Type: application/json' -``` - -#### 可能返回的结果示例 - -- 返回值200,表示成功获取录制文件 -- 返回结果是500,可能是服务器故障 -- 返回结果是**429、503**或者其他**5xx**,有可能代表该接口被限流了,请稍微暂停一下并重试。详见[接口限流说明](../../product/limitationapi.html) - - -``` -{ - "id": 112, - "owner": "easemob-demo#testapp", - "confrBeginTime": "2019-02-21 17:56:04", - "confrEndTime": "2019-02-21 17:56:46", - "confrType": "LIVE", - "confrId": "IM_X364829548358926336C16", - "memberId": "IM_X364829548358926336C16M21", - "memberName": "easemob-demo#testapp_user1", - "userName": "easemob-demo#testapp_user1", - "accessId": "HI365195406759428096", - "recordType": "ONLY_REC_ONE", - "recordTime": "2019-02-21 17:56:49", - "expireTime": "2019-03-23 17:56:49", - "url": "http://kefu-media-files.oss-cn-beijing.aliyuncs.com/mlgh7n0ltu09sehvst53dh8huurqrj6f5knbhfbnopppgoocr67/20190221170556-000000408.webm?Expires=9223372036854775&OSSAccessKeyId=LTAI3pBwoxnmCWUw&Signature=hZk4jJDcMsuJfioscv%2B4L1zk1aA%3D" -} -``` diff --git a/docs/private/media/rest_whiteboard.md b/docs/private/media/rest_whiteboard.md deleted file mode 100644 index cfbf2903..00000000 --- a/docs/private/media/rest_whiteboard.md +++ /dev/null @@ -1,89 +0,0 @@ -# 互动白板REST简介 - -| 名称 | 请求 | method | -| ---------------- | ---------------------------------------------------------- | ------ | -| 创建或者加入白板 | /{orgName}/{appName}/whiteboards/joinorcreate/byname | POST | -| 上传文件 | /{orgName}/{appName}/whiteboards/upload/{whiteboardUserId} | POST | - -## 创建或者加入白板 - -HTTP Request - -| ![img](/images/privitization/post.png) | /{orgName}/{appName}/whiteboards/joinorcreate/byname | -| ---- | ---------------------------------------------------- | - -| 参数 | 说明 | -| :------------ | :--------------- | -| Content-Type | application/json | -| Authorization | Bearer ${token} | - -#### Request Body - -| 名称 | 类型 | 描述 | -| :------------- | :----- | :----------------------------------------------------------- | -| userId | String | im用户的userId | -| whiteBoardName | String | 将要创建或者加入的白板名称 | -| password | String | 白板密码 | -| level | int | 共1-8级,创建白板时可以指定白板成员的默认等级,4级及以上可以操作白板,以下不能操作 | -| layout | int | 页面布局,共三种分别取0/1/2 | -| ratio | String | 页面比例比如2:1,比例范围为1:5至5:1 | - -#### Response Body - -| 名称 | 类型 | 描述 | -| :------------ | :------ | :------------------------------------ | -| whiteBoardUrl | string | 将要打开的白板地址 | -| domainName | String | 白板的域名 | -| socketIOUrl | String | SocketIO链接地址 | -| socketIOPath | String | SocketIO链接路径 | -| roomId | String | 白板系统的userId,注意这不是IM的userId | -| token | String | 白板的token | -| status | boolean | 请求状态 | - -#### 请求示例 - -``` -curl -L -X POST 'http://127.0.0.1:8031/easemob-demo/chatdemoui/whiteboards/joinorcreate/byname' \ ---header 'Authorization: Bearer YWMtmSQukKrsEeqv9QV7AzcHWwAAAAAAAAAAAAAAAAAAAAFDtjwasNNKD6W3CET2O3RNAQMAAAFynSVq-wBPGgBKfz02AUoGLesKFexM4_1uAAW25lj33z0siltXBgRoWQ' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "userId": "zd2", - "whiteBoardName": "128", - "password": "1", - "level":5 -}' -``` - -根据请求返回的status字段判断请求是否成功 - -``` -{ - "whiteBoardUrl": "http://whiteboards-hsb.easemob.com/index.html?roomId=ZBXZH0001TGJ5AAYK400&userId=ZBXZH0001TGJ5AAYK400-0&socketIOUrl=http://127.0.0.1:8900/message&socketIOPath=/socket.io/&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3aGl0ZWJvYXJkIiwiaXNzIjoiZWFzZW1vYiIsInVzZXJOYW1lIjoiemQyIiwiZXhwIjoxNTk3NDg1NTExLCJ1c2VySWQiOiJaQlhaSDAwMDFUR0o1QUFZSzQwMC0wIn0.izUKAFrQBKRnDEg1d_yt-Xe9DGwZobb7Oa9-03yLO0Q&domainName=http://127.0.0.1:8031&appKey=easemob-demo#chatdemoui&isCreater=true", - "domainName": "http://127.0.0.1:8031", - "socketIOUrl": "http://127.0.0.1:8900/message", - "socketIOPath": "/socket.io/", - "userId": "ZBXZH0001TGJ5AAYK400-0", - "roomId": "ZBXZH0001TGJ5AAYK400", - "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3aGl0ZWJvYXJkIiwiaXNzIjoiZWFzZW1vYiIsInVzZXJOYW1lIjoiemQyIiwiZXhwIjoxNTk3NDg1NTExLCJ1c2VySWQiOiJaQlhaSDAwMDFUR0o1QUFZSzQwMC0wIn0.izUKAFrQBKRnDEg1d_yt-Xe9DGwZobb7Oa9-03yLO0Q", - "status": true -} -``` - -## 白板上传文件 - -HTTP Request 注意这里的whiteboardUserId不是IM的useId,是上一个创建或者加入白板里返回的userId - -| ![img](/images/privitization/post.png) | /{orgName}/{appName}/whiteboards/upload/{whiteboardUserId} | -| ---- | ---------------------------------------------------------- | - -#### 请求示例 - -``` -curl -L -X POST 'http://127.0.0.1:8031/easemob-demo/chatdemoui/whiteboards/upload/ZBW51UX8XTGFYJX8LL0-0' \ ---header 'Content-Type: multipart/form-data' \ ---form 'file=@/D:/easemob/文档/中文名字1.jpg' -``` - -#### 返回值 - -- 返回200表示成功 \ No newline at end of file diff --git a/docs/private/media/scenario_live.md b/docs/private/media/scenario_live.md deleted file mode 100644 index 454c172e..00000000 --- a/docs/private/media/scenario_live.md +++ /dev/null @@ -1,84 +0,0 @@ -# 多人视频互动直播场景介绍 - -## 概述 - -环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。 - -![img](/images/privitization/em-rtcsdk-scenarios.png) - -多人音视频互动直播的典型场景包括多人视频相亲、线上KTV、狼人杀直播、教育小班课、教育双师课等。 - -## 多人视频互动直播与传统CDN直播的区别 - -很多开发者和产品经理经常会问,我要做一个直播产品,我应该用传统CDN直播,还是应该用多人视频互动直播呢? - --传统CDN直播是主播推流到CDN,观众从CDN拉流观看。主播和观众之间是一对多的单向关系。主播与观众或观众之间的互动主要通过[文字聊天室](../../document/server-side/overview.html#聊天室管理)来实现,比如聊天室消息、弹幕、刷礼物等。传统CDN直播最大的优点是可以支持极高的同时在线人数,数百万数千万都不是问题,但互动性稍弱。 - --多人视频互动直播则可以有多个主播进行远程的视频连麦互动,观众上麦后,也可以与主播之间进行视频连麦互动。 - -**多人视频互动极大丰富了直播的可玩度,带来了很多新型应用场景,比如远程培训直播、教育小班课、双师课等。** - -## 多人视频互动直播与多人音视频会议的区别 - -1. 从产品角度看,多人音视频会议和多人音视频互动直播的主要区别是:
-- 多人音视频会议的所有参会者都有相同的权利,都可以随时发布音频和视频,也就是说,每个人都是主播。 - -- 多人音视频互动直播的参会者除了主播外,还有观众。观众只能观看,如果要发布音频和视频,需要申请上麦,切换到主播角色。 - -2. 从技术架构角度看,多人音视频会议和多人音视频互动直播使用的是相同的技术架构--**媒体流发布和订阅的技术架构**,主要区别是: -:::tip -发布是指参会者发布媒体流(即发言,包括视频流和音频流)到服务器,其他人收到发布事件然后去订阅拉取媒体流。 -::: -- 多人音视频会议场景中,在创建会议时指定默认角色为主播,即每个参会者加入会议后都可以发言。 - -- 多人音视频互动直播场景中,在创建会议时指定默认角色为观众,除了管理员(同时也可以是主播)以外,其他人默认是观众。管理员可以设置指定观众成主播实现上麦操作;或设置指定主播为观众,实现下麦操作。 - -3. 相同点:
- -**多人音视频里有管理员,主播和观众三种角色** - -- 管理员拥有最高权限,可以发布媒体流,订阅媒体流,设定其他人是主播还是观众 -- 主播可以发布媒体流,订阅媒体流 -- 观众只有订阅媒体流权限 - -**多人音视频会议和多人音视频互动直播模式都支持白板、共享桌面** - -## 实现方案 - -多人视频会议开发的入口文档是:[多人通话简介](conference_introduction)。这个文档包含了以下部分: - -- 功能列表:各端功能清单 -- 通话流程:通话流程描述 -- 角色权限:会议室的角色权限说明 -- 客户端SDK及demo源码:开发者可以先下载demo,体验demo中的一对一音视频功能。如有需要,还可以查看demo的源代码。 -- 计费说明 - - -多人视频会议如果需要环信即时通讯云的文字聊天室实现IM沟通功能,请详见文档: - -服务器端: [聊天室管理](http://doc.easemob.com/document/server-side/chatroom.html) - -Android: [聊天室管理](http://doc.easemob.com/document/android/room_overview.html) - -iOS: [聊天室管理](http://doc.easemob.com/document/ios/room_overview.html) - -web端: [聊天室管理](http://doc.easemob.com/document/web/room_overview.html) - -微信小程序: [聊天室管理](http://doc.easemob.com/document/applet/room_overview.html) - -PC端: [聊天室管理](https://docs-im.easemob.com/im/pc/basics/chatroom) - - - \ No newline at end of file diff --git a/docs/private/media/scenario_meeting.md b/docs/private/media/scenario_meeting.md deleted file mode 100644 index fb3db517..00000000 --- a/docs/private/media/scenario_meeting.md +++ /dev/null @@ -1,119 +0,0 @@ -# 视频会议场景方案介绍 - -## 概述 - -环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。 - -![img](/images/privitization/em-rtcsdk-scenarios.png) - -多人音视频会议的典型场景包括企业多人视频会议、移动协同办公、远程医疗会诊、会诊模式的视频客服等。 - -## 典型需求 - -多人视频会议场景的典型功能需求包括: - -- 多人音频通话 -- 多人视频通话 -- 共享桌面 -- 外部视频源输入 -- 美颜 -- 服务器端录制及下载 -- 即时沟通:在使用多人会议时,也可以通过集成环信即时通讯实现IM沟通,如发文字、图片、语音片段、各种自定义消息等) -- 视频流水印 -- 会议室的管理:创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室 -- 会议室的人员管理:获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等 -- 多端支持:Android、iOS、Web、PC、小程序 - -:::tip -在多人视频会议场景下用到的某些功能需要在特定的浏览器、版本或插件下才能使用。
所以为了简化用户体验,不推荐直接使用浏览器,**建议引导用户使用本地应用(如PC端应用)**。 - -::: -## 实现方案 - -1. 多人视频会议开发的入口文档是:[多人通话简介](conference_introduction),这个文档包含了以下部分: - -- 功能列表:各端功能清单 -- 通话流程:通话流程描述 -- 角色权限:会议室的角色权限说明 -- 客户端SDK及demo源码:开发者可以先下载demo,体验demo中的一对一音视频功能。如有需要,还可以查看demo的源代码。 -- 计费说明 - - -2. 多人视频会议如果需要环信即时通讯云的文字聊天室实现IM沟通功能,请详见文档: - -服务器端: [聊天室管理](http://doc.easemob.com/document/server-side/chatroom.html) - -Android: [聊天室管理](http://doc.easemob.com/document/android/room_overview.html) - -iOS: [聊天室管理](http://doc.easemob.com/document/ios/room_overview.html) - -web端: [聊天室管理](http://doc.easemob.com/document/web/room_overview.html) - -微信小程序: [聊天室管理](http://doc.easemob.com/document/applet/room_overview.html) - -PC端: [聊天室管理](https://docs-im.easemob.com/im/pc/basics/chatroom) - - - - -## 客户端应用源码 - -“环信视频会议”Demo主要面向开发者,用于演示如何通过调用音视频API实现视频会议基础功能,如需打造产品级别应用,要按自身项目需求完成UI/UE设计。 - -### Demo 下载 - -Demo下载地址请见: [demo下载](common_clientsdk#场景demo及源码下载) - -### Demo 源码 - -我们在 Github 提供了完整的 Demo源代码,大家可以在 Github 上获取。 - -- [Android](https://github.com/easemob/videocall-android) - -- [iOS](https://github.com/easemob/videocall-ios) - -- [Web](https://github.com/easemob/videocall-web) - -- [桌面](https://github.com/easemob/videocall-web) (桌面端使用electron打包了web端的代码,跟web端是同一套代码) - - -### Demo 功能介绍 - -#### **创建或加入房间** - -1. 创建房间:在本页面,输入一个不存在的房间号和密码,可以创建新房间
-2. 加入房间:如果输入当前存在的房间号,则加入现有房间 - -:::tip -请选择“以主播身份进入房间”。
-“以观众身份进入房间”属于环信多人音视频互动直播API的一部分,使用说明请见 [互动直播介绍](scenario_live) -::: -![img](/images/privitization/meeting-demo4.png?w=300) -#### **音视频会议主界面** - -在音视频会议的主界面,演示了以下功能: - -- 打开或关闭麦克风。 -- 打开或关闭摄像头。切换前后摄像头。 -- 查看当前会议室参会人员名单 -- 踢人 -- 上麦、下麦 -- 退出会议室 - -:::tip -“上麦/下麦”属于环信多人音视频互动直播API的一部分,使用说明请见 [互动直播介绍](scenario_live) -::: - -![img](/images/privitization/meeting-demo5.png?w=300) \ No newline at end of file diff --git a/docs/private/media/scenario_one2one.md b/docs/private/media/scenario_one2one.md deleted file mode 100644 index 06437dd4..00000000 --- a/docs/private/media/scenario_one2one.md +++ /dev/null @@ -1,44 +0,0 @@ -# 1对1音视频场景介绍 - -## 概述 - -环信音视频能力有几种典型的应用模式,包括:一对一音视频、多人音视频会议、多人音视频互动直播。 - -![img](/images/privitization/em-rtcsdk-scenarios.png) - -一对一音视频用于实现1对1语音通话和1对1视频通话,典型场景包括社交交友,远程心理咨询、远程医疗、视频面试、一对一在线教育、远程视频辅助等。 - -## 需求 - -1对1音视频场景的主要功能需求包括: - -- 1对1音频通话 -- 1对1视频通话 -- 外部视频源输入:用户可自行采集视频数据,比如接入外部摄像头;这个功能也可以用于对接第三方美颜,变声等。以Android为例,请参考[用户自定义数据采集及数据处理](one2one_android.html#变声-自定义音频)接口文档 -- 美颜 -- AI鉴黄 -- 服务器端录制及下载 -- 即时沟通:在使用音视频服务时,也可以通过集成环信即时通讯实现IM沟通,如发文字、图片、语音片段、各种自定义消息等 - -## 实现方案 - -1. 一对一音视频开发的入口文档是:[1对1通话简介](one2one_introduction.html),这个文档包含了以下部分: - -- 功能列表:各端功能清单 -- 通话流程:通话流程描述 -- 客户端SDK及demo源码:开发者可以先下载demo,体验demo中的一对一音视频功能。如有需要,还可以查看demo的源代码。 -- 计费说明 - -2. 一对一音视频还需要用到环信即时通讯云的基础IM功能,请详见文档: - -服务器端:[服务端集成](http://doc.easemob.com/document/server-side/overview.html) - -Android:[Android SDK 介绍及导入](http://doc.easemob.com/document/android/quickstart.html) - -iOS:[iOS SDK 快速集成](http://doc.easemob.com/document/ios/quickstart.html) - -web端: [Web IM 介绍](http://doc.easemob.com/document/web/quickstart.html) - -微信小程序: [微信小程序SDK简介](http://doc.easemob.com/document/applet/wechat.html) - -PC端: [桌面端集成说明](https://docs-im.easemob.com/im/pc/intro/integration) \ No newline at end of file diff --git a/docs/private/media/scenario_tc-host.md b/docs/private/media/scenario_tc-host.md deleted file mode 100644 index 1f3434f9..00000000 --- a/docs/private/media/scenario_tc-host.md +++ /dev/null @@ -1,33 +0,0 @@ -# 主持模式 - -## 前言 -本文将简要分享语音聊天室中主持玩法的的应用场景,并讲述基于环信语聊解决方案,主持玩法的实现步骤。 - -:::tip -`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。 -::: - -主持玩法是目前语音连麦聊天室中必备的玩法之一,通过房主的主持,大家可以有序的进行发言,更好的组织聊天室的互动场景。 - -在主持模式,由房主指定谁可以发言,被指定的主播可以发言,其他人不能发言。这个功能是通过会议属性来实现的,当房主指定发言人后,房主修改会议属性,所有人收到会议属性变更通知,如果发现会议属性中是指定的自己发言,自己打开麦克风。其他人关闭。当房主指定另外一个主播发言时,房主修改会议属性,所有人收到会议属性变更通知,当前主播自动下麦。 - -## 实现方案 -我们可以通过一张图,来了解主持模式中接口的调用逻辑: - -![img](/images/privitization/tc_logic_host.png) - -上图中每步涉及到的iOS/Android接口如下: - -| 步骤 | iOS API | Android API | -| :--------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | -| 1.设置主持会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | -| 2.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | -| 3.指定某个主播发言,并修改会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | -| 4.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | -| 5.指定者说话,其他人闭麦 | [EMClient.sharedClient.conferenceManager updateConference: isMute:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | [EMClient.getInstance().conferenceManager().openVoiceTransfer();EMClient.getInstance().conferenceManager().closeVoiceTransfer();](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a7b4bd022d9daf8fe127d89494897bf99) | -| 6.指定某个主播发言,并修改会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | -| 7.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | -| 8.指定者说话,其他人闭麦 | [EMClient.sharedClient.conferenceManager updateConference: isMute:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | [EMClient.getInstance().conferenceManager().openVoiceTransfer();EMClient.getInstance().conferenceManager().closeVoiceTransfer();](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a7b4bd022d9daf8fe127d89494897bf99) | - -语音聊天室可根据业务模型提供多种模式与玩法。目前环信提供的语聊集成方案对准备开发和正在集成聊天室的开发者来说,不仅可以更好的理解环信 IM 即时通讯、音视频所提供的丰富功能,还能通过产品层面的操作,帮助开发者构思出更多的互动玩法,扩展更多有意思的场景。 - diff --git a/docs/private/media/scenario_tc-robmic.md b/docs/private/media/scenario_tc-robmic.md deleted file mode 100644 index 05773243..00000000 --- a/docs/private/media/scenario_tc-robmic.md +++ /dev/null @@ -1,34 +0,0 @@ -# 抢麦模式 - -## 前言 -本文将简要分享语音聊天室中抢麦玩法的的应用场景,并讲述基于环信语聊解决方案,实现抢麦玩法的步骤。 - -:::tip -`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。 -::: - -在抢麦模式下,只有抢到麦的主播可以发言,由 AppServer 来决定是否抢到麦当房主发起抢麦时;
- -首先请求 AppServer , AppServer 确定主播可以抢麦,返回成功的同时,AppServer 开始计时,在计时结束前或者抢到麦的主播主动释放麦之前,其他主播请求 AppServer 抢麦返回失败。主播抢到麦后,修改会议属性,告知所有人自己抢到了,同时开始倒计时,倒计时结束后,主动重新设置会议属性,告诉所有人自己释放麦。其他人收到抢麦的会议属性变化回调后更新 UI,并开始倒计时,在倒计时结束或者收到释放麦的会议属性变化前,所有人不可以发起抢麦操作。 - -## 实现方案 - -我们可以通过一张图,来了解抢麦模式中接口的调用逻辑: - -![img](/images/privitization/tc_logic_robmic.png) - -上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能 - -| 步骤 | iOS API | Android API | -| :---------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | -| 1.设置抢麦会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | -| 2.广播抢麦会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | -| 3.主播向AppServer发起抢麦请求 | AppServer API | Android与iOS调用接口相同 | -| 4.返回抢麦成功结果 | AppServer API | Android与iOS调用接口相同 | -| 5.主播改变会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | -| 6.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | -| 7.抢麦者说话,其他人闭麦 | [EMClient.sharedClient.conferenceManager updateConference: isMute:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#abc3d1658875a99bdd1f5f1158a74e789) | [EMClient.getInstance().conferenceManager().openVoiceTransfer();EMClient.getInstance().conferenceManager().closeVoiceTransfer();](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a7b4bd022d9daf8fe127d89494897bf99) | -| 8.释放麦,改变会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | -| 9.广播会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | - -语音聊天室可根据业务模型提供多种模式与玩法。目前环信提供的语聊集成方案对准备开发和正在集成聊天室的开发者来说,不仅可以更好的理解环信 IM 即时通讯、音视频所提供的丰富功能,还能通过产品层面的操作,帮助开发者构思出更多的互动玩法,扩展更多有意思的场景。 \ No newline at end of file diff --git a/docs/private/media/scenario_tc-scene.md b/docs/private/media/scenario_tc-scene.md deleted file mode 100644 index 0cfb1186..00000000 --- a/docs/private/media/scenario_tc-scene.md +++ /dev/null @@ -1,58 +0,0 @@ -# 临场模式 - -## 前言 - -本文简要分享语音聊天室中临场模式的使用场景,并概述基于环信音视频会议实现临场模式切换的主要步骤。 -:::tip -`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。 -::: - -临场模式环信以常见的杀人游戏白天、黑夜示例两种临时模式的切换,示例并非完整展示游戏的过程。仅提供切换方法和思路,以便开发者学习使用。 - -2018年后,由于实时音视频在社交应用中的广泛使用,影响了了大量私密社交和娱乐化社交的场景升级,娱乐社交方式不在停留在即时通讯的领域而更加激进的走向实时通讯领域。无论是连麦、直播或者场景化的聊天室。互动过程中更丰富发玩法自由切换,场景自由穿插组合成成为大部分社交应用的基础功能。业务模型的逐渐升级也推进环信语音连麦场景需要更迅速的提供通用的解决方案和集成支持。 - -环信将音视频会议内的临时场景切换归纳形成临场模式集成方案,主要解决: - -- 用户通过业务场景的定义实现发言逻辑变更,用户使用行为变更等常用功能; -- 通过此模式的集成实现,可以更快速的切换业务; -- 保持音视频会议通讯的稳定; -- 以及最大化的录制保存用户沟通的全部信息。 - -下面将详细介绍语音聊天室临场模式的集成方法: - -临场模式中的场景切换核心是通过修改和广播会议属性,由客户端预先约定好会议属性内的参数对应业务进行对订阅流音频、视频设置实现,这个`至关重要!!!` 同时还增加了服务端 的修改接口,可以通过 REST API 对会议属性进行控制。下图详细介绍临时场景实现过程。 - -## 临场变更 - -![img](/images/privitization/tc_logic_scene.png) - -| 步骤 | iOS API | Android API | REST API | -| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :------- | -| 1. 修改会议属性 | [EMConferenceManagerDelegate](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMConferenceManager.setConferenceAttribute](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | 近期上线 | -| 2. 广播同步会议属性 | [EMConferenceManagerDelegate.h](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | - | -| 3. 客户端按照约定参数进行muteRemote指定的特殊用户并mute自身,并且配合UI进行场景分别定制 | [muteRemoteAudio:mute](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28f9297ad2411c6aa9bdbb291bb8df26) | [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa55d14555c59930263659b1f608e8f18) | - | - -4. 当前语聊demo中的特殊主播用户(狼人)在夜晚场景可以自由发言,其他主播夜晚将无法发言; - -5. 所有订阅未改变,按照会议默认的方式继续同步; - -6. 但是由于其他主播用户设置muteRemote的特殊用户,将不进行特殊用户发言发本地播放行为。从而实现了临时场景屏蔽; - - -## 临场变更恢复 - -![img](/images/privitization/tc_logic_scene_reset.png) - -| 步骤 | iOS API | Android API | REST API | -| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :------- | -| 1. 修改会议属性 | [EMConferenceManagerDelegate](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMConferenceManager.setConferenceAttribute](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | 近期上线 | -| 2. 广播同步会议属性 | [EMConferenceManagerDelegate.h](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | - | -| 3. 客户端按照约定参数取消之前muteRemote指定的特殊用户并mute自身,并且配合UI进行场景恢复 | [muteRemoteAudio:mute](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a28f9297ad2411c6aa9bdbb291bb8df26) | [muteRemoteAudio](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_conference_manager.html#aa55d14555c59930263659b1f608e8f18) | - | - -临场模式的优势在于: - -1. 通过会议属性的切换同步,可以快速通知到各客户端场景切换,并且可以使新用户接入时继承最新的会议状态衔接场景功能。 -2. 过程中没有改变会议订阅的情况,与服务器之间交互行为减少,减少其他非必要的网络延迟,符合多次、小范围、临时的场景切换的要求。 -3. 保持全员通话畅通的基础上可以最大限度的保留原始素材的服务端录制,对后续的回溯播放提供完整的信息。 - -以上是临场模式的集成介绍,临场模式配合各种玩法,希望结合实际业务完成更多的聊天室互动场景。如有相关集成问题可以联系环信支持与产品咨询。另有更多的玩法集成请考到其他常见集成文档。 \ No newline at end of file diff --git a/docs/private/media/scenario_tc.md b/docs/private/media/scenario_tc.md deleted file mode 100644 index f4604c31..00000000 --- a/docs/private/media/scenario_tc.md +++ /dev/null @@ -1,176 +0,0 @@ -# 语音连麦聊天室集成介绍 - - -## 前言 -本文将简要分享几个语音聊天室的应用场景,并讲述基于环信 SDK ,实现语音连麦聊天室的步骤。 -:::tip -`仅特定的私有化版本SDK支持语聊解决方案.` 开发者如有需求,请联系商务咨询。 -::: - -语音聊天是社交软件必备的功能,语音相比文字图片更丰富,比视频又更简便,是天然的社交工具。除了单纯的1对1语音或视频聊天,在实时音视频技术支持下,很多 APP 已经延伸出多人语聊房、语音电台、语音游戏、私人聊天房、KTV 语聊房等非常丰富的场景。 - -比如: -1. 语音电台:是目前很多社交APP的玩法。主播可以在直播间中给听众讲故事、脱口秀、唱歌,多种形式不胜枚举,观众也可以申请上麦与主播聊天互动,在聊天的基础上,加上了背景伴奏音以及通过消息系统来实现的文字消息功能,在这种模式下,可以提高用户的活跃度。 - -2. 语音游戏:也是语音聊天室的常见应用场景。支持在狼人杀、剧本杀,王者荣耀及吃鸡等游戏中实现语音开黑,为玩家创建音视频对话实时互动的场景,功能上与语音直播相似,只是在这个频道中,上麦下麦的玩法逻辑有所不同。 - ------- - -## Demo - - -### Demo 源码 - -我们在 Github 已经提供了一套完整的 Demo,在 Demo 的基础上,开发者只需要不到1周的时间,对 UI 和功能做简单修改即可准备测试上线。 - -- [Android](https://github.com/easemob/liveroom-android) - -- [iOS](https://github.com/easemob/liveroom-ios) - - - ------- - -## 实现方案 - -语音聊天室需要满足的主要功能包括: -- 支持多人参与语音聊天 -- 支持本地混音 -- 多种连麦模式 - -要实现一个具备以上功能的语音聊天室,大致可以分为三步:**实现语音连麦、支持本地混音,多种连麦模式**的设计,基于设计需求,语音聊天室场景化方案的架构图与实现思路如下:
-![img](/images/privitization/tc_architecture.png) - - ------- - -### 实现语音连麦 - -基于开发者反馈,如果要通过自研的方法实现语音连麦,会存在如下问题: -- 需要自己部署服务器做好高并发处理; -- 需要对编解码器优化来解决回声、噪声问题; -- 需要有成熟的技术方案降低延迟、提高音质; -- 需要兼容各种网络环境下的用户体验等; - -总体来讲,就是需要解决设备端网络中的语音连麦**稳定低延时问题与可用性问题**。而以上这些问题,环信已为开发者提供成熟的解决方案,并将相关接口封装于SDK 中,让开发者可以简单快速调用集成。 - -**场景需求:观众上麦请求和主播通过上麦申请**
-在任意模式下,听众进入房间后可以允许发出上麦申请,房主同意后,听众可上麦,用户角色由听众变为了主播,主播要遵循房间模式来实现自己的功能。 - -**实现方案:通过会议属性实现**
-在语音聊天室 Demo 中,抢麦、主持、自由麦等模式,及包括各个模式中的上麦者均可通过会议属性实现,当会议属性发生更改时,会广播给房间内所有人。 - ------- - -#### 创建语聊房间 - -首先创建者通过 AppServer 创建并加入语聊房间,IM 聊天室。在房主通过 AppServer 创建并进入房间后,通过音视频提供的会议属性接口修改房间的会议属性,从而自定义一些房间的属性。 - -我们可以通过一张图,来了解创建语聊房间接口的调用逻辑: - -![img](/images/privitization/tc_logic_create.png) - -上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能。 - -| 步骤 | iOS API | Android API | -| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | -| 1. 创建语聊房间 | AppServer API | Android与iOS调用接口相同 | -| 2. [ 创建conference](rest_manage.html#创建会议) | AppServer API http://a1.easemob.com/{orgname}/{appname}/conferences POST | Android与iOS调用接口相同 | -| 3. 创建 chatroom | AppServer API http://a1.easemob.com/{orgname}/{appname}/chatrooms POST | Android与iOS调用接口相同 | -| 4. 创建成功返回conference ID,chatroom ID | AppServer API | Android与iOS调用接口相同 | -| 5. 加入 conference | [EMClient.sharedClient.conferenceManager joinConferenceWithConfId: password: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a465bd08db130e2d10d9bf0d418871bac) | [EMClient.getInstance().conferenceManager().joinConference(conferenceId, password, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#aa04a85ab5f36f3f4ac14dc23ac18afb8) | -| 6. 加入 chatroom | [EMClient.sharedClient.roomManager joinChatroom: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chatroom_manager-p.html#a4091826df825b9f1825f2ea97c4fb3e2) | [EMClient.getInstance().chatroomManager().joinChatRoom(chatRoomId, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatRoomManager.html#af2d592b0801dbc333c0c60bd551e150d) | -| 7. 设置会议属性 | [EMClient.sharedClient.conferenceManager setConferenceAttribute: value: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a7e29cc54c08e9cab13a3b58df89eea80) | [EMClient.getInstance().conferenceManager().setConferenceAttribute(key, value, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a785be01c2f30dbe661fb91c9c8cac7a9) | - ------- - -#### 加入语聊房间 - -当房主创建语聊房间后,其他人通过 AppServer 看到有房间被创建,可以输入房间密码加入到房间中。当加入房间后,就会收到会议属性变更的通知,从而得到会议属性。 - -我们可以通过一张图,来了解观众进入语聊房间接口的调用逻辑: - -![img](/images/privitization/tc_logic_join.png) - -上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能。 - -| 步骤 | iOS API | Android API | -| :----------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | -| 1.获取语聊房间列表 | AppServer API | Android与iOS调用接口相同 | -| 2.加入 conference | [EMClient.sharedClient.conferenceManager joinConferenceWithConfId: password: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a465bd08db130e2d10d9bf0d418871bac) | [EMClient.getInstance().conferenceManager().joinConference(conferenceId, password, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#aa04a85ab5f36f3f4ac14dc23ac18afb8) | -| 3.加入 chatroom | [EMClient.sharedClient.roomManager joinChatroom: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chatroom_manager-p.html#a4091826df825b9f1825f2ea97c4fb3e2) | [EMClient.getInstance().chatroomManager().joinChatRoom(chatRoomId, callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatRoomManager.html#af2d592b0801dbc333c0c60bd551e150d) | -| 4.同步会议属性 | [EMConferenceManagerDelegate#-conferenceAttributeUpdated:attributes:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html) | [EMConferenceListener#onAttributesUpdated(attributes);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceAttribute.html) | - ------- - -#### 上麦 - -已在语聊房间的观众通过 IMServer 发送 message 向房主发起上麦请求,房主同意后,通过 MediaServer 改变会议属性,将观众上麦成为主播,成为主播后就能说话进行推流。房间内其他的人都能收到推流通知并进行订阅。 - -我们可以通过一张图,来了解观众上麦接口的调用逻辑: - -![img](/images/privitization/tc_logic_mic.png) - -上图中每步涉及到的 iOS/Android 接口如下: - -| 步骤 | iOS API | Android API | -| :------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | -| 1.请求上麦 | [EMClient.sharedClient.chatManager sendMessage: progress: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chat_manager-p.html#ad139d7ad31d934a721a979955baf1868) | [EMClient.getInstance().chatManager().sendMessage(msg);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatManager.html#ad50be7183f088c415b9507bc7ce792e6) | -| 2.改变角色属性 | [EMClient.sharedClient.conferenceManager changeMemberRoleWithConfId: memberNames: role: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac613f23e6f13a14f8c40f12f5c1b45f9) | [EMClient.getInstance().conferenceManager().grantRole(targetRole);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a52a1e73bc4b588bc57227c7a57512409) | -| 3.上麦成为主播 | [EMConferenceManagerDelegate#-roleDidChanged:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ada8c07dac796d492a5165b28b50fb02c) | [EMConferenceListener#onRoleChanged(role);](http://www.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1EMConferenceListener.html#a6df0e567fc534314cee3008c310dfe72) | -| 4.推流 | [EMClient.sharedClient.conferenceManager publishConference: streamParam: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a4a621606d73a0ea1fab14aa336446a6b) | [EMClient.getInstance().conferenceManager().publish(param,callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#aa087a548e2d8f79ce06f50927decc137) | -| 5.收到推流通知 | [EMConferenceManagerDelegate#-streamDidUpdate: addStream:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#aaec86cf13eaa8930fa5261c1f3848785) | [EMConferenceListener#onStreamAdded(stream);](http://www.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1EMConferenceListener.html#ad06a034d00575fbf41798b98bebe6089) | -| 6.订阅 | [EMClient.sharedClient.conferenceManager subscribeConference: streamId: remoteVideoView: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a97e899177d4a7abcc49d8d7ea5152039) | [EMClient.getInstance().conferenceManager().subscribe(stream,surface,callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a405c38df38cbb0e6bf11420ff80540e0) | - ------- - -#### 下麦、销毁房间 - -当主播在麦上时,如果想要下麦,同样通过 IMServer 向房主发送 message 发起下麦请求,这里无需房主同意,默认直接下麦。若房主主动将主播下麦,则没有之前这步,房主直接通过 MediaServer 改变会议属性,将主播下麦成为观众,主播成为观众后就停止推流。房主调用 AppServer 销毁房间,进而销毁conference、chatroom。 - -我们可以通过一张图,来了解主播下麦、房主销毁语聊房间接口的调用逻辑: - -![img](/images/privitization/tc_logic_down.png) - -上图中每步涉及到的 iOS/Android 接口如下,其中部分调用到了 AppServer 的接口,开发者需要自己实现 AppServer 功能 - -| 步骤 | iOS API | Android API | -| :--------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | -| 1.请求下麦 | [EMClient.sharedClient.chatManager sendMessage: progress: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chat_manager-p.html#ad139d7ad31d934a721a979955baf1868) | [EMClient.getInstance().chatManager().sendMessage(msg);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMChatManager.html#ad50be7183f088c415b9507bc7ce792e6) | -| 2.改变角色属性 | [EMClient.sharedClient.conferenceManager changeMemberRoleWithConfId: memberNames: role: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#ac613f23e6f13a14f8c40f12f5c1b45f9) | [EMClient.getInstance().conferenceManager().grantRole(targetRole);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a52a1e73bc4b588bc57227c7a57512409) | -| 3.下麦成为观众 | [EMConferenceManagerDelegate#-roleDidChanged:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_e_m_conference_manager_delegate-p.html#ada8c07dac796d492a5165b28b50fb02c) | [EMConferenceListener#onRoleChanged(role);](http://www.easemob.com/apidoc/android/chat3.0/interfacecom_1_1hyphenate_1_1EMConferenceListener.html#a6df0e567fc534314cee3008c310dfe72) | -| 4.停止推流 | [EMClient.sharedClient.conferenceManager unpublishConference: streamId: completion:](http://www.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_conference_manager-p.html#a679bced8da6fa7b293626c0c3243cfe8) | [EMClient.getInstance().conferenceManager().unpublish(publishId,callback);](http://www.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1EMConferenceManager.html#a926c631717ce04a6c2a31401c8e095f7) | -| 5.销毁语聊房间 | AppServer API | Android与iOS调用接口相同 | -| 6.销毁conference | AppServer API http://a1-hsb.easemob.com/{orgname}/{appname}/conferences/{confrId} DELETE | Android与iOS调用接口相同 | -| 7.销毁chatroom | AppServer API http://a1.easemob.com/{orgname}/{appname}/chatrooms/{groupid} DELETE | Android与iOS调用接口相同 | - ------- - -### 本地混音 - -本地混音是指将几种不同的声音在发送端混在一起。例如常见的K歌场景,就需要将人唱歌的声音和歌曲的背景音乐进行混音处理。所以,在实现了基本的连麦功能后,我们还需要增加背景音乐的混音、播放控制。 - -在这里,主播可以在自己的客户端上选择要播放的音乐,然后通过 SDK 的 **startAudioMixing** 接口在本地与主播语音混音后播放给连麦听众和普通听众。并且连麦语音与背景音乐播放互不干扰,帮助用户活跃房间内的气氛。在默认情况下,背景音乐是循环播放的。 - ------- - -### 多种连麦模式 - -在语音聊天室 Demo 中,提供了三种模式,自由麦模式、主持模式、抢麦模式(开发者还可以基于此扩展更多模式玩法)。这三种模式就是通过会议属性区分的,当用户进入房间后,就可以知道当前的房间属于哪种模式。 - -自由麦模式:主播用户可以自由打开和关闭发言,实现起来较为简单就不过多赘述。 - -这里主要介绍一下,主持模式和抢麦模式的实现逻辑: - -- [主持模式](scenario_tc-host) - -- [抢麦模式](scenario_tc-robmic) \ No newline at end of file diff --git a/docs/private/media/whiteboard_android.md b/docs/private/media/whiteboard_android.md deleted file mode 100644 index 4ccb4a6e..00000000 --- a/docs/private/media/whiteboard_android.md +++ /dev/null @@ -1,86 +0,0 @@ -# Android集成互动白板 - -**注意:**`仅特定的私有化版本SDK支持白板功能.` - -使用白板功能首先需要登录环信,登录成功之后才可以去调用api创建白板房间,创建成功之后会直接加入房间,不需要再去调用加入的api。 - -其他人可以通过房间名称或者通过创建成功之后返回的房间ID去加入白板房间。创建或者加入成功之后会返回对应白板房间的URL,在webview中去加载显示 - -## 创建白板房间 - -``` -/** - * \~chinese - * 创建白板房间 - * @param user 用户名 - * @param token 用户的token - * @param roomName 房间名 - * @param password 房间的密码 - * @param isInteractive 是否允许互动 - * @param callBack 请求完成的回调 - */ -public void createWhiteboardRoom(final String user, final String token, final String roomName, - final String password, final boolean isInteractive, - final EMValueCallBack callBack) {} -``` - -## 通过房间名称加入白板房间 - -``` -/** - * \~chinese - * 通过白板名称加入房间 - * @param user 用户名 - * @param token 用户的token - * @param roomName 房间名 - * @param password 房间的密码 - * @param callBack 请求完成的回调 - */ - public void joinWhiteboardRoomWithName(final String user, final String token, final String roomName, final String password, final EMValueCallBack callBack) -``` - -## 通过房间ID加入白板房间 - -``` -/** - * \~chinese - * 通过白板id加入房间 - * @param user 用户名 - * @param token 用户的token - * @param roomId 房间名 - * @param password 房间的密码 - * @param callBack 请求完成的回调 - */ - public void joinWhiteboardRoomWithId(final String user, final String token, final String roomId, final String password, final EMValueCallBack callBack) -``` - -## 通过房间ID修改白板互动权限 - -``` -* \~chinese - * 通过白板Id 修改白板操作权限 - * @param user 创建者的userId - * @param roomId 房间Id - * @param token 用户的token - * @param isInteractive 是否开启交互权限 - * @param aServentIds 需要互动控制的成员 - * @param isAllInTeract 是否允许所有人交互 - * @param callBack 请求完成的回调 - * - */ - public void updateWhiteboardRoomWithRoomId(final String user,final String roomId, final String token, final boolean isInteractive,final List aServentIds,final boolean isAllInTeract, EMCallBack callBack){} -``` - -## 销毁白板房间 - -``` -/** - * \~chinese - * 销毁白板房间 - * @param user 用户名 - * @param token 用户的token - * @param roomId 房间id - * @param callBack 请求完成的回调 - */ - public void destroyWhiteboardRoom(final String user, final String token, final String roomId, EMCallBack callBack) -``` \ No newline at end of file diff --git a/docs/private/media/whiteboard_introduction.md b/docs/private/media/whiteboard_introduction.md deleted file mode 100644 index adbe6bb7..00000000 --- a/docs/private/media/whiteboard_introduction.md +++ /dev/null @@ -1,90 +0,0 @@ -# 互动白板简介 - -### 产品介绍 - -白板(Easemob-WhiteBoard)服务端基于socket.io,页面基于svg.js开发,所以兼容性参考上述两项即可。 - -SDK提供了创建白板、加入白板、销毁白板三个API。白板角色默认分为创建者/成员,都可以在实时共享的画布上运用提供工具进行元素的绘制、拖动等操作。创建者会增加白板页面的相关操作如:增加/删除白板页面、查看页面缩略图、上传文档(上传文档会根据文档页数在当前页面后面作为白板页插入);同时创建者有撤销/恢复、清空当前画布并更改房间成员的互动权限的操作。一个白板中支持多个白板页面,支持通过上传文档增加白板页面并作为白板页的背景。文档类型包括:PDF文档、Word、PPT文档进行实时展示和讲解。 - -创建白板后会返回一个白板地址链接,用户通过直接使用页面、ifram 或者 webview等方式集成。白板功能是实时音视频通话场景的互动补充,可以满足广泛的业务场景,例如:教育板书、会议内容展示、笔记记录。 - -白板功能特性: - -- 多客户端支持: 桌面端(基于electron)、Web端; -- 多人实时互动:可支持多人同时在线互动; -- 超低时延同步:白板操作低时延同步展示; -- 上传文件支持类型:图片、PDF文档、Word、PPT; - -### SDK API - -#### 1.创建白板房间 - -``` -a. whiteBoard.create() -b.whiteBoard.join() -``` - -注:.create()只是单独的创建并加入房间; .join()存在当前的房间名称就加入房间,不存在当前房间名就创建房间并加入; - -#### 2.加入白板房间 - -``` -a.whiteBoard.join() -当前房间名已存在,则加入该房间 -b.whiteBoard.joinByRoomName() -通过房间名加入 -c.whiteBoard.joinByRoomId() -通过房间id加入 -``` - -#### 3.房间权限更改 - -``` -whiteBoard.oprateAuthority() -控制房间内成员是否可以进行白板操作 -``` - -#### 4.删除白板 - -``` -whiteBoard.destroy() -``` - -## Demo - -### Demo源码 - -我们在 Github 已经提供了一套完整的 Demo,大家可以在 Github 地上获取。 - -- [Android](https://github.com/easemob/whiteboard_demo_android) - -- [iOS](https://github.com/easemob/whiteboard_demo_ios) - -- [web](https://github.com/easemob/whiteboard_demo_web) - -在 Demo 的基础上,开发者只需要不到1周的时间,对 UI 和功能做简单修改即可准备测试上线。 - -### 产品功能 - -白板操作有3类,分别为:页面类操作、元素类操作、文档类操作; -
表1.白板支持功能
- -![img](/images/privitization/whiteboard_function.png) - -
图2.白板操作界面
- -![img](/images/privitization/whiteboard_view.png) - diff --git a/docs/private/media/whiteboard_ios.md b/docs/private/media/whiteboard_ios.md deleted file mode 100644 index 4e6c2743..00000000 --- a/docs/private/media/whiteboard_ios.md +++ /dev/null @@ -1,127 +0,0 @@ -# iOS集成互动白板 - -**注意:**`仅特定的私有化版本SDK支持白板功能.` - -使用白板功能首先需要登录环信,登录成功之后才可以去调用api创建白板房间,创建成功之后会直接加入房间,不需要再去调用加入的api。 - -其他人可以通过房间名称或者通过创建成功之后返回的房间ID去加入白板房间。创建或者加入成功之后会返回对应白板房间的URL,在webview中去加载显示 - -## 创建白板房间 - -``` -/** - * \~chinese - * 创建白板房间 - * @param aUsername 用户名 - * @param aToken 用户的token - * @param aRoomName 房间名 - * @param aPassword 房间的密码 - * @param bInteract 是否允许互动 - * @param aCompletionBlock 请求完成的回调 - * - * \~english - * create room for whiteboard - * @param aUsername username - * @param aToken user's token - * @param aRoomName room name for whiteboard - * @param aPassword password for room - * @param bInteract weather allow members interact - * @param aCompletionBlock callback - */ -- (void)createWhiteboardRoomWithUsername:(NSString *)aUsername - userToken:(NSString *)aToken - roomName:(NSString *)aRoomName - roomPassword:(NSString *)aPassword - interact:(BOOL)aInteract - completion:(void(^)(EMWhiteboard *aWhiteboard, EMError *aError))aCompletionBlock; -``` - -## 通过房间名称加入白板房间 - -``` -/** - * \~chinese - * 通过白板名称加入房间 - * @param aRoomName 房间名 - * @param aUsername 用户名 - * @param aToken 用户的token - * @param aPassword 房间的密码 - * @param aCompletionBlock 请求完成的回调 - */ -- (void)joinWhiteboardRoomWithName:(NSString *)aRoomName - username:(NSString *)aUsername - userToken:(NSString *)aToken - roomPassword:(NSString *)aPassword - completion:(void(^)(EMWhiteboard *aWhiteboard, EMError *aError))aCompletionBlock; -``` - -## 通过房间ID加入白板房间 - -``` -/** - * \~chinese - * 通过白板id加入房间 - * @param aRoomId 房间id - * @param aUsername 用户名 - * @param aToken 用户的token - * @param aPassword 房间的密码 - * @param aCompletionBlock 请求完成的回调 - */ -- (void)joinWhiteboardRoomWithId:(NSString *)aRoomId - username:(NSString *)aUsername - userToken:(NSString *)aToken - roomPassword:(NSString *)aPassword - completion:(void(^)(EMWhiteboard *aWhiteboard, EMError *aError))aCompletionBlock; -``` - -## 修改成员互动权限 - -白板创建者可以修改其他成员的互动权限,禁止互动的成员将无法操作白板。修改互动权限的api如下 - -``` -/** - * \~chinese - * 修改白板的用户互动权限 - * @param aRoomId 房间Id - * @param aToken 用户的token - * @param aPassword 房间的密码 - * @param aInteract 是否允许互动,YES为允许互动,NO为不允许互动 - * @param aAll 是否操作所有成员,YES时操作所有人,aServentIds不起作用 - * @param aServentIds 操作的成员数组,aAll为NO时有效 - * @param aCompletionBlock 请求完成的回调 - * - * \~english - * update whiteboard room interact - * @param aRoomId room Id - * @param aUsername username - * @param aToken user's token - * @param aInteract weather allow members interact - * @param aAll weather update all members`s interact right.if YES,aServentIds is invalid. - * @param aServentIds array of members`s id.invalid when aAll is NO - * @param aCompletionBlock callback - */ -- (void)updateWhiteboardRoomWithRoomId:(NSString *)aRoomId - username:(NSString *)aUsername - userToken:(NSString *)aToken - intract:(BOOL)aInteract - allUsers:(BOOL)aAll - serventIds:(NSArray*)aServentIds - completion:(void(^)(EMError *aError))aCompletionBlock; -``` - -## 销毁白板房间 - -``` -/** - * \~chinese - * 销毁白板房间 - * @param aUsername 用户名 - * @param aToken 用户的token - * @param aRoomId 房间id - * @param aCompletionBlock 请求完成的回调 - */ -- (void)destroyWhiteboardRoomWithUsername:(NSString *)aUsername - userToken:(NSString *)aToken - roomId:(NSString *)aRoomId - completion:(void(^)(EMError *aError))aCompletionBlock; -``` \ No newline at end of file diff --git a/docs/private/media/whiteboard_pcdesktop.md b/docs/private/media/whiteboard_pcdesktop.md deleted file mode 100644 index cf82da55..00000000 --- a/docs/private/media/whiteboard_pcdesktop.md +++ /dev/null @@ -1,5 +0,0 @@ -# PC桌面集成互动白板 - ------- - -参考 [Web集成互动白板](whiteboard_web.html) \ No newline at end of file diff --git a/docs/private/media/whiteboard_vxmini.md b/docs/private/media/whiteboard_vxmini.md deleted file mode 100644 index c94a4c17..00000000 --- a/docs/private/media/whiteboard_vxmini.md +++ /dev/null @@ -1,5 +0,0 @@ -# 微信小程序集成互动白板 - ------- - -参考 [Web集成互动白板](whiteboard_web.html) \ No newline at end of file diff --git a/docs/private/media/whiteboard_web.md b/docs/private/media/whiteboard_web.md deleted file mode 100644 index 78becca2..00000000 --- a/docs/private/media/whiteboard_web.md +++ /dev/null @@ -1,179 +0,0 @@ -# Web集成互动白板 - -## 下载 - -``` -npm install easemob-whiteboards -``` - -## 引入sdk - -``` -import whiteboards from 'easemob-whiteboards' -``` - -## 初始化 - -``` -var WDSdk = new whiteboards({ - appKey: "yourAppKey" -}); -``` - -## APIs - -有两种方式创建白板: - -### 1. 通过房间名加入,没有房间创建房间,有房间加入房间 - -``` -/** - * @param {string} roomName 房间名 - * @param {string} password 房间密码 - * @param {string} userName im用户名 - * @param {number} level 权限等级 ,1-3禁止互动,4-8允许互动。默认允许互动 - * @param {number} layout 工具栏位置 ,默认0;0-底部,1-右侧,2-顶部 - * @param {string} ratio 白板画布宽高比。建议"4:3"、"2:1" - * @param {string} token im登录token - * @param {function} suc 成功的回调 - * @param {function} error 失败的回调 - */ -WDSdk.join({ - roomName: 'roomName', - password: 'password', - userName: 'userName', - level: 4, - layout:0, - ratio:"2:1", - token: 'token', - suc: (res) => { - res.whiteBoardUrl; 为白板房间地址 - }, - error: () => {}, -}) -``` - -### 2. 通过单独api去创建、加入 - -a. 创建白板 (WDSdk.create) - -``` -/** - * @param {string} roomName 房间名 - * @param {string} password 房间密码 - * @param {string} userName im用户名 - * @param {number} level 权限等级 ,1-3禁止互动,4-8允许互动。默认允许互动 - * @param {number} layout 工具栏位置 ,默认0;0-底部,1-右侧,2-顶部 - * @param {string} ratio 白板画布宽高比。建议"4:3"、"2:1" - * @param {string} token im登录token - * @param {function} suc 成功的回调 - * @param {function} error 失败的回调 - */ -WDSdk.create({ - userName: 'userName', - roomName: 'roomName', - level: 4, - layout:0, - ratio:"2:1", - password: 'password', - token: 'token', - suc: (res) => { - window.location = res.whiteBoardUrl; - }, - error: () => {} -}); -``` - -b. 加入白板,可支持两种方式加入白板: -- joinByRoomId :通过已经创建的房间ID加入; -- joinByRoomName :通过已经创建的房间名称加入; - -``` -/** - * 1 通过房间ID加入 - * @param {string} roomId 房间Id - * @param {string} password 房间密码 - * @param {string} userName im用户名 - * @param {string} token im登录token - * @param {function} suc 成功的回调 - * @param {function} error 失败的回调 - */ -WDSdk.joinByRoomId({ - userName: userName, - roomId: roomId, - token: "token", - suc: function(res){ - window.location = res.whiteBoardUrl; - }, - error: function(err){ - console.log("err", err); - } -}); - -/** - * 2 通过房间名加入 - * @param {string} roomName 房间名 - * @param {string} password 房间密码 - * @param {string} userName im用户名 - * @param {string} token im登录token - * @param {function} suc 成功的回调 - * @param {function} error 失败的回调 - */ -WDSdk.joinByRoomName({ - userName: userName, - roomName: roomName, - token: "token", - suc: function(res){ - window.location = res.whiteBoardUrl; //同joinByRoomId返回 - }, - error: function(err){ - console.log("err", err); - } -}); -``` - -### 3. 白板互动权限 - -``` -/** - * @param {string} userName im用户名 - * @param {string} roomId 房间id - * @param {number} leval 4-8允许互动/1-3禁止互动 - * @param {arr} members 操作的权限用户名数组,当isAll为true,此参数不生效,所以设置此参数时需设置isAll=false - * @param {bloon} isAll ture时操作对象为房间所有成员,默认为true - * @param {string} token im登录token - * @param {function} suc 成功的回调 - * @param {function} error 失败的回调 - */ -WDSdk.oprateAuthority({ - userName: "username", - roomId: "roomId", - leval: 4, - members:[], - isAll: true, - token: "token", - suc: function(res){}, - err: function(err){} -}) -``` - -### 4. 销毁白板 - -``` -/** - * @param {string} roomId 房间id - * @param {string} token im登录token - * @param {function} suc 成功的回调 - * @param {function} error 失败的回调 - */ -WDSdk.destroy({ - roomId: roomId, - token: "token", - suc: function(res){ - console.log(res); - }, - error: function(err){ - console.log("err", err); - } -}); -``` \ No newline at end of file diff --git a/docs/product/GDPR.md b/docs/product/GDPR.md deleted file mode 100644 index 73143d7f..00000000 --- a/docs/product/GDPR.md +++ /dev/null @@ -1,93 +0,0 @@ -# GDPR 安全合规 - - - -环信 IM 提供一系列数据删除和导出 API,保护数据安全和用户隐私 ,确保符合 GDPR(通用数据保护条例)的安全合规要求。 - -## 数据删除 - - -为保护用户隐私,环信提供数据删除 REST API 供开发者对环信即时通讯服务器存储的用户相关数据进行删除,例如:删除用户账号、删除用户属性、解散群组和聊天室。 - -### 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段: - -`Authorization:Bearer YourAppToken` - -为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 仅支持使用 app token 的鉴权方式,详见[使用 App Token 鉴权](easemob_app_token.html)。 - -### REST API 介绍 - -#### 删除用户账号 - -[删除 App 下指定的用户](/document/server-side/account_system.html#删除单个用户),删除的用户数据主要包括用户的会话列表、用户属性和好友关系。 - -#### 删除用户属性 - -[删除 App 下指定用户的用户属性](/document/server-side/userprofile.html#删除用户属性)。 - -#### 解散群组 - -[删除 App 下指定群 ID 的群组](/document/server-side/group_member.html#解散群组)。 - -#### 解散聊天室 - -[删除 App 下指定 ID 的聊天室](/document/server-side/chatroom_manage.html#解散聊天室)。 - -## 数据导出 - -### 功能描述 - -为了保证用户管理其隐私数据的权利,环信提供了数据导出 REST API,可供开发者导出环信即时通讯服务器存储的相关数据,包括用户数据、群组数据、聊天室数据、历史消息和附件。 - -### REST API 概览 - -本文介绍数据导出 API 的列表。 - -#### 导出用户数据 - -| REST API | 描述 | -| :----------------------------------------------------------- | :---------------------------------- | -| [获取单个用户信息](/document/server-side/account_system.html#获取单个用户的详情)
[批量获取用户信息](/document/server-side/account_system.html#批量获取用户详情) | 获取 App 下指定用户 ID 的用户信息。 | -| [获取用户属性](/document/server-side/userprofile.html#获取用户属性) | 获取 App 下指定用户 ID 的用户属性。 | - -#### 导出群组数据 - -| REST API | 描述 | -| :----------------------------------------------------------- | :---------------------------------------- | -| [群组详情](/document/server-side/group_manage.html#获取群组详情) | 获取 App 下指定群组 ID 的群组详情。 | -| [App 下所有的群组](/document/server-side/group_manage.html#获取-app-中所有的群组-可分页) | 获取 App 下包含所有群组的列表。 | -| [群组管理员列表](/document/server-side/group_member.html#获取群管理员列表) | 获取 App 下指定群组 ID 的群组管理员列表。 | -| [群组成员列表](/document/server-side/group_member.html#分页获取群组成员) | 获取 App下指定群组 ID 的群组成员列表。 | -| [群组公告](/document/server-side/group_file.html#获取群组公告) | 获取 App 下指定群组 ID 的群组公告。 | -| [群组共享文件](/document/server-side/group_file.html#获取群组共享文件) | 获取 App 下指定群组 ID 的群组共享文件。 | -| [群组黑名单列表](/document/server-side/group_member.html#查询群组黑名单) | 获取 App 下指定群组 ID 的群组黑名单列表。 | -| [群组禁言列表](/document/server-side/group_member.html#获取禁言列表) | 获取 App 下指定群组 ID 的群组禁言列表。 | - -#### 导出聊天室数据 - -| REST API | 描述 | -| :----------------------------------------------------------- | :-------------------------------------------- | -| [获取聊天室详情](/document/server-side/chatroom.html#查询聊天室详情) | 获取 App 下指定聊天室 ID 的聊天室详情。 | -| [App 下所有的聊天室](/document/server-side/chatroom.html#获取-app-中所有的聊天室) | 获取 App 下所有的聊天室列表。 | -| [用户加入的聊天室](/document/server-side/chatroom.html#获取用户加入的聊天室) | 获取 App 下指定用户 ID 加入的聊天室列表。 | -| [聊天室管理员列表](/document/server-side/chatroom.html#获取聊天室管理员列表) | 获取 App 下指定聊天室 ID 的聊天室管理员列表。 | -| [聊天室成员列表](/document/server-side/chatroom.html#分页获取聊天室成员) | 获取 App 下指定聊天室 ID 的聊天室禁言列表。 | -| [聊天室禁言列表](/document/server-side/chatroom.html#获取禁言列表) | 获取 App 下指定聊天室 ID 的聊天室禁言列表。 | - -#### 获取历史消息记录 - -此接口一次只能获取一个小时的历史消息记录。 - -| REST API | 描述 | -| :----------------------------------------------------------- | :------------------------------------ | -| [获取历史消息记录](/document/server-side/message_historical.html) | 获取 App 下指定时间段的历史消息文件。 | - -#### 导出附件 - -附件包含图片、语音、视频、文件。 - -| REST API | 描述 | -| :----------------------------------------------------------- | :---------------------------- | -| [下载附件](/document/server-side/message_download.html#下载文件) | 下载 App 下指定 UUID 的附件。 | \ No newline at end of file diff --git a/docs/product/README.md b/docs/product/README.md deleted file mode 100644 index e13416f9..00000000 --- a/docs/product/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 产品简介 ---- diff --git a/docs/product/aigc/aigc_rest_api.md b/docs/product/aigc/aigc_rest_api.md deleted file mode 100644 index f78c9851..00000000 --- a/docs/product/aigc/aigc_rest_api.md +++ /dev/null @@ -1,199 +0,0 @@ -# AI 智能 - -环信即时通讯云提供 REST API 获取 app 下的机器人列表。**如果需要该功能相关的其他 REST API,请联系环信商务。** - -## 前提条件 - -要调用环信即时通讯 RESTful API,请确保满足以下要求: - -- 已在环信即时通讯云控制台 [开通配置环信即时通讯 IM 服务](/product/enable_and_configure_IM.html)。 -- 已从服务端获取 app token,详见 [使用 App Token 鉴权](/product/easemob_app_token.html)。 -- 了解环信 IM API 的调用频率限制,详见 [接口频率限制](/product/limitationapi.html)。 - -## 认证方式 - -环信即时通讯 REST API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段: - -`Authorization: Bearer YourAppToken` - -为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。本文介绍的即时通讯所有 REST API 均需使用 App Token 的鉴权方式,详见 [使用 App Token 鉴权](/product/easemob_app_token.html)。 - -## 获取 app 下的机器人列表 - -你可以调用该 API 获取你的 app 下的机器人列表。 - -**调用频率上限**:100 次/秒/App Key - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/robot/rule?&page={page}&size={size} -``` - -#### 路径参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见 [获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见 [获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见 [获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | - -#### 查询参数 - -| 字段 | 类型 | 是否必选 | 备注 | -| :-------------- | :----- | :------- | :--------------------------------------- | -| `page` | Int | 是 | 当前页码,默认值为 `0`。| -| `size` | Int | 是 | 每页返回的机器人数量,取值范围为 [1,20],默认值为 `10`。| - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :--------------------------------------- | -| `Authorization` | String | 是 | App 管理员的鉴权 token,格式为 `Bearer YourAppToken`,其中 `Bearer` 为固定字符,后面为英文空格和获取到的 app token。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中的字段描述如下: - -| 字段 | 类型 | 描述 | -| :------------------ | :----- | :-------------------------------------- | -| `status` | String | 是否成功获取 app 下的机器人列表。`OK` 表示成功获取。 | -| `entities` | JSONArray | app 下的机器人详情。 | -| - `id` | String | 机器人 ID。 | -| - `name` | String | 机器人名称。 | -| - `appkey` | String | 应用的唯一标识,由 `Orgname` 和 `Appname` 组成,生成后不允许修改。在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **应用详情** 页面查看。 | -| - `robotId` | String | robot ID。 | -| - `robotAppId` | String | robot ID 对应的 robot app ID。 | -| - `msgType` | String | 消息类型,目前固定值为 `txt`,即文本消息。 | -| - `targetType` | String | 会话类型,目前固定值为 `chat`,即单聊。 | -| - `targetId` | List | 机器人对应的 IM 的用户 ID。目前只有一个用户 ID。 | -| - `providerType` | String | AI 大模型厂商,目前固定值为 `MINIMAX`。 | -| - `providerId` | String | 机器人对应的厂商 ID。 | -| - `timeout` | Int | 超时时间,目前未启用。 | -| - `status` | String | 机器人的状态,`ACTIVE` 为启用状态,默认是启用。 | -| - `createDateTime` | DATETIME | 开通使用 MiniMax AI 聊天服务的时间。 | -| - `updateDateTime` | DATETIME | 更新 MiniMax AI 聊天服务开通状态的时间。 | -| - `providerTextApi` | String | 厂商支持的 AI 接口,默认使用 `chatcompletion_pro`,当前不支持可选。 | -| - `providerModel` | String | 厂商支持的 AI 模型类别。| -| - `providerAttribute` | JSONObject | 机器人的一些属性。 | -| - `historyNum` | Int | 传递给机器人的历史消息数,固定为 `10`。开发者忽略该字段。 | -| - `avatar` | String | 机器人头像图片链接。 | -| - `restMsgLimit` | Int | 发送的 REST 消息大小值。该字段为内部使用,开发者可忽略。 | -| - `providerPayload` | JSONObject | 调用厂商接口时的一些参数。 | -| - `top_p` | Int | 控制生成环节采样范围,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 | -| - `tokens_to_generate` | Int | 机器人回复的最大生成 token 数。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 | -| - `temperature` | Int | 控制生成环境采样随机性,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 | -| - `providerContent` | String | 具体机器人的设定,长度影响接口性能。 | -| - `textType` | String | 固定值,该字段为内部使用,开发者可忽略。 | -| `size` | Int | 当前页面返回的机器人数量。 | -| `page` | Int | 当前页码。 | -| `elements` | Int | 当前页面返回的机器人数量。 | -| `totalPages` | Int | 总页数。 | -| `totalElements` | Int | App 下的机器人总数。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -# 将 替换为你在服务端生成的 App Token -curl --location 'http://XXXX/XXXX/XXXX/robot/rule?page=0&size=10' --H 'Authorization: Bearer ' -``` - -#### 响应示例 - -```json -{ - "status": "OK", - "entities": [ - { - "id": "1eUOZ3RFpJA2BFSsaB8n5EFrETh", - "name": "Kyler_Robel", - "appkey": "easemob-demo#test", - "robotId": "f5f07c60ce95ca4f496870665d0e868d", - "robotAppId": "1eRg1UCOhrvkMw1q47G7tToUduJ", - "msgType": "TEXT", - "targetType": "CHAT", - "targetId": [ - "some_user_id371-916-6147" - ], - "providerType": "MINIMAX", - "providerId": "1eUOZ28DChC1LUc5a5YSvSoPPnq", - "timeout": 3000, - "status": "ACTIVE", - "createDateTime": "2024-05-29T09:30:56.427220Z", - "updateDateTime": "2024-05-29T09:37:40.969794Z", - "providerTextApi": "chatcompletion_pro", - "providerModel": "abab6.5-chat", - "providerAttribute": { - "historyNum": 10, - "avatar": "http://placeimg.com/640/480", - "restMsgLimit": 1024 - }, - "providerPayload": { - "top_p": 0.9, - "tokens_to_generate": 2048, - "temperature": 0.1 - }, - "providerContent": "putMessage我是助理222", - "textType": "DEFAULT" - }, - { - "id": "1eUbgljnq7yhHqgQ7cjKw5mOUxC", - "name": "Dessie81", - "appkey": "easemob-demo#test", - "robotId": "f5f07c60ce95ca4f496870665d0e868d", - "robotAppId": "1eRg1UCOhrvkMw1q47G7tToUduJ", - "msgType": "TEXT", - "targetType": "CHAT", - "targetId": [ - "some_user_id379-312-1146" - ], - "providerType": "MINIMAX", - "providerId": "1eUbgjWOKkzbaRCysbLozPy4E4h", - "timeout": 3000, - "status": "ACTIVE", - "createDateTime": "2024-05-29T11:18:51.454156Z", - "updateDateTime": "2024-05-29T11:46:19.333387Z", - "providerTextApi": "chatcompletion_pro", - "providerModel": "abab6.5-chat", - "providerAttribute": { - "historyNum": 10, - "avatar": "http://placeimg.com/640/480", - "restMsgLimit": 1024 - }, - "providerPayload": { - "top_p": 0.9, - "tokens_to_generate": 2048, - "temperature": 0.1 - }, - "providerContent": "putMessage我是助理222", - "textType": "DEFAULT" - } - ], - "size": 10, - "page": 0, - "elements": 2, - "totalPages": 1, - "totalElements": 2 -} -``` - -### 错误码 - -| HTTP 状态码 | 错误类型 | 错误提示 | 可能原因 | 处理建议 | -| :----------- | :--- | :------------- | :----------- | :----------- | -| 401 | unauthorized | Unable to authenticate (OAuth) | token 不合法,可能过期或 token 错误。 | 使用新的 token 访问。 | -| 500 | Internal Server Error | Internal Server Error | 服务内部错误。 | 检查请求参数是否合理。| -| 400 | Bad Request | Request param error | 请求参数错误。 | 检查请求参数是否合理。| - -关于其他错误,你可以参考 [响应状态码](/document/server-side/overview.html) 了解可能的原因。 - - - - diff --git a/docs/product/aigc/aigc_run_through_demo_client.md b/docs/product/aigc/aigc_run_through_demo_client.md deleted file mode 100644 index 6aaed24e..00000000 --- a/docs/product/aigc/aigc_run_through_demo_client.md +++ /dev/null @@ -1,41 +0,0 @@ -# 客户端跑通示例项目 - -通过配置服务端和客户端,利用环信即时通信 IM 服务器回调功能,在 IM 中引入 AI 服务(以 MiniMax 中文大语言模型为例),创建机器人账号,从而跑通示例项目。 - -本文介绍通过跑通示例项目如何配置客户端,跑通示例项目。 - -## 环境准备 - -1. 开发环境 - -- 工具:Android Studio -- 系统:MacOS -- 代码:Java - -2. 运行环境 - -系统: Android 6.0 + - -## 下载代码 - -通过 [GitHub 链接下载客户端代码](https://github.com/easemob/Easemob-AIGCService-Example/tree/dev/AIGCService-AndroidClient)。 - -## 参数配置 - -使用 `AndroidStudio` 运行项目,打开 `com.imchat.chanttyai/base/Constants.java` 文件,只需将 `APP_KEY` 及 `HTTP_HOST` 参数分别修改为环信 App Key 和服务端部署域名或 IP 地址。 - -![img](/images/aigc/parameter_configure.png) - -## 运行示例项目 - -跑通示例项目,跑通后的界面以及聊天界面如下图所示: - -- 启动页面和机器人列表用户界面如下图所示: - -   - - -- 聊天页面如下图所示: - -   - \ No newline at end of file diff --git a/docs/product/aigc/aigc_run_through_demo_server.md b/docs/product/aigc/aigc_run_through_demo_server.md deleted file mode 100644 index f664065b..00000000 --- a/docs/product/aigc/aigc_run_through_demo_server.md +++ /dev/null @@ -1,290 +0,0 @@ -# 服务端配置 - -通过配置服务端和客户端,利用环信即时通信 IM 服务器回调功能,在 IM 中引入 AI 服务(以 MiniMax 中文大语言模型为例),创建机器人账号,从而跑通示例项目。本文介绍通过跑通示例项目如何配置服务端。 - -此外,利用 AI 聊天功能,你可以设置问候语,让机器人用户每天定时主动向聊天用户发送问候语,实现详情请参见 [FAQ](#faq)。 - -若要体验 Demo,你可以扫描以下二维码: - -![img](/images/aigc/ai_solution1_demo.png) - -## 环境准备 - -1. 部署要求:Windows 或者 Linux 服务器 - -2. 环境要求 - -- JDK 1.8+ -- Redis 3.0.504 -- Redis 绑定地址更改为 127.0.0.1 -- MySQL 8.0.30 - -## 代码下载 - -当部署环境准备好后,通过 [GitHub 链接下载服务端代码](https://github.com/easemob/Demo-ChattyAI/tree/dev/chattyai_server)。 - -## 信息配置 - -服务端配置信息全部集中在以下文件中,主要配置包含三个部分:环信即时通讯 IM、miniMax 和 redis,配置内容如下: - -``` -src/main/resources/application.yml -``` - -### 环信即时通讯 IM 相关配置 - -#### 1. 创建应用 - -登录[环信即时通讯云控制台](https://console.easemob.com/user/login),点击**添加应用**,填写应用相关信息。 - -![img](/images/aigc/app_create.png) - -#### 2. 获取 app 信息 - -选中创建的应用,点击**管理**,进入**应用详情**页面,获取 **App Key**、**ClientID** 及**ClientSecret**。 - -```yaml -logging: - level: - com.easemob.im.http: debug #启动之后可打印的日志级别 -server: - port: 80 #修改启动端口,只能为数字(请确保该端口没有被占用) -easemob: - appkey: {appkey} # 创建应用获取到的 App Key,可通过环信即时通讯云控制台的 “应用详情” 页面上的 “APPKEY” 字段获取。 - clientId:{clientId} # App 的 client_id,可通过环信即时通讯云控制台的 “应用详情” 页面上的 “Client ID” 字段获取。 - clientSecret:{clientSecret} # App 的 client_secret,可通过环信即时通讯云控制台的 “应用详情” 页面上的 “ClientSecret” 字段获取。 -``` - -![img](/images/aigc/app_detail.png) - -#### 3. 关闭好友关系检查 - -设置**用户注册模式**为**开放注册**,关闭好友关系检查。 - -![img](/images/aigc/user_register_contact.png) - -#### 4. 创建机器人账号 - -选择**应用概览** > **用户认证** 创建机器人账号,进行单聊或群组聊天。 - -示例项目中创建了 3 个智能体,因此建议设置 3 个机器人账号与智能体一 一绑定,即 `com.easemob.chattyai.chat.util.BotSettingUtil` 中的 `botBean0.setAccount`(机器人用户 ID)与 `botBean0.setName`(智能体名称)为一 一对应关系,见下方代码。 - -下图红框中的用户 ID(`bot1222700215765565440`、`bot1223027765968633856` 和 `bot1223027786982096896`)为示例项目中的与智能体绑定的机器人账号,若使用其他用户 ID,则需同步修改 `BotSettingUtil` 的 `botBean0.setAccount` 中的值,否则无法跑通示例项目。 - -![img](/images/aigc/robot_account_create.png) - -```java -static{ - -BotBean botBean0 = new BotBean(); -botBean0.setAccount("boy0"); -botBean0.setName("智能体名称"); -botBean0.setGender(0); -botBean0.setContent("智能体介绍" + -"); -botBean0.setDesc("智能体相关信息,例如特征等。"); -bots.put("boy0",botBean0); - -} -``` - -#### 5. 配置发送前回调规则 - -若使用消息发送前回调功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)开通该功能,详见[回调配置相关文档](/product/enable_and_configure_IM.html#配置消息回调)。该功能为增值服务,费用详见[功能费用文档](/product/pricing.html#增值服务费用)。 - -回调功能开通后,选择**即时通讯** > **功能配置** > **消息回调**,点击**添加回调地址**,配置发送前回调规则。其中,**会话类型**选择**单聊**和**群聊**,**消息类型**选择**文本**,**启用状态**选择**启用**,**回调地址**需确保设置为环信即时通讯 IM 可以通过外网访问到回调地址,格式为 `http(s)://ip:端口/chatty/callback.json`。其他参数的含义详见[配置回调规则相关文档](/product/enable_and_configure_IM.html#配置回调规则)。 - -![img](/images/aigc/callback_address.png) - -### 大语言模型(LLM)信息配置 - -本代码示例以 MiniMax 为例 [MiniMax 开放平台快速开始](https://platform.minimaxi.com/document/Fast%20access?key=66701cf51d57f38758d581b2),若使用其他大语言模型,可按其他语言模型配置要求进行调整。 - -```yaml -miniMax: - groupId:{groupId} # MiniMax 基础信息的 groupID。选择 “MiniMax账号管理” > “账户信息”页面,获取 “groupID” 字段。 - appkey: {appkey} # MiniMax 的接口密钥。当需要复制 API 密钥时,可以重新创建一个以完成复制操作。 - url: https://api.minimax.chat/v1/text/chatcompletion_pro?GroupId= -``` - -### MySQL 配置 - -```yaml -spring: - datasource: - type: com.alibaba.druid.pool.DruidDataSource - driverClassName: com.mysql.cj.jdbc.Driver - druid: - url: xxxx - username: xxxx - password: xxxx - initial-size: 10 - max-active: 100 - min-idle: 10 - max-wait: 60000 - pool-prepared-statements: true -``` - -### redis 配置 - -redis 安装完成以后,设置上 redis 的密码(也可以设置为空),确保 "host:port" 链接可以访问 redis 即可。 - -```yaml - redis: - host: {host} #redis 地址 - port: {port} #redis 端口 - password: {password} #redis 密码 - # 连接超时时间(毫秒) - timeout: 30000 - # 连接池中的最大空闲连接 - max-idle: 8 - # 连接池中的最小空闲连接 - min-idle: 10 - # 连接池最大连接数(使用负值表示没有限制) - max-active: 100 - # 连接池最大阻塞等待时间(使用负值表示没有限制) - max-wait: -1 -``` - -### 数据库初始化 - -导入下方脚本: - -```yaml -/* -SQLyog 企业版 - MySQL GUI v8.14 -MySQL - 8.3.0 : Database - chattyai -********************************************************************* -*/ - - -/*!40101 SET NAMES utf8 */; - -/*!40101 SET SQL_MODE=''*/; - -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -CREATE DATABASE /*!32312 IF NOT EXISTS*/`chattyai` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */; - -USE `chattyai`; - -/*Table structure for table `chat_bot` */ - -DROP TABLE IF EXISTS `chat_bot`; - -CREATE TABLE `chat_bot` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `bot_name` varchar(50) DEFAULT NULL COMMENT '名称', - `describe` varchar(2000) DEFAULT NULL COMMENT '描述', - `pic` varchar(50) DEFAULT NULL COMMENT '头像地址', - `open` tinyint NOT NULL DEFAULT '1' COMMENT '是否公开', - `ea_account` varchar(50) DEFAULT NULL COMMENT '环信账号', - `create_account` varchar(50) DEFAULT NULL COMMENT '创建人', - `create_time` datetime DEFAULT NULL COMMENT '创建时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB COMMENT='聊天机器人'; - -/*Data for the table `chat_bot` */ - -insert into `chat_bot` (`id`, `bot_name`, `describe`, `pic`, `open`, `ea_account`, `create_account`, `create_time`) values('1','智能助手','理解人类语言、生成内容,是生活和工作的智能助手。','1','1','bot1222700215765565440','default','2024-03-28 00:14:08'); -insert into `chat_bot` (`id`, `bot_name`, `describe`, `pic`, `open`, `ea_account`, `create_account`, `create_time`) values('2','编程助手','一个经验丰富的程序员开发助手,擅长 web 前端、springboot 后端和 Android 开发','2','1','bot1223027765968633856','default','2024-03-28 00:14:07'); -insert into `chat_bot` (`id`, `bot_name`, `describe`, `pic`, `open`, `ea_account`, `create_account`, `create_time`) values('3','法律顾问','你精通各个领域的法律知识,能够提供专业且贴心的法律咨询服务','3','1','bot1223027786982096896','default','2024-03-28 00:14:06'); - - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -``` - -### 启动说明 - -1. `host` 填写为 `127.0.0.1`。 -2. `port` 填写为 redis 所占用的端口。 -3. `password` 填写 redis 的密码(如果没有密码,使用 `#` 注释该配置)。 - -![img](/images/aigc/redis_password.png) - -4. 使用 `mvn install` 将项目打包为 `jar`。 - -![img](/images/aigc/jar.png) - -5. 找到对应位置的 `jar` 包,上传到服务器。 - -使用命令启动即可: - -```shell -nohup java -jar $APP_DIR/chattyai-0.0.1-SNAPSHOT.jar --server.port=$PORT >> ./chattyai.log 2>&1 & -``` - -- `$APP_DIR` 替换为上传 jar 包存在的根路径。 -- `$PORT` 替换为需要占用的端口。 - -6. 查看启动日志。 - -```shell -tail -f $APP_DIR/chattyai.log -``` - -## FAQ - -1. Q: 项目为何启动失败? - -A: 确保 JDK 配置正确,端口没有被占用,redis 能被访问到。 - -1. Q: 项目启动后为何无法访问? - -A: 检查以下两方面: - - 配置 nginx 的情况下,请确保 nginx 配置正确。 - - 未配置 nginx 的情况下,请确保端口对外开放。 - -3. Q: MiniMax 的调用失败,无返回结果,是什么原因? - -A: 请确保 MiniMax 有余额,否则可能导致调用 MiniMax 的调用失败。 - -4. Q: 如何实现问候语? - -A: 你可以设置问候语,让机器人用户每天定时主动向聊天用户发送问候语。 - -`com.easemob.chattyai.chat.util.GreetUtil` 类中存在一个静态代码块和以下三个镜头属性。 - -静态代码用于加载该类时,分别向这三个 List 中添加对应的问候语。 - -```java - /** - * 早上问候语 list - */ - public static List moringGreetList = new ArrayList<>(); - - /** - * 中午问候语 list - */ - public static List noonGreetList = new ArrayList<>(); - - /** - * 晚上问候语 list - */ - public static List eveningGreetList = new ArrayList<>(); -``` - -设置问候语后,可在 `com.easemob.chattyai.task.GreetTask` 类中设置定时任务。定时任务触发的 Cron 如下所示。例如,若用户 A 与机器人用户 B 聊过天,机器人用户 B 会在每天早上 9 点、中午 12 点和晚上 21 点给用户发送消息。 - -```java -0 0 9,12,21 * * ? -``` - -5. Q: 如何获取历史消息? - -A: 下图中的 `MiniMaxAiSingleHandler` 为单聊的 MinMax 处理类,`MiniMaxAiGroupHandler` 为群聊的 MinMax 的处理类。 - -![img](/images/aigc/historical_message.png) - -在本示例项目中,与智能体交互后,聊天记录会同步处理到 从 redis 获取的 key (`Constant.CHAT_GROUP_HISTORY_REDIS_KEY_PREFIX+发送人的环信用户ID+:+机器人的环信 ID`)的对应的 value 中,方便下一次聊天时作为历史消息传递给 AI。示例项目中只取最近 10 条消息作为历史数据,对应的代码如下所示: - -```java -long l = redisUtil.lGetListSize(key); -if (l > 10) { - redisUtil.leftpop(key, 2L); -} -``` diff --git a/docs/product/aigc/aigc_scenario_introduction.md b/docs/product/aigc/aigc_scenario_introduction.md deleted file mode 100644 index 8d1615be..00000000 --- a/docs/product/aigc/aigc_scenario_introduction.md +++ /dev/null @@ -1,62 +0,0 @@ -# 方案介绍 - -环信 AIGC X IM(Artificial Intelligence Generated Content,生成式人工智能)一站式解决方案,充分发挥即时通讯的实时性和便利性,同时叠加AI的智能化能力,实现了更便捷的开发、更具沉浸感和个性化的用户体验。通过环信 AIGC 解决方案,可以快速搭建多类低延迟的 AI 实时互动场景,包括: - -- **虚拟角色互动**:AIGC 结合 IM 能力可定制特定人物性格的 AI 陪伴者,提供即时的情感支持与个性化体验,创造更加新颖的社交体验。 -- **营销内容推送**:AIGC 基于用户属性、历史记录等数据训练,可定制化生成营销摘要,基于 IM 消息通道,实现信息的精准推送。 -- **社群活跃度提升**:通过 AIGC 在 IM 社群场景中实时创建互动式故事线/谜题等娱乐内容,增强群组活跃度,促进用户间深度互动。 -- **社交辅助工具**:AIGC 技术在聊天过程中生成表情包、GIF 动图、多语言翻译等个性化内容,满足用户表达需求,提升沟通乐趣。 - -## 亮点功能 - -**模型能力** - -- 集成了国内外多语言大模型,可以根据用户输入实时生成高质量的内容回复。 -- 支持跨语言沟通,并可针对不同领域提供定制化的智能对话服务。 - -**多模态交互与融合** - -- AI 模型能够基于文本、语音、图像等多元信息进行理解并产出相应的内容。 -- AI+IM 可以自动生成图文混排、动态表情、互动卡片等内容,丰富聊天体验。 - -**消息触达能力** - -- 结合 AIGC 技术,可实现智能化消息推荐,例如,根据上下文情境自动发送相关信息或提示。 -- 实时高效离线唤醒推送机制,根据用户行为和偏好进行定制化推送,提高推送效果和转化率。 - -**群组模型与协同创作** - -- 在群聊环境中,AI 可以辅助管理群组讨论,如提炼关键信息、总结讨论要点。 -- 支持多个 AI 机器人同时参与群聊讨论,多角色分工,从不同角度对用户提问进行协作回答。 - -## 方案优势 - -环信 AIGC 解决方案具有如下优势: - -**1. 海量并发,稳定可靠的平台能力** - -支持多重备份、灾备恢复、回调容灾等技术手段,单日数十亿级别的消息传输和处理,SLA 达 99.99%,持续保障系统高可用性和可靠性。 - -**2. 国际化加速,提升出海使用体验** - -提供快速、准确的消息传递和响应,全球平均时延小于 100 ms,使得用户交互过程流畅自然,提升应用的竞争力和用户满意度。 - -**3. 易开发,方案快速上线** - -开发者可以通过调用 API 等方式快速构建智能交互功能,提供开箱即用的场景化 Demo,最快 1 天实现方案快速验证。 - -**4. 内容审核,为应用安全保驾护航** - -基于先进的算法和 AI 技术,在保证高效性和准确性的同时,自动检测和屏蔽不合规信息,确保聊天环境的健康和安全。 - -**5. 安全合规,保障用户隐私安全** - -支持国内外不同区域合规要求,根据最小化和公开透明处理原则,保护不同区域的网络安全、数据安全及用户隐私安全。 - -**6. 卓越服务,助力战略愿景落地** - -支持全球范围内的企业级客户服务,具备丰富的行业标杆客户案例,提供专属方案咨询、集成顾问、营销推广及客户成功保障服务。 - - - - diff --git a/docs/product/aigc/aigc_selection.md b/docs/product/aigc/aigc_selection.md deleted file mode 100644 index 925df9ec..00000000 --- a/docs/product/aigc/aigc_selection.md +++ /dev/null @@ -1,49 +0,0 @@ -# 环信 AIGC 方案选择 - -本文提供两种方案供你接入环信 AI 聊天服务,实现与机器人的聊天功能: - -- **方案一**:利用服务器回调服务,在 IM 中引入 AI 服务。 -- **方案二**:使用环信即时通讯云提供的 AI 智能功能。 - -## 方案一 - -通过配置服务端和客户端,利用环信即时通信 IM 服务器回调功能,在 IM 中引入 AI 服务(以 MiniMax 中文大语言模型为例),创建机器人账号,从而跑通示例项目。 - -### 技术架构 - -目前,环信 AIGC 方案可通过服务器回调服务实现与机器人聊天,以单聊为例,工作流程如下: - -1. 用户发消息给机器人。 -2. 环信服务器收到消息后,通过服务端回调将事件通知第三方大模型厂商。 -3. 第三方大模型厂商收到事件通知,将消息回复内容发送给 app server。 -4. app server 调用 Restful API 将回复内容发送给环信服务器。 -5. 环信服务器将回复内容发送给用户。 - -![img](/images/aigc/technical_architecture1.png) - -### 跑通示例项目 - -完成客户端和服务端配置,跑通 [GitHub 示例项目](https://github.com/easemob/Easemob-AIGCService-Example),体验与 AIGC 数字人沟通方案。 - -有关更多信息,请参见[跑通示例项目文档说明](aigc_run_through_demo_server.html)。 - -## 方案二 - -使用环信即时通讯 IM 提供的 AI 机器人聊天。你需要在[环信即时通讯控制台](https://console.easemob.com/user/login)开通 AI 智能功能,创建机器人,即实现与机器人的**单聊**功能。 - -此外,你可以在[环信即时通讯控制台](https://console.easemob.com/user/login)查看机器人账号消耗的 token 数和消耗趋势。 - -有关更多信息,请参见[使用 AI 机器人聊天](aigc_use.html)和[调用 REST API 获取 app 下的机器人列表](aigc_rest_api.html)相关文档。 - -### 技术架构 - -目前,环信 AI 智能功能**仅支持单聊**,工作流程如下: - -1. 用户发消息给机器人。 -2. 环信服务器收到消息后,通过环信机器人服务将用户消息传递给第三方大模型厂商。 -3. 第三方大模型厂商对用户消息进行回复,将消息回复内容发送给环信机器人服务。 -4. 环信机器人服务收到消息后,通过环信服务器将回复内容发送给用户。 - -![img](/images/aigc/technical_architecture2.png) - - diff --git a/docs/product/aigc/aigc_use.md b/docs/product/aigc/aigc_use.md deleted file mode 100644 index 39ac1fd9..00000000 --- a/docs/product/aigc/aigc_use.md +++ /dev/null @@ -1,80 +0,0 @@ -# 使用 AI 智能功能 - -使用 AI 机器人聊天,你需要首先开通 AI 智能功能,然后创建机器人,与机器人进行**一对一聊天**。 - -## 1. 开通 AI 智能功能 - -你可以在[环信即时通讯控制台](https://console.easemob.com/user/login)开通 AI 智能功能。 - -1. 登录[环信即时通讯云控制台](https://console.easemob.com/user/login),在首页的**应用列表**区域点击目标应用的**操作**一栏中的**管理**。 - -![img](/images/aigc/app_select.png) - -2. 选择**即时通讯** > **功能配置** > **功能配置总览**。选择**试用功能**页签,点击**智能机器人 Chatbot** 对应的**操作**一栏中的**申请试用**。 - -![img](/images/aigc/ai_open.png) - -## 2. 创建机器人 - -1. 选择**即时通讯** > **AI 智能** > **AI机器人**,进入 **AI 机器人**页面。点击**创建机器人**。 - -:::tip -每个 app 默认支持 200 个机器人,可联系环信商务提升该上限。 -::: - -![img](/images/aigc/aichatbot_create.png) - -2. 配置机器人相关信息。 - -![img](/images/aigc/aichatbot_configure.png) - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :----------- | :--------- | -| 机器人名称 | String | 是 | 机器人的名称,长度在 64 个字符内。 | -| 用户 ID | String | 是 | 机器人对应的 IM 的用户 ID。目前一个机器人只能绑定一个用户 ID。
**若输入了不存在的用户 ID,配置机器人信息后,会自动创建用户。**
用户 ID 长度不可超过 64 个字节。不可设置为空。支持以下字符集:
- 26 个小写英文字母 a-z;
- 26 个大写英文字母 A-Z;
- 10 个数字 0-9;
- “\_”, “-”, “.”。

- 该参数不区分大小写,因此 `Aa` 和 `aa` 为相同的用户 ID;
- 请确保同一个 app 下,用户 ID 唯一;
- 用户 ID 为公开信息,请勿使用 UUID、邮箱地址、手机号等敏感信息。
| -| 头像 | String | 是 | 机器人的头像图片链接。 | -| AI引擎 | | 是 | 目前只能选择 **MINIMAX**。 | -| Model | | 是 | 厂商支持的 AI 模型类别,当前可支持选择。关于 API 模型类别的详细介绍,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/Models?key=66701cb01d57f38758d581a4)。 | -| System prompt | String | 是 | 具体机器人的设定,长度影响接口性能。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 | -| Top-p | Int | 是 | 控制生成环节采样范围,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。| -| Temperature | Int | 是 | 控制生成环境采样随机性,参数值越小,生成结果越稳定。关于该参数的更多详情,请参阅 [MiniMax 官方文档](https://platform.minimaxi.com/document/ChatCompletion%20Pro?key=66718f6ba427f0c8a57015ff)。 | - -3. 查看新创建的机器人。 - -![img](/images/aigc/aichatbot_view.png) - -## 3. 使用机器人聊天 - -创建机器人账户后,你可以体验和它进行**一对一聊天**。 - -1. 若你开启了好友关系检查功能(**即时通讯** > **服务概览** > **设置**),可以在**即时通讯 > 运营服务 > 用户管理** 页面,添加机器人绑定的即时通讯 IM 用户为好友。例如,图中的 **aitest** 用户添加新创建的 **bbb** 用户为好友,与机器人 **aaa** 进行聊天。在 **aitest1** 用户的**操作**一栏中选择**查看IM用户好友**,在文本框中输入 **bbb**,点击**添加好友**。 - -:::tip -若关闭了好友检查功能,则无需添加好友即可聊天。 -::: - -![img](/images/aigc/ai_add_contact.png) - -2. 用户 **aitest** 与机器人 **aaa** 进行聊天,以下截图以 Android 设备为例。 - - - -## 4. 查看数据统计 - -你可以在[环信即时通讯控制台](https://console.easemob.com/user/login)的左侧导航栏选择 **即时通讯** > **AI 智能** > **数据统计**,查看机器人账号消耗的 token 数和消耗趋势。 - -目前,大模型平台只能选择 **MINIMAX**。 - -![img](/images/aigc/ai_token_statistic.png) - - - - - - - - - - - - diff --git a/docs/product/circle/api_reference_android.md b/docs/product/circle/api_reference_android.md deleted file mode 100644 index 6e434f9c..00000000 --- a/docs/product/circle/api_reference_android.md +++ /dev/null @@ -1,7 +0,0 @@ -# 环信超级社区 Android SDK API 参考 - - - -若要访问环信超级社区 Android SDK API 参考,请点击[这里](https://www.easemob.com/apidoc/Android/hyphenate-api-doc/html/annotated.html)。 - - diff --git a/docs/product/circle/api_reference_ios.md b/docs/product/circle/api_reference_ios.md deleted file mode 100644 index 3ab48bd8..00000000 --- a/docs/product/circle/api_reference_ios.md +++ /dev/null @@ -1,5 +0,0 @@ -# 环信超级社区 iOS SDK API 参考 - - - -若要访问环信超级社区 iOS SDK API 参考,请点击[这里](https://www.easemob.com/apidoc/iOS/html_ch/annotated.html)。 \ No newline at end of file diff --git a/docs/product/circle/api_reference_web.md b/docs/product/circle/api_reference_web.md deleted file mode 100644 index 1dbe6926..00000000 --- a/docs/product/circle/api_reference_web.md +++ /dev/null @@ -1,5 +0,0 @@ -# 环信超级社区 Web SDK API 参考 - - - -若要访问环信超级社区 Web SDK API 参考,请点击[这里](https://www.easemob.com/apidoc/Web/)。 \ No newline at end of file diff --git a/docs/product/circle/category_mgmt_android.md b/docs/product/circle/category_mgmt_android.md deleted file mode 100644 index 91b3ebdf..00000000 --- a/docs/product/circle/category_mgmt_android.md +++ /dev/null @@ -1,173 +0,0 @@ -# 管理频道分组 - - - -环信超级社区(Circle)支持将多个频道归入一个频道分组,方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。 - -社区创建时会创建默认的频道分组,包含默认频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_android.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_android.html#解散社区)和[删除频道](channel_mgmt_android.html#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 提供 `EMCircleManager` 类和 `EMCircleCategory` 类用于频道分组管理,支持你通过调用 API 实现如下功能: - -- 创建和管理频道分组; -- 监听频道分组事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html) -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -### 创建频道分组 - -仅社区所有者可以调用 `createCategory` 方法创建频道分组。创建频道分组时需设置频道分组所属的社区 ID 和频道分组名称。频道分组创建后,社区所有成员(除创建者外)会收到 `EMCircleCategoryListener#onCategoryCreated` 事件。 - -每个社区下最多可创建 50 个频道分组,超过需要联系商务。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().createCategory(serverId, categoryName, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleCategory value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -### 修改频道分组名称 - -仅社区所有者和管理员可调用 `updateCategory` 方法修改频道分组名称。频道分组名称修改后,社区所有成员(除操作者外)会收到 `EMCircleCategoryListener#onCategoryUpdated` 事件。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().updateCategory(serverId, categoryId, categoryName, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleCategory value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -### 删除频道分组 - -仅社区所有者可调用 `destroyCategory` 方法删除频道分组。社区所有成员(除操作者外)会收到 `EMCircleCategoryListener#onCategoryDestroyed` 事件。频道分组删除后,该频道分组下的所有频道会移至当前社区的默认频道分组下。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().destroyCategory(serverId, categoryId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } - }); -``` - -### 分页获取社区下的频道分组列表 - -社区中的所有成员可以调用 `fetchCategoriesInServer` 方法获取社区下的频道分组列表。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchCategoriesInServer(serverID, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } - }); -``` - -### 更换指定频道的频道分组 - -仅社区所有者和管理员可以调用 `transferChannel` 方法将指定频道从一个频道分组转移至另一个频道分组。频道分组更换后,社区所有成员(除操作者外)会收到 `EMCircleCategoryListener#onChannelTransfered` 事件。 - -:::tip -调用该方法时,若 `newCategoryId` 参数传入 `null` 或空字符串 `""`,表示将频道归入社区默认的频道分组。 -::: - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().transferChannel(serverId,channelId, newCategoryId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } - }); -``` - -### 监听频道分组事件 - -`EMCircleManager` 中提供频道分组事件的监听接口。开发者可以通过设置此监听,获取频道分组中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。 - -```java -EMCircleCategoryListener chatCategoryListener = new EMCircleCategoryListener() { - //创建了频道分组。社区所有成员(除创建者外)会收到该事件。 - @Override - public void onCategoryCreated(EMCircleCategory category, String creator) { - - } - //删除了频道分组。社区所有成员(除操作者外)会收到该事件。 - @Override - public void onCategoryDestroyed(String serverId, String categoryId, String initiator) { - - } - //修改了频道分组名称。社区所有成员(除操作者外)会收到该事件。 - @Override - public void onCategoryUpdated(EMCircleCategory category, String initiator) { - - } - //频道更换了分组。社区所有成员(除操作者外)会收到该事件。 - @Override - public void onChannelTransfered(String serverId, String fromCategoryId, String toCategoryId, String channelId, String initiator) { - - } -}; - -//添加频道分组监听。 -EMClient.getInstance().chatCircleManager().addCategoryListener(chatCategoryListener); -//移除频道分组监听。 -EMClient.getInstance().chatCircleManager().removeCategoryListener(chatCategoryListener); -//清除所有频道分组监听。 -EMClient.getInstance().chatCircleManager().clearCategoryListeners(); -``` \ No newline at end of file diff --git a/docs/product/circle/category_mgmt_ios.md b/docs/product/circle/category_mgmt_ios.md deleted file mode 100644 index c1e83166..00000000 --- a/docs/product/circle/category_mgmt_ios.md +++ /dev/null @@ -1,121 +0,0 @@ -# 管理频道分组 - - - -环信超级社区(Circle)支持将多个频道归入一个频道分组,方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。 - -社区创建时会创建默认的频道分组,包含默认频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_ios.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_ios.html#解散社区)和[删除频道](channel_mgmt_ios.html#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 提供 `IEMCircleManager` 类和 `EMCircleManagerCategoryDelegate` 类用于频道分组管理,支持你通过调用 API 实现如下功能: - -- 创建和管理频道分组; -- 监听频道分组事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -### 创建频道分组 - -仅社区所有者可以调用 `createCategory` 方法创建频道分组。创建频道分组时需设置频道分组所属的社区 ID 和频道分组名称。频道分组创建后,社区所有成员(除创建者外)会收到 `EMCircleManagerCategoryDelegate#onCategoryCreated` 事件。 - -每个社区下最多可创建 50 个频道分组,超过需要联系商务。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.createCategory(serverId, name: name, completion: { category, error in -}) -``` - -### 修改频道分组名称 - -仅社区所有者和管理员可调用 `updateCategory` 方法修改频道分组名称。频道分组名称修改后,社区所有成员(除操作者外)会收到 `onCategoryUpdated` 事件。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.updateCategory(serverId, categoryId: categoryId, name: name, completion: { category, error in -}) -``` - -### 删除频道分组 - -仅社区所有者可调用 `destroyCategory` 方法删除频道分组。社区所有成员(除操作者外)会收到 `EMCircleManagerCategoryDelegate#onCategoryDestroyed` 事件。频道分组删除后,该频道分组下的所有频道会移至当前社区的默认频道分组下。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.destroyCategory(self.serverId, categoryId: self.groupId, completion: { error in -}) -``` - -### 分页获取社区下的频道分组列表 - -社区中的所有成员可以调用 `fetchCategories` 方法获取社区下的频道分组列表。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchCategories(inServer: self.serverId, limit: 20, cursor: refresh ? nil : self.result?.cursor, completion: { result, error in -}) -``` - -### 更换指定频道的频道分组 - -仅社区所有者和管理员可以调用 `transferChannel` 方法将指定频道从一个频道分组转移至另一个频道分组。频道分组更换后,社区所有成员(除操作者外)会收到 `EMCircleManagerCategoryDelegate#onChannelTransferred` 事件。 - -:::tip -调用该方法时,若 `newCategoryId` 参数传入 `nil` 或空字符串 `""`,表示将频道归入社区默认的频道分组。 -::: - -示例代码如下: - -```swift -EMClient.shared().circleManager?.transferChannel(self.serverId, channelId: self.channelId, newCategoryId: category.categoryId, completion: { error in -}) -``` - -### 监听频道分组事件 - -`IEMCircleManager` 中提供频道分组事件的监听接口。开发者可以通过设置此监听,获取频道分组中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。 - -```swift -//添加频道分组回调代理。 -EMClient.shared().circleManager?.add(categoryDelegate: self, queue: nil) -//移除频道分组回调代理。 -EMClient.shared().circleManager?.remove(categoryDelegate: self) -``` - -```swift -//创建了频道分组。社区所有成员(除创建者外)会收到该事件。 -func onCategoryCreated(_ category: EMCircleCategory, creator: String) { -} - -//删除了频道分组。社区所有成员(除操作者外)会收到该事件。 -func onCategoryDestroyed(_ serverId: String, categoryId: String, initiator: String) { -} - -//修改了频道分组名称。社区所有成员(除操作者外)会收到该事件。 -func onCategoryUpdated(_ category: EMCircleCategory, initiator: String) { -} - -//频道更换了分组。社区所有成员(除操作者外)会收到该事件。 -func onChannelTransferred(_ serverId: String, from fromCategoryId: String, to toCategoryId: String, channelId: String, initiator: String) { -} -``` diff --git a/docs/product/circle/category_mgmt_rest.md b/docs/product/circle/category_mgmt_rest.md deleted file mode 100644 index 3ef05588..00000000 --- a/docs/product/circle/category_mgmt_rest.md +++ /dev/null @@ -1,699 +0,0 @@ -# 管理社区频道分组 - - - -环信超级社区(Circle)支持频道分组方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。 - -社区创建时会创建默认的频道分组,包含默认频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者调用 RESTful API 解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_rest.html#查询指定频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_rest.html#删除社区)和[删除频道](channel_mgmt_rest.html#删除频道)等 API。** - -## 前提条件 - -要调用环信即时通讯 RESTful API,请确保满足以下要求: - -- 已在环信即时通讯控制台 [开通配置环信即时通讯 IM 服务](/document/server-side/enable_and_configure_IM.html)。 -- 了解环信 IM RESTful API 的调用频率限制,详见 [接口频率限制](/product/limitationapi.html)。 - -## 公共参数 - -### 请求参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :----------------------------------------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见[获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见[获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见[获取环信即时通讯 IM 的信息](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `server_id` | String | 是 | 社区 ID。 | -| `channel_id` | String | 是 | 频道 ID。 | -| `channel_category_id` | String | 是 | 频道分组 ID。 | -| `user_id` | String | 是 | 用户 ID。 | - -:::tip -对于分页获取数据列表,若查询参数中的 `limit` 和 `cursor` 均未设置,则服务器返回首页的数据列表。 -::: - -### 响应参数 - -| 参数 | 类型 | 描述 | -| :-----------------| :----- | :----------------------------------------------------------- | -| `channels.owner` | String | 频道创建者。 | -| `channels.name` | String | 频道名称。 | -| `channels.type` | Int | 频道类型:
- `0`:公开频道;
- `1`:私密频道。 | -| `channels.mode` | Int | 频道模式:
- `0`:文字频道;
- `1`:语聊频道。 | -| `channels.description` | String | 频道描述。| -| `channels.custom` | String | 频道的扩展信息。 | -| `channels.created` | Long | 频道的创建时间,Unix 时间戳,单位为毫秒。 | -| `channels.server_id` | String | 社区 ID。 | -| `channels.channel_category_id` | String | 频道分组 ID。 | -| `channels.channel_id` | String | 频道 ID。 | -| `channels.max_users` | Long | 频道最大成员数量。 | -| `channels.default_channel` | Int | 是否为社区的默认频道:
- `0`:否;
- `1`:是。 | -| `rtc_name` | String | RTC 频道名称。该名称在加入 RTC 频道时使用。若使用声网 RTC,该名称还用于[生成 RTC Token](https://docportal.shengwang.cn/cn/voice-call-4.x/token_server_android_ng?platform=Android)。
该参数仅在创建语聊频道时返回,若创建语聊房频道时未指定 `rtc_name`,服务器将使用频道 ID 作为该参数的值返回。 | - -## 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段: - -Authorization:`Bearer ${YourToken}` - -为提高项目的安全性,环信使用 App Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 需使用 App Token 的鉴权方式,详见 [使用环信 App Token 鉴权](/product/easemob_app_token.html)。 - -## 创建频道分组 - -在社区下创建一个频道分组,将多个频道归入一个频道分组方便管理。 - -每个社区下最多可以创建 50 个频道分组。每个频道只能加入一个频道分组。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/channel/category -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### 请求 body - -| 参数 | 类型 | 是否必需 | 备注 | -| :---------- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID,即频道分组所属的社区。 | -| `name` | String | 是 | 频道分组名称,长度不能超过 50 个字符。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------- | :----- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channel_category_id` | String | 频道分组 ID。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category' -d '{ - "server_id" : "19SW5Q85jHxxxxx6T5kexvn", - "name" : "channel category name" -}' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "channel_category_id": "77a9860xxxxxx2b54881025861c", -} -``` - -## 修改频道分组的名称 - -修改指定社区下的特定频道分组的名称。 - -### HTTP 请求 - -```http -PUT https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### 请求 body - -| 参数 | 类型 | 是否必需 | 备注 | -| :---------- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID,即要修改的频道分组所属社区的 ID。 | -| `name` | String | 是 | 修改后的频道分组名称,长度不能超过 50 个字符。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channelCategory` | JSON | 频道分组的数据。 | -| `channelCategory.name` | String | 修改后的频道分组名称。 | -| `channelCategory.created` | Long | 频道分组的创建时间,Unix 时间戳,单位为毫秒。 | -| `channelCategory.channel_category_id` | String | 频道分组 ID。 | - -其他字段及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX' -d '{ - "server_id" : "19SW5Q85jHxxxxx6T5kexvn", - "name" : "update channel category name" -}' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "channelCategory": { - "name": "update channel category name", - "created": 1667471759201, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "channel_category_id": "77a9860xxxxxx2b54881025861c" - } -} -``` - -## 删除社区下的频道分组 - -删除指定社区下的特定频道分组。删除频道分组后,该频道分组下的所有频道会添加到社区的默认频道分组中。 - -### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}?serverId={server_id} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX?serverId=XXX' -``` - -#### 响应示例 - -```json -{ - "code": 200 -} -``` - -## 更换频道的频道分组 - -将指定频道从当前频道分组转移至其他频道分组。 - -### HTTP 请求 - -```http -POST -http://{host}/{org_name}/{app_name}/circle/channel/category/member/transfer?serverId={server_id}&channelCategoryId={channel_category_id}&channelId={channel_id} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------------- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。 | -| `channel_category_id` | String | 否 | 频道分组 ID。请求时若设置了该参数,会将频道转移至指定的频道分组中;若不设置该参数,则将频道转移至社区的默认频道分组中。 | -| `channel_id` | String | 是 | 要转移频道分组的频道 ID。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----------- | :----- | :--------------------------------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | - -其他字段及描述详见[公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/member/transfer?serverId=XXX&channelCategoryId=XXX&channelId=XXX' -``` - -#### 响应示例 - -```json -{ - "code": 200 -} -``` - -## 获取社区下的频道分组列表 - -分页获取指定社区下的频道分组列表。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/category/list?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。| -| `limit` | Int | 否 | 每页获取的社区下的频道分组数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。 | -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :--------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取的频道分组数量。 | -| `channelCategoryList` | List | 获取的频道分组列表。 | -| `channelCategoryList.name` | String| 频道分组名称。 | -| `channelCategoryList.created` | Long | 频道分组的创建时间。 | -| `channelCategoryList.channel_category_id` | String | 频道分组 ID。 | -| `cursor` | String | 查询游标,指定下次数据查询的起始位置。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/list?serverId=XXX' -``` -#### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channelCategoryList": [ - { - "name": "channel category name", - "created": 1667471759201, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "channel_category_id": "77a9860xxxxxx2b54881025861c" - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -## 获取指定频道分组下的频道列表 - -分页获取指定频道分组下的所有频道的列表(包括公开和私密频道)。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/member/list?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。| -| `limit` | Int | 否 | 每页获取的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。| -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---- | :--- | :------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取的指定频道分组下的频道数量。 | -| `channels` | List | 获取的频道列表。 | -| `cursor` | String | 游标,指定下次数据查询的起始位置。 | - -其他字段及描述详见[公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/member/list?serverId=xxx?limit={limit}&cursor={cursor}' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -## 获取指定频道分组下的公开频道列表 - -分页获取指定频道分组下的公开频道列表。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/public/member/list?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。| -| `channel_category_id` | String | 是 | 频道分组 ID。| -| `limit` | Int | 否 | 每页获取的公开频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。| -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---- | :--- | :------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取的公开频道数量。 | -| `channels` | List | 获取的指定频道分组下的公开频道列表。 | -| `cursor` | String | 游标,指定下次数据查询的起始位置。 | - -其他字段及描述详见[公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/public/member/list?serverId=XXX' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` -## 获取指定频道分组下的私密频道列表 - -分页获取频道分组下的私密频道列表。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/private/member/list?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。| -| `limit` | Int | 否 | 每页获取的社区频道分组下私密频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。 | -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---- | :--- | :------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取的私密频道数量。 | -| `channels` | List | 获取的指定频道分组下的私密频道列表。 | -| `cursor` | String | 游标,指定下次数据查询的起始位置。 | - -其他字段及描述详见[公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/private/member/list?serverId=XXX' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "chat channel", - "type": 1, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2090xxxxxx2369", - "max_users": 200, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -## 获取指定频道分组下用户加入的频道列表 - -分页获取指定频道分组下用户加入的频道 ID 列表。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/category/{channel_category_id}/user/joined/member/list?serverId={server_id}&userId={user_id}&limit={limit}&cursor={cursor} -``` - -#### 路径参数 - -参数及描述详见[公共参数](#公共参数)。 - -#### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。| -| `user_id` | String | 是 | 用户 ID。| -| `limit` | Int | 否 | 每页获取的用户在指定频道分组下加入的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。| -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---- | :--- | :------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取的用户在指定的频道分组下加入的频道数量。 | -| `channelIds` | List | 获取的用户在指定的频道分组下加入的频道 ID 列表。 | -| `cursor` | String | 游标,指定下次数据查询的起始位置。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/category/XXX/user/joined/member/list?serverId=XXX&userId=XXX' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channelIds": [ - "2090xxxxxx2369" - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - - diff --git a/docs/product/circle/category_mgmt_web.md b/docs/product/circle/category_mgmt_web.md deleted file mode 100644 index 30d36297..00000000 --- a/docs/product/circle/category_mgmt_web.md +++ /dev/null @@ -1,133 +0,0 @@ -# 管理频道分组 - - - -环信超级社区(Circle)支持将多个频道归入一个频道分组,方便频道管理。例如,可将歌剧频道、民歌频道和流行歌曲频道划分为声乐频道分组。 - -社区创建时会创建默认的频道分组,包含默认频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_web.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_web.html#解散社区)和[删除频道](channel_mgmt_web.html#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 支持你通过调用 API 实现如下功能: - -- 创建和管理频道分组; -- 监听频道分组事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -### 创建频道分组 - -仅社区所有者可以调用 `createCategory` 方法创建频道分组。创建频道分组时需设置频道分组所属的社区 ID 和频道分组名称。频道分组创建后,社区所有成员(除创建者外)会收到 `onCategoryEvent` 回调,事件为 `create`。 - -每个社区下最多可创建 50 个频道分组,超过需要联系商务。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - name: 'categoryName', -} -WebIM.conn.createCategory(options).then(res => { - console.log(res) -}) -``` - -### 修改频道分组名称 - -仅社区所有者和管理员可调用 `updateCategory` 方法修改频道分组名称。频道分组名称修改后,社区所有成员(除操作者外)会收到 `onCategoryEvent` 回调,事件为 `update`。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - categoryId: 'categoryId', - name: 'categoryName', -} -WebIM.conn.updateCategory(options).then(res => { - console.log(res) -}) -``` - -### 删除频道分组 - -仅社区所有者可调用 `deleteCategory` 方法删除频道分组。社区所有成员(除操作者外)会收到 `onCategoryEvent` 回调,事件为 `destroy`。频道分组删除后,分组下的频道会移至当前社区的默认分组下。 - -示例代码如下: - -```javascript -WebIM.conn.deleteCategory({serverId: 'serverId', categoryId: 'categoryId',}).then(res => { - console.log(res) -}) -``` - -### 分页获取社区下的频道分组列表 - -社区中的所有成员可以调用 `getCategorylist` 方法获取社区下的频道分组列表。 - -示例代码如下: - -```javascript -WebIM.conn.getCategorylist({serverId: 'serverId',pageSize:'20',cursor:''}).then(res => { - console.log(res) -}) -``` - -### 更换指定频道的频道分组 - -仅社区所有者和管理员可以调用 `transferChannel` 方法将指定频道从一个频道分组转移至另一个频道分组。频道分组更换后,社区所有成员(除操作者外)会收到 `onCategoryEvent` 回调,事件为 `transferChannel`。 - -:::tip -调用该方法时,若 `newCategoryId` 参数传入 `null`、空字符串(``)或者不传,表示将频道归入社区默认的频道分组。 -::: - -示例代码如下: - -```javascript -WebIM.conn.transferChannel({serverId: 'serverId',channelId: 'channelId',newCategoryId:'newCategoryId'}).then(res => { - console.log(res) -}) -``` - -### 监听频道分组事件 - -Circle 提供 `addEventHandler` 方法用于注册监听事件。开发者可以通过设置此监听,获取频道分组中的事件。 - -```javascript -WebIM.conn.addEventHandler('CIRCLE',{ - onServerEvent:(msg) => { - switch (msg.operation){ - case "create": - //创建频道分组。社区所有成员(除创建者外)会收到该事件。 - break; - case "update": - //修改了频道分组名称。社区所有成员(除创建者外)会收到该事件。 - break; - case "destroy": - //删除了频道分组。社区所有成员(除创建者外)会收到该事件。 - break; - case "transferChannel": - //频道更换了分组。社区所有成员(除创建者外)会收到该事件。 - break; - default: - break; - } - }, -}); -``` \ No newline at end of file diff --git a/docs/product/circle/channel_mgmt_android.md b/docs/product/circle/channel_mgmt_android.md deleted file mode 100644 index b609e7e3..00000000 --- a/docs/product/circle/channel_mgmt_android.md +++ /dev/null @@ -1,589 +0,0 @@ -# 管理频道 - - - -频道(Channel)是一个社区下不同子话题的讨论分区,因此一个社区下可以有多个频道。社区创建时会自动创建默认频道,该频道中添加了所有社区成员,用于承载各种系统通知。从可见性角度看,频道社区分为公开和私密频道;从功能角度看,频道分为文字频道和语聊频道。社区创建者可以根据自己需求创建频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_android.html#解散社区)和[删除频道](#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 提供 `EMCircleManager` 类和 `EMCircleChannel` 类用于频道管理,支持你通过调用 API 在项目中实现如下功能: - -- 创建和管理频道; -- 管理频道成员; -- 监听频道事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -本节介绍如何使用环信即时通讯 IM Android SDK 提供的 API 实现上述功能。 - -### 创建和管理频道 - -#### 创建频道 - -1. 社区所有者可以调用 `createChannel` 方法在社区中创建公开或私密频道。参与频道创建的初始成员会收到 `EMCircleChannelListener#onChannelCreated` 事件。 - -每个社区默认最多可创建 100 个频道。如需调整该阈值,请联系商务。 - -示例代码如下: - -```java -EMCircleChannelAttribute attribute = new EMCircleChannelAttribute(); - attribute.setName(name); - attribute.setDesc(desc); - attribute.setMaxUsers(2000); - attribute.setType(EMCircleChannelStyle.EMChannelStylePublic); - -EMClient.getInstance().chatCircleManager().createChannel(serverId, categoryId, attribute, EMCircleChannelModeChat, new EMValueCallBack() { - - @Override - public void onSuccess(EMCircleChannel value) { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -创建频道时,需设置社区 ID、频道分组 ID、频道模式以及频道属性 `EMCircleChannelAttribute`,如下表所示。 - -| 参数 | 类型 | 描述 | 是否必需 | -| :--------- | :----------------------- | :------------------ |:------------------ | -| serverId | String | 社区 ID。 | 是 | -| categoryId | String | 频道分组 ID。 | 否 | -| mode | EMCircleChannelMode | 频道模式:
- `EMCircleChannelModeChat`:文字频道;
- `EMCircleChannelModeVoice`:语聊频道。 | 是 | -| EMCircleChannelAttribute.name | String | 频道名称,不超过 50 个字符。 | 是 | -| EMCircleChannelAttribute.desc | String | 频道描述,不超过 500 个字符。 | 否 | -| EMCircleChannelAttribute.maxUsers | Int | 频道最大成员数量:
- 对于语聊频道,该属性的取值范围为 [1,20],默认值为 `8`;
- 对于文字频道,该属性的取值范围为 [1,2000],默认值为 `2000`。 | 否 | -| EMCircleChannelAttribute.type | EMCircleChannelStyle | 频道类型:
- (默认)`EMChannelStylePublic`:公开频道;
- `EMChannelStylePrivate`:私密频道。 | 否 | -| EMCircleChannelAttribute.ext | String | 频道自定义扩展信息,不超过 500 个字符。 | 否 | -| EMCircleChannelAttribute.rtcChannelId | String | RTC 频道 ID。该参数仅在创建语聊频道时需设置。若不设置,服务器使用创建的语聊频道的 ID 作为该参数的值返回。 | 否 | - -2. 邀请用户加入频道。 - -社区中的用户可以自由加入社区下的公开频道,私密频道只能由频道成员邀请用户加入。 - -频道创建者调用 `inviteUserToChannel` 方法邀请用户加入频道。受邀用户收到 `EMCircleChannelListener#onReceiveInvitation` 事件。 - -```java -EMClient.getInstance().chatCircleManager().inviteUserToChannel(serverId, channelId, inviteeUserId, "welcome", new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } - }); -``` - -3. 受邀用户确认是否加入频道。 - - - 用户调用 `acceptChannelInvitation` 方法同意加入频道,邀请人收到 `EMCircleChannelListener#onInvitationBeAccepted` 事件,频道所有成员(不包括该新加入的成员)收到 `EMCircleChannelListener#onMemberJoinedChannel` 事件。示例代码如下: - - ```java - EMClient.getInstance().chatCircleManager().acceptChannelInvitation(serverId, channelId, inviterUserId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleChannel circleChannel) { - - } - - @Override - public void onError(int code, String message) { - - } - }); - ``` - -- 用户调用 `declineChannelInvitation` 方法拒绝加入频道,邀请人收到 `EMCircleChannelListener#onInvitationBeDeclined` 事件。示例代码如下: - - ```java - EMClient.getInstance().chatCircleManager().declineChannelInvitation(serverId,channelId, inviterUserId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String message) { - - } - }); - ``` - -4. 用户加入频道后,可在频道中发送和接收消息。 - -#### 修改频道信息 - -仅社区所有者和管理员可调用 `updateChannel` 方法修改频道属性 `EMCircleChannelAttribute`,包括频道名称、类型(公开/私有)、描述、最大成员数量和自定义扩展信息。频道所有成员(除操作者外)会收到 `EMCircleChannelListener#onChannelUpdated` 事件。频道创建后,频道模式(文字或语聊)不能修改。 - -若更换频道所属的频道分组,需调用 [transferChannel](category_mgmt_android.html#更换指定频道的频道分组)方法。 - -示例代码如下: - -```java -EMCircleChannelAttribute attribute = new EMCircleChannelAttribute(); - attribute.setName(name); - attribute.setDesc(desc); - -EMClient.getInstance().chatCircleManager().updateChannel(serverId, channelId, attribute, new EMValueCallBack() { - - @Override - public void onSuccess(EMCircleChannel value) { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 解散频道 - -仅社区所有者可以调用 `destroyChannel` 方法解散社区中的频道。频道内其他成员收到 `EMCircleChannelListener#onChannelDestroyed` 事件并被移出频道。 - -示例代码如下: - -```java - EMClient.getInstance().chatCircleManager().destroyChannel(serverId, channelId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 获取频道详情 - -社区成员可以调用 `fetchChannelDetail` 方法获取频道的详情。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchChannelDetail(serverId, channelId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleChannel value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 获取频道列表 - -##### 获取社区的公开频道列表 - -社区成员可以调用 `fetchPublicChannelsInServer` 方法获取社区下的所有公开频道的列表,示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchPublicChannelsInServer(serverId, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -##### 获取社区的私密频道列表 - -社区成员可以调用 `fetchVisiblePrivateChannelsInServer` 方法获取社区下所有私密频道的列表。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchVisiblePrivateChannelsInServer(serverId, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -##### 获取社区中加入的频道 - -社区成员可以调用 `fetchJoinedChannelIdsInServer` 方法获取社区下加入的频道列表。 - -```java -EMClient.getInstance().chatCircleManager().fetchJoinedChannelIdsInServer(serverId, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -##### 获取频道分组的公开频道列表 - -社区成员可以调用 `fetchPublicChannelsInCategory` 方法获取频道分组下所有公开频道的列表,示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchPublicChannelsInCategory(serverId, categoryId,20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -##### 获取频道分组下的私密频道列表 - -调用 `fetchPrivateChannelsInCategory` 方法获取频道分组下的所有私密频道的列表,示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchPrivateChannelsInCategory(serverId, categoryId,20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -### 发送消息 - -在频道中发送消息与在群组中发送消息的方式类似,唯一的区别在于接收方需要设置为频道 ID。详见 [发送群聊消息](/document/android/message_send_receive.html)。 - -### 管理频道成员 - -#### 频道加人 - -用户加入频道分为两种方式:主动申请和频道成员邀请。 - -邀请用户加入频道,详见 [创建频道](#创建频道)。本节对用户申请加入频道进行详细介绍。 - -只有公开频道支持用户申请加入,私有频道不支持。若申请加入公开频道,用户需执行以下步骤: - -1. 用户可获取社区下的[公开频道列表](#获取社区的公开频道列表)。 - -2. 调用 `joinChannel` 方法传入社区 ID 和频道 ID,申请加入对应频道。用户加入频道后,频道所有成员(不包括该新加入的成员)会收到 `EMCircleChannelListener#onMemberJoinedChannel` 事件。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().joinChannel(serverId, channelId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleChannel value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -3. 用户加入频道后可以在频道中发送和接收消息。 - -#### 退出频道 - -##### 频道成员主动退出频道 - -频道所有成员可调用 `leaveChannel` 方法退出频道。频道内的其他成员会收到 `EMCircleChannelListener#onMemberLeftChannel` 事件。退出频道的成员不会再收到频道消息。 - -:::tip -社区内的默认频道不允许成员主动退出。 -::: - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().leaveChannel(serverId, channelId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -##### 频道成员被移出频道 - -仅频道所有者和管理员可以调用 `removeUserFromChannel` 方法将指定成员移出频道。被移出的频道的成员会收到 `EMCircleChannelListener#onMemberRemovedFromChannel`事件,其他成员会收到 `EMCircleChannelListener#onMemberLeftChannel` 事件。被移出频道的成员不会再收到频道消息。 - -:::tip -社区内的默认频道不允许踢出成员。 -::: - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().removeUserFromChannel(serverId, channelId, userId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 将成员加入频道禁言列表 - -社区所有者和社区管理员可以调用 `muteUserInChannel` 方法将频道成员加入禁言列表。被禁言的频道成员、社区所有者和管理员(除操作者外)会收到 `EMCircleChannelListener#onMemberMuteChanged` 事件。 - -禁言列表中的成员无法在频道中发送消息,但可以接收频道中的消息。 - -```java -long muteDuration = 24 * 60 * 60 * 1000;//毫秒 -EMClient.getInstance().chatCircleManager().muteUserInChannel(serverId, channelId, username, muteDuration, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 将成员移出频道禁言列表 - -社区所有者和社区管理员可以调用 `unmuteUserInChannel` 方法,将频道禁言列表上的频道成员移出频道禁言列表。被移出禁言列表的频道成员、社区所有者和管理员(除操作者外)会收到 `EMCircleChannelListener#onMemberMuteChanged` 事件。频道成员被移出禁言列表后可在频道中正常发送和接收消息。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().unmuteUserInChannel(serverId, channelId, username, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 获取频道禁言列表 - -社区所有者和社区管理员可以调用 `fetchChannelMuteUsers` 方法获取频道下的禁言列表。 - -```java -EMClient.getInstance().chatCircleManager().fetchChannelMuteUsers(serverId, channelId, new EMValueCallBack>() { - @Override - public void onSuccess(Map usersMuted) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } - }); -``` - -#### 获取指定频道的成员列表 - -频道中的成员可以获取该频道下的成员列表: - -- 创建语聊房频道时,创建者不加入频道。因此,频道创建者不算入频道成员数量,查询频道成员列表时不返回频道创建者。 - -- 对于其他模式的频道创建时,创建者直接加入频道。因此,频道创建者算入频道成员数量,查询频道成员列表返回频道创建者。 - -```java -EMClient.getInstance().chatCircleManager().fetchChannelMembers(serverId, channelId, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 查询当前用户是否在频道中 - -社区成员可调用 `checkSelfIsInChannel` 方法查询自己是否在指定频道中。示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().checkSelfIsInChannel(serverId, channelId, new EMValueCallBack() { - @Override - public void onSuccess(Boolean value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -### 监听频道事件 - -#### 单设备登录监听事件 - -`EMCircleManager` 中提供频道事件的监听接口。开发者可以通过设置此监听,获取频道中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。 - -```java -EMCircleChannelListener chatChannelListener = new EMCircleChannelListener() { - //创建频道。参与创建的初始成员会收到该事件。 - @Override - public void onChannelCreated(EMCircleChannel channel, String creator) { - - } - //解散频道。频道的所有成员(除操作者)会收到该事件。 - @Override - public void onChannelDestroyed(String serverId, String categoryId, String channelId, String initiator) { - - } - //修改频道信息。频道所有成员(除操作者外)会收到该事件。 - @Override - public void onChannelUpdated(EMCircleChannel channel, String initiator) { - - } - //有用户加入频道。频道的所有成员(不包括该新加入的成员)会收到该事件。 - @Override - public void onMemberJoinedChannel(String serverId, String categoryId, String channelId, EMCircleUser circleUser) { - - } - //有成员退出频道。频道内的其他成员会收到该事件。 - @Override - public void onMemberLeftChannel(String serverId, String categoryId, String channelId, String member) { - - } - //有成员被移出频道。被移出的成员会收到该事件。 - @Override - public void onMemberRemovedFromChannel(String serverId, String categoryId, String channelId, String member, String initiator) { - - } - //用户收到频道加入邀请。受邀用户会收到该事件。 - @Override - public void onReceiveInvitation(EMCircleChannelInviteInfo inviteInfo, String inviter) { - - } - //用户同意频道加入邀请。邀请人会收到该事件。 - @Override - public void onInvitationBeAccepted(String serverId, String categoryId, String channelId, String invitee) { - - } - //用户拒绝频道加入邀请。邀请人会收到该事件。 - @Override - public void onInvitationBeDeclined(String serverId, String categoryId, String channelId, String invitee) { - - } - //有成员的禁言状态发生变化。禁言状态变更的成员、社区所有者和管理员(除操作者外)会收到该事件。 - @Override - public void onMemberMuteChanged(String serverId, String categoryId, String channelId, boolean isMuted, List muteMembers) { - - } -}; - -//添加对频道的监听 -EMClient.getInstance().chatCircleManager().addChannelListener(chatChannelListener); -//移除频道的监听。 -EMClient.getInstance().chatCircleManager().removeChannelListener(chatChannelListener); -//清空所有频道的监听 -EMClient.getInstance().chatCircleManager().clearChannelListeners(); -``` - -#### 多设备登录监听事件 - -```java -public void onCircleChannelEvent(int event, String channelId, List usernames) { - switch (event) { - // 当前用户在其他设备上创建频道。 - case CHANNEL_CREATE: - break; - // 当前用户在其他设备上删除频道。 - case CHANNEL_DELETE: - break; - // 当前用户在其他设备上更新频道。 - case CHANNEL_UPDATE: - break; - // 当前用户在其他设备上加入频道。 - case CHANNEL_JOIN: - break; - // 当前用户在其他设备上接受加入频道的邀请。 - case CHANNEL_INVITATION_ACCEPT: - break; - // 当前用户在其他设备上拒绝加入频道的邀请。 - case CHANNEL_INVITATION_DECLINE: - break; - // 当前用户在其他设备上退出频道。 - case CHANNEL_LEAVE: - break; - // 当前用户在其他设备上从频道中移除成员。 - case CIRCLE_CHANNEL_REMOVE_USER: - break; - // 当前用户在其他设备上邀请用户加入频道。 - case CIRCLE_CHANNEL_INVITE_USER: - break; - // 当前用户在其他设备上禁言频道成员。 - case CIRCLE_CHANNEL_MEMBER_ADD_MUTE: - break; - // 当前用户在其他设备上解除对频道成员的禁言。 - case CIRCLE_CHANNEL_MEMBER_REMOVE_MUTE: - break; - } -} -``` diff --git a/docs/product/circle/channel_mgmt_ios.md b/docs/product/circle/channel_mgmt_ios.md deleted file mode 100644 index e2c9ffa5..00000000 --- a/docs/product/circle/channel_mgmt_ios.md +++ /dev/null @@ -1,397 +0,0 @@ -# 管理频道 - - - -频道(Channel)是一个社区下不同子话题的讨论分区,因此一个社区下可以有多个频道。社区创建时会自动创建默认频道,该频道中添加了所有社区成员,用于承载各种系统通知。从可见性角度看,频道社区分为公开和私密频道;从功能角度看,频道分为文字频道和语聊频道。社区创建者可以根据自己需求创建频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_ios.html#解散社区)和[删除频道](#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 提供 `IEMCircleManager` 类和 `EMCircleManagerChannelDelegate` 类用于频道管理,支持你通过调用 API 在项目中实现如下功能: - -- 创建和管理频道; -- 管理频道成员; -- 监听频道事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -本节介绍如何使用环信即时通讯 IM iOS SDK 提供的 API 实现上述功能。 - -### 创建和管理频道 - -#### 创建频道 - -1. 社区所有者可以调用 `createChannel` 方法在社区中创建公开或私密频道。参与频道创建的初始成员会收到 `EMCircleManagerChannelDelegate#onChannelCreated` 事件。 - -每个社区默认最多可创建 100 个频道。如需调整该阈值,请联系商务。 - -示例代码如下: - -```swift -let attribute = EMCircleChannelAttribute() -attribute.name = self.nameTextField.text ?? "" -attribute.type = self.publicSwitch.isOn ? .public : .private -let mode: EMCircleChannelMode = self.voiceSwitch.isOn ? .voide : .chat -EMClient.shared().circleManager?.createChannel(self.serverId, categoryId: self.categoryId, attribute: attribute, mode: mode, completion: { channel, error in -}) -``` - -创建频道时,需设置社区 ID、频道分组 ID、频道模式以及频道属性 `EMCircleChannelAttribute`,如下表所示。 - -| 参数 | 类型 | 描述 | 是否必需 | -| :--------- | :----------------------- | :------------------ |:------------------ | -| serverId | NSString | 社区 ID。 | 是 | -| categoryId | NSString | 频道分组 ID。 | 否 | -| mode | EMCircleChannelMode | 频道模式:
- `Chat`:文字频道;
- `Voice`:语聊频道。 | 是 | -| EMCircleChannelAttribute.name | NSString | 频道名称,不超过 50 个字符。 | 是 | -| EMCircleChannelAttribute.desc | NSString | 频道描述,不超过 500 个字符。 | 否 | -| EMCircleChannelAttribute.maxUsers | int32_t | 频道最大成员数量:
- 对于语聊频道,该属性的取值范围为 [1,20],默认值为 `8`;
- 对于文字频道,该属性的取值范围为 [1,2000],默认值为 `2000`。 | 否 | -| EMCircleChannelAttribute.type | EMCircleChannelType | 频道类型:
- (默认)`Public`:公开频道;
- `Private`:私密频道。 | 否 | -| EMCircleChannelAttribute.ext | NSString | 频道自定义扩展信息,不超过 500 个字符。 | 否 | -| EMCircleChannelAttribute.rtcChannelId | NSString | RTC 频道 ID。该参数仅在创建语聊频道时需设置。若不设置,服务器使用创建的语聊频道的 ID 作为该参数的值返回。 | 否 | - -2. 邀请用户加入频道。 - -社区中的用户可以自由加入社区下的公开频道,私密频道只能由频道成员邀请用户加入。 - -频道创建者调用 `inviteUserToChannel` 方法邀请用户加入频道。受邀用户收到 `EMCircleManagerChannelDelegate#onReceiveChannelInvitation` 事件。 - -```swift - EMClient.shared().circleManager?.inviteUserToChannel(serverId: serverId, channelId: channelId, userId: userId, welcome: welcome) { error in - } -``` - -3. 受邀用户确认是否加入频道。 - - - 用户调用 `acceptChannelInvitation` 方法同意加入频道,邀请人收到 `EMCircleManagerChannelDelegate#onReceiveChannelInvitation` 事件,频道所有成员(不包括该新加入的成员)收到 `EMCircleManagerChannelDelegate#onMemberJoinedChannel` 事件。示例代码如下: - - ```swift - EMClient.shared().circleManager?.acceptChannelInvitation(serverId, channelId: channelId, inviter: inviter) { channel, error in - } - ``` - -- 用户调用 `declineChannelInvitation` 方法拒绝加入频道,邀请人收到 `EMCircleManagerChannelDelegate#onChannelInvitationBeDeclined` 事件。示例代码如下: - - ```swift - EMClient.shared().circleManager?.declineChannelInvitation(serverId, channelId: channelId, inviter: inviter) { error in - } - ``` - -4. 用户加入频道后,可在频道中发送和接收消息。 - -#### 修改频道信息 - -仅社区所有者和管理员可调用 `updateChannel` 方法修改频道属性 `EMCircleChannelAttribute`,包括频道名称、类型(公开/私有)、描述、最大成员数量和自定义扩展信息。频道所有成员(除操作者外)会收到 `EMCircleManagerChannelDelegate#onChannelUpdated` 事件。频道创建后,频道模式(文字或语聊)不能修改。 - -若更换频道所属的频道分组,需调用 [`transferChannel`](category_mgmt_ios.html#更换指定频道的频道分组)方法。 - -示例代码如下: - -```swift -let channelAttr = EMCircleChannelAttribute() -channelAttr.name = channelName -channelAttr.desc = channelDesc -EMClient.shared().circleManager?.updateChannel(serverId, channelId: channelId, attribute: channelAttr) { channel, error in -} -``` - -#### 解散频道 - -仅社区所有者可以调用 `destroyChannel` 方法解散社区中的频道。频道内其他成员收到 `EMCircleManagerChannelDelegate#onChannelDestroyed` 事件并被移出频道。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.destroyChannel(serverId, channelId: channelId) { error in -} -``` - -#### 获取频道详情 - -社区成员可以调用 `fetchChannelDetail` 方法获取频道的详情。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchChannelDetail(serverId, channelId: channelId) { channel, _ in -} -``` - -#### 获取频道列表 - -##### 获取社区的公开频道列表 - -社区成员可以调用 `fetchPublicChannelsInServer` 方法获取社区下的所有公开频道的列表,示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchPublicChannels(inServer: serverId, limit: 20, cursor: nil) { result, error in -} -``` - -##### 获取社区的私密频道列表 - -社区成员可以调用 `fetchPrivateChannelsInServer` 方法获取社区下所有私密频道的列表。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchPrivateChannels(inServer: serverId, limit: 20, cursor: nil) { result, error in -} -``` - -##### 获取社区中加入的频道 - -社区成员可以调用 `fetchJoinedChannelIds` 方法获取社区下加入的频道列表。 - -```swift -EMClient.shared().circleManager?.fetchJoinedChannelIds(inServer: serverId, limit: 20, cursor: cursor, completion: { result, error in - - }) -``` - -##### 获取频道分组的公开频道列表 - -社区成员可以调用 `fetchPublicChannelsInCategory` 方法获取频道分组下所有公开频道的列表,示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchPublicChannels(inCategory: serverId, categoryId: categoryId, limit: 20, cursor: result?.publicResult?.cursor, completion: { result, error in -} -``` - -##### 获取频道分组下的私密频道列表 - -调用 `fetchPrivateChannelsInCategory` 方法获取频道分组下的所有私密频道的列表,示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchPrivateChannels(inCategory: self.serverId, categoryId: categoryId, limit: 20, cursor: result?.privateResult?.cursor, completion: { result, error in -} -``` - -### 发送消息 - -在频道中发送消息与在群组中发送消息的方式类似,唯一的区别在于接收方需要设置为频道 ID。详见 [发送群聊消息](/document/ios/message_send_receive.html)。 - -### 管理频道成员 - -#### 频道加人 - -用户加入频道分为两种方式:主动申请和频道成员邀请。 - -邀请用户加入频道,详见 [创建频道](#创建频道)。本节对用户申请加入频道进行详细介绍。 - -只有公开频道支持用户申请加入,私有频道不支持。若申请加入公开频道,用户需执行以下步骤: - -1. 用户可获取社区下的[公开频道列表](#获取社区的公开频道列表)。 - -2. 调用 `joinChannel` 方法传入社区 ID 和频道 ID,申请加入对应频道。用户加入频道后,频道所有成员(不包括该新加入的成员)会收到 `EMCircleManagerChannelDelegate#onMemberJoinedChannel` 事件。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.joinChannel(serverId, channelId: channelId) { channel, error in -} -``` - -3. 用户加入频道后可以在频道中发送和接收消息。 - -#### 退出频道 - -##### 频道成员主动退出频道 - -频道所有成员可调用 `leaveChannel` 方法退出频道。频道内的其他成员会收到 `EMCircleManagerChannelDelegate#onMemberLeftChannel` 事件。退出频道的成员不会再收到频道消息。 - -:::tip -社区内的默认频道不允许成员主动退出。 -::: - -示例代码如下: - -```swift -EMClient.shared().circleManager?.leaveChannel(serverId, channelId: channelId) { error in -} -``` - -##### 频道成员被移出频道 - -仅频道所有者和管理员可以调用 `removeUserFromChannel` 方法将指定成员移出频道。被移出的频道的成员会收到 `EMCircleManagerChannelDelegate#onMemberRemovedFromChannel`事件,其他成员会收到 `EMCircleManagerChannelDelegate#onMemberLeftChannel` 事件。被移出频道的成员不会再收到频道消息。 - -:::tip -社区内的默认频道不允许踢出成员。 -::: - -示例代码如下: - -```swift -EMClient.shared().circleManager?.removeUser(fromServer: serverId, userId: userId) { error in -} -``` - -#### 将成员加入频道禁言列表 - -社区所有者和社区管理员可以调用 `muteUserInChannel` 方法将频道成员加入禁言列表。被禁言的频道成员、社区所有者和管理员(除操作者外)会收到 `EMCircleManagerChannelDelegate#onMemberMuteChangeInChannel` 事件。 - -禁言列表中的成员无法在频道中发送消息,但可以接收频道中的消息。 - -```swift -EMClient.shared().circleManager?.muteUserInChannel(userId: userId, serverId: serverId, channelId: channelId, duration: 86400) { error in -} -``` - -#### 将成员移出频道禁言列表 - -社区所有者和社区管理员可以调用 `unmuteUserInChannel` 方法,将频道禁言列表上的频道成员移出频道禁言列表。被移出禁言列表的频道成员、社区所有者和管理员(除操作者外)会收到 `EMCircleManagerChannelDelegate#onMemberMuteChangeInChannel` 事件。频道成员被移出禁言列表后可在频道中正常发送和接收消息。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.unmuteUserInChannel(userId: userId, serverId: serverId, channelId: channelId) { error in -} -``` - -#### 获取频道禁言列表 - -社区所有者和社区管理员可以调用 `fetchChannelMuteUsers` 方法获取频道下的禁言列表。 - -```swift -EMClient.shared().circleManager?.fetchChannelMuteUsers(serverId, channelId: channelId) { map, error in -} -``` - -#### 获取指定频道的成员列表 - -频道中的成员可以获取该频道下的成员列表: - -- 创建语聊房频道时,创建者不加入频道。因此,频道创建者不算入频道成员数量,查询频道成员列表时不返回频道创建者。 - -- 对于其他模式的频道创建时,创建者直接加入频道。因此,频道创建者算入频道成员数量,查询频道成员列表返回频道创建者。 - -```swift -EMClient.shared().circleManager?.fetchChannelMembers(serverId, channelId: channelId, limit: 20, cursor: cursor) { result, error in -} -``` - -#### 查询当前用户是否在频道中 - -社区成员可调用 `checkSelfIsInChannel` 方法查询自己是否在指定频道中。示例代码如下: - -```swift -EMClient.shared().circleManager?.checkSelfIsInChannel(serverId: serverId, channelId: channelId) { isJoined, error in -} -``` - -### 监听频道事件 - -#### 单设备登录监听事件 - -`IEMCircleManager` 中提供频道事件的监听接口。开发者可以通过设置此监听,获取频道中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。 - -```swift -//添加频道回调代理。 -EMClient.shared().circleManager?.add(channelDelegate: self, queue: nil) -//移除频道回调代理。 -EMClient.shared().circleManager?.remove(channelDelegate: self) -``` - -```swift -//创建频道。参与创建的初始成员会收到该事件。 -func onChannelCreated(_ channel: EMCircleChannel, creator: String) { - -} -//修改频道信息。频道所有成员(除操作者外)会收到该事件。 -func onChannelUpdated(_ channel: EMCircleChannel, initiator: String) { - -} -//解散频道。频道的所有成员(除操作者)会收到该事件。 -func onChannelDestroyed(_ serverId: String, categoryId: String, channelId: String, initiator: String) { - -} -//用户收到频道加入邀请。受邀用户会收到该事件。 -func onReceiveChannelInvitation(_ invite: EMCircleChannelExt, inviter: String) { - -} -//用户同意频道加入邀请。邀请人会收到该事件。 -func onChannelInvitationBeAccepted(_ serverId: String, categoryId: String, channelId: String, invitee: String) { - -} -//用户拒绝频道加入邀请。邀请人会收到该事件。 -func onChannelInvitationBeDeclined(_ serverId: String, categoryId: String, channelId: String, invitee: String) { - -} -//有用户加入频道。频道的所有成员(不包括该新加入的成员)会收到该事件。 -func onMemberJoinedChannel(_ serverId: String, categoryId: String, channelId: String, member: EMCircleUser) { - -} -//有成员主动退出频道。频道内的其他成员会收到该事件。 -func onMemberLeftChannel(_ serverId: String, categoryId: String, channelId: String, member: String) { - -} -//有成员被移出频道。被移出的成员会收到该事件。 -func onMemberRemoved(fromChannel serverId: String, categoryId: String, channelId: String, member: String, initiator: String) { - -} -//有成员的禁言状态发生变化。禁言状态变更的成员、社区所有者和管理员(除操作者外)会收到该事件。 -func onMemberMuteChange(inChannel serverId: String, categoryId: String, channelId: String, muted isMuted: Bool, members: [String]) { - -} -``` - -#### 多设备登录监听事件 - -```swift -(void)multiDevicesCircleChannelEventDidReceive:(EMMultiDevicesEvent)aEvent - channelId:(NSString * _Nonnull)channelId - ext:(id _Nullable)aExt -{ - switch (aEvent) { - // 当前用户在其他设备创建了频道。 - case EMMultiDevicesEventCircleChannelCreate: - break; - // 当前用户在其他设备销毁了频道。 - case EMMultiDevicesEventCircleChannelDestroy: - break; - // 当前用户在其他设备更新了频道。 - case EMMultiDevicesEventCircleChannelUpdate: - break; - // 当前用户在其他设备加入了频道。 - case EMMultiDevicesEventCircleChannelJoin: - break; - // 当前用户在其他设备同意了频道邀请。 - case EMMultiDevicesEventCircleChannelInviteBeAccepted: - break; - // 当前用户在其他设备拒绝了频道邀请。 - case EMMultiDevicesEventCircleChannelInviteBeDeclined: - break; - // 当前用户在其他设备退出了频道。 - case EMMultiDevicesEventCircleChannelExit: - break; - // 当前用户在其他设备将用户从频道中踢出。 - case EMMultiDevicesEventCircleChannelRemoveUser: - break; - // 当前用户在其他设备邀请用户加入频道。 - case EMMultiDevicesEventCircleChannelInviteUser: - break; - // 当前用户在其他设备将频道中的用户禁言。 - case EMMultiDevicesEventCircleChannelAddMute: - break; - // 当前用户在其他设备解除频道中的用户禁言。 - case EMMultiDevicesEventCircleChannelRemoveMute: - break; - default: - break; - } -} -``` diff --git a/docs/product/circle/channel_mgmt_rest.md b/docs/product/circle/channel_mgmt_rest.md deleted file mode 100644 index e73c535f..00000000 --- a/docs/product/circle/channel_mgmt_rest.md +++ /dev/null @@ -1,2171 +0,0 @@ -# 管理频道以及频道成员 - - - -频道(Channel)是一个社区下不同子话题的讨论分区,因此一个社区下可以有多个频道。社区创建时会自动创建默认频道,该频道中添加了所有社区成员,用于承载各种系统通知。从可见性角度看,频道社区分为公开和私密频道;从功能角度看,频道分为文字频道和语聊频道。用户可以根据自己需求创建频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台、调用 RESTful API 或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](#查询指定频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](https://docs-im.easemob.com/ccim/circle/rest/serverapi#删除社区)和[删除频道](https://docs-im.easemob.com/ccim/circle/rest/channelapi#删除频道)等 API。** - -## 前提条件 - -要调用环信即时通讯 RESTful API,请确保满足以下要求: - -- 已在环信即时通讯控制台 [开通配置环信即时通讯 IM 服务](http://doc.easemob.com/document/server-side/enable_and_configure_IM.html)。 -- 了解环信 IM RESTful API 的调用频率限制,详见 [接口频率限制](http://doc.easemob.com/product/limitationapi.html)。 - -## 公共参数 - -### 请求参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :----------------------------------------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见[获取环信即时通讯 IM 的信息](http://doc.easemob.com/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见[获取环信即时通讯 IM 的信息](http://doc.easemob.com/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见[获取环信即时通讯 IM 的信息](http://doc.easemob.com/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `server_id` | String | 是 | 社区 ID。 | -| `channel_id` | String | 是 | 频道 ID。 | -| `user_id` | String | 是 | 用户 ID。 | -| `role` | Int | 是 | 频道成员的角色:
- `0`:频道所有者;
- `1`:频道的普通成员。 | - -:::tip -对于分页获取数据列表,若查询参数中的 `limit` 和 `cursor` 均未设置,则服务器返回首页的数据列表。 -::: - -### 响应参数 - -| 参数 | 类型 | 描述 | -| :-------| :----- | :------------------------------------ | -| `owner` | String | 频道所有者。 | -| `name` | String | 频道名称。 | -| `type` | Int | 频道类型:
- `0`:公开频道;
- `1`:私密频道。 | -| `mode` | Int | 频道模式:
- `0`:文字频道;
- `1`:语聊频道。 | -| `description` | String | 频道描述。| -| `custom` | String | 频道的扩展信息。 | -| `max_users` | Long | 频道最大成员数量。 | -| `rtc_name` | String | RTC 频道名称。该名称在加入 RTC 频道时使用。若使用声网 RTC,该名称还用于[生成 RTC Token](https://docportal.shengwang.cn/cn/voice-call-4.x/token_server_android_ng?platform=Android)。
该参数仅在创建语聊频道时返回,若创建语聊房频道时未指定 `rtc_name`,服务器将使用频道 ID 作为该参数的值返回。 | -| `current_users_count` | Int | 当前在频道中的成员数,仅在获取语聊房频道详情时返回。 | -| `default_channel` | Int | 是否为社区的默认频道:
- `0`:否;
- `1`:是。 | -| `user_id` | String | 环信用户 ID。 | -| `role` | Int | 频道成员的角色:
- `0`:频道所有者;
- `1`:频道的普通成员。 | -| `created` | Long | 频道的创建时间,Unix 时间戳,单位为毫秒。 | -| `server_id` | String | 社区 ID。 | -| `channel_category_id` | String | 频道分组 ID。 | -| `channel_id` | String | 频道 ID。 | - -## 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段: - -Authorization:`Bearer ${YourAppToken}` - -为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 推荐使用 app token 的鉴权方式,详见 [使用环信 App Token 鉴权](/document/server-side/easemob_app_token.html)。 - -## 创建和管理频道 - -### 创建频道 - -每个社区最多可以创建 100 个频道。一个频道只能加入一个频道分组。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/channel -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。 | -| `channel_category_id` | String | 否 | 频道分组 ID。如果指定频道分组 ID,创建的频道将添加到该分组下;若不指定,则频道添加至社区默认频道分组中。 | -| `name` | String | 是 | 频道名称,长度不能超过 50 个字符。 | -| `type` | Int | 否 | 频道类型:
- (默认)`0`:公开频道;
- `1`:私密频道。 | -| `mode` | Int | 否 | 频道模式:
- (默认)`0`:文字频道;
- `1`:语聊频道。 | -| `max_users` | Long | 否 | 频道最大成员数量。
- 对于语聊频道(即 `mode` 为 `1`),该参数的取值范围为 [1,20],默认值为 `8`。
- 对于文字频道,该参数的取值范围为 [1,2000],默认值为 `2000`。如需要提高上限请联系商务。 | -| `description` | String | 否 | 频道描述,长度不能超过 500 个字符。 | -| `custom` | String | 否 | 频道扩展信息,例如可以给社区添加业务相关的标记,长度不能超过 500 个字符。 | -| `rtc_name` | String | 否 | RTC 频道名称,长度不能超过 50 个字符。该名称在加入 RTC 频道时使用,仅在创建语聊频道时返回。若使用声网 RTC,该名称还用于[生成 RTC Token](https://docportal.shengwang.cn/cn/voice-call-4.x/token_server_android_ng?platform=Android)。
若创建语聊频道时未指定 `rtc_name`,服务器将使用频道 ID 作为该参数的值返回。| - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--------- | :----- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channel` | JSON | 频道详情。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -创建 IM 频道: - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel' --d '{ - "server_id" : "19VM9oPBasxxxxxx0tvWViEsdM", - "name" : "chat channel", - "type" : 0, - "mode":0, - "max_users" : 200, - "description" : "chat Channel", - "custom" : "custom" -}' -``` - -创建语聊房频道: - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel' --d '{ - "server_id" : "19KM9oPBasxxxxxx0tvWViVhgk", - "name" : "voice chatroom channel", - "type" : 0, - "mode":1, - "max_users" : 10, - "description" : "voice chatroom Channel", - "custom" : "custom", - "rtc_name" : "150986" -}' -``` - -##### 响应示例 - -创建 IM 频道的响应: - -```json -{ - "code": 200, - "channel": { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - }, - "channel_id": "2059xxxxxx1542" -} -``` - -创建语聊房频道的响应: - -```json -{ - "code": 200, - "channel": { - "owner": "user1", - "name": "voice chatroom Channel", - "type": 0, - "mode": 1, - "description": "voice chatroom Channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1590", - "max_users": 10, - "rtc_name" : "150986", - "default_channel": 0 - }, - "channel_id": "2059xxxxxx1590" -} -``` - -### 修改频道信息 - -修改指定频道的信息。 - -#### HTTP 请求 - -```http -PUT https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}?serverId={server_id} -``` - -##### 路径参数 - -参数及描述详见 [公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :----- | :----- | :------- | :-------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| ------------- | ------ | -------- | ------------------------------------------------------------ | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| ----------- | ------ | -------- | ------------------------------------------------------------ | -| `name` | String | 否 | 频道名称,长度不能超过 50 个字符。 | -| `type` | Int | 否 | 频道类型:
- `0`:公开频道;
- `1`:私密频道。 | -| `max_users` | Long | 否 | 频道最大成员数量。
- 对于语聊房频道,该参数的取值范围为 [1,20]。
- 对于其他模式的频道,该参数的取值范围为 [1,2000],如需要提高上限请联系商务。 | -| `description` | String | 否 | 频道描述,长度不能超过 500 个字符。 | -| `custom` | String | 否 | 频道的扩展信息,例如可以给社区添加业务相关的标记,长度不能超过 500 个字符。 | -| `rtc_name` | String | 否 | 目前该名称用于使用声网 RTC 时,生成 Token 以及端上加入声网 RTC 频道时使用,长度不能超过 50 个字符。该字段目前仅在修改语聊房频道时才有效。若创建语聊房频道时未指定 `rtc_name`,服务器将使用频道 ID 作为 `rtc_name` 的值返回。| - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channel` | Json | 频道详情。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX' -d '{ - "name" : "chat channel", - "max_users" : 200, - "description" : "chat Channel", - "custom" : "custom" -}' -``` - -#### 响应示例 - -```json -{ - "code": 200, - "channel": { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } -} -``` - -### 查询指定频道详情 - -查询指定的频道详情。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}?serverId={server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channel` | JSON | 频道详情。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX?serverId=XXX' -``` - -##### 响应示例 - -查询 IM 频道的响应: - -```json -{ - "code": 200, - "channel": { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } -} -``` - -查询语聊房频道的响应: - -```json -{ - "code": 200, - "channel": { - "owner": "user1", - "name": "voice chatroom channel", - "type": 0, - "mode": 1, - "description": "voice chatroom channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "rtc_name" : "150986", - "max_users": 10, - "current_users_count" : 2, - "default_channel": 0 - } -} -``` - -### 获取单个社区下的所有公开频道 - -分页获取单个社区下的所有公开频道。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/public?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `limit` | Int | 否 | 每页获取的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :------------------------ | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--------- | :----- | :----------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的频道数量。 | -| `channels` | List | 获取到的频道详情列表。 | -| `cursor` | String | 游标,指定下次查询的起始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/public?serverId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 获取用户在社区创建的频道列表 - -查询用户在社区创建的频道列表。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/user/{user_id}/created/channels?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :---------- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `limit` | Int | 否 | 每页获取的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定数据查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--------- | :----- | :----------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的频道数量。 | -| `channels` | List | 获取到的频道详情列表。 | -| `cursor` | String | 游标,指定下次查询的开始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/user/XXX/created/channels?serverId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 获取单个用户已加入的频道列表 - -分页获取单个用户已加入的频道列表,包括公开和私密频道。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/user/joined/list?userId={user_id}&serverId={server_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `user_Id` | String | 是 | 用户 ID。 | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `limit` | Int | 否 | 每页获取的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定数据查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------- | :--- | :-------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channels` | List | 获取到的频道详情列表。 | -| `count` | Int | 获取到的频道数量。 | -| `cursor` | String | 游标,指定下次查询的开始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/user/joined/list?userId=XXX&serverId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 获取单个社区下的所有私密频道 - -分页获取单个社区下的所有私密频道。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/private?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `limit` | Int | 否 | 每页获取的私密频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------- | :--- | :------------------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的频道数量。 | -| `channels` | List | 获取到的私密频道详情列表。 | -| `cursor` | String | 游标,指定下次查询的开始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/private?serverId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "channels": [ - { - "owner": "user1", - "name": "private chat channel", - "type": 1, - "mode": 0, - "description": "private chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2065xxxxxx1590", - "max_users": 100, - "default_channel": 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 删除频道 - -删除指定的频道。 - -#### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}?serverId={server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :------------ | :----- | :------- | :------------------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :------------------ | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX?serverId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -## 发送消息 - -通过 RESTful API 在频道中发送消息与在群组中发送消息的方式类似,唯一的区别在于请求体中的 `to` 参数需要设置为频道 ID,并且发送的消息不会写入会话列表。详见 [发送群聊消息](/document/server-side/message_group.html)。 - -## 管理消息 Reaction - -### 添加消息 Reaction - -添加消息 Reaction。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/reaction/user/{user_id} -``` - -##### 路径参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :--------------------------------- | -| `user_id` | String | 是 | 用户 ID。 | - -其他参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :--------------------------------- | -| `message_id` | String | 是 | 消息 ID。 | -| `message` | String | 是 | 表情 ID,与客户端一致。长度不可超过 128 个字符。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---------- | :----- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `reaction_id` | String | Reaction ID。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/reaction/user/{user_id}' --d '{ - "message_id" : "131345390", - "message" : "message123456" -}' -``` - -##### 响应示例 - -```json -{ - "code" : 200, - "reaction_id" : "15890012560" -} -``` - -### 获取指定消息的 Reaction - -获取指定消息的 Reaction。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/reaction/user/{user_id}?msgIdList={message_id}&channelId={channel_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :------------------------------ | -| `msgIdList` | String | 是 | Reaction 所属消息的 ID。 | -| `channelId` | String | 是 | 消息所属频道的 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | Reaction 数量。 | -| `reactions.msgId` | String | Reaction 所属消息的 ID。 | -| `reactionList` | List | Reaction 列表及其详细信息。 | -| `reactionList.reactionId` | String | Reaction ID。 | -| `reactionList.message` | String | Reaction 名称。 | -| `reactionList.state` | Bool | 发送该请求的用户是否向消息添加了 Reaction:
- `true`:是;
- `false`:否。 | -| `reactionList.count` | Int | 向消息添加了该 Reaction 的用户数量。| -| `reactionList.userList` | List | 添加了该 Reaction 的用户 ID 列表。| - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/reaction/user/XXX?msgIdList=XXX&channelId=XXX' -``` - -##### 响应示例 - -```json -{ - "code":200, - "count" : 1, - "reactions":[ - { - "msgId":"131345390", - "reactionList":[ - { - "reactionId":"944330310986837168", - "message":"message123456", - "count":2, - "state":"该用户是否追加了此 reaction", - "userList":[ - "user1", - "user2" - ] - } - ] - } - ] -} -``` - -### 删除指定消息的 Reaction - -删除指定消息的 Reaction。 - -#### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/circle/reaction/user/{user_id}?messageId={message_id}&message={message} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :------------------------------ | -| `message_id` | String | 是 | Reaction 所属消息的 ID。 | -| `message` | String | 是 | 要移除的表情的 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/reaction/user/XXX?messageId=XXX&message=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200 -} -``` - -## 管理频道成员 - -### 将用户加入频道 - -将用户加入频道。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/join?userId={user_id}&serverId={server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `user_id` | String | 是 | 用户 ID。 | -| `server_id` | String | 是 | 社区 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `channel` | JSON | 频道详情。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/join?userId=XXX&serverId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "channel": { - "owner": "user1", - "name": "chat channel", - "type": 0, - "mode": 0, - "description": "chat channel", - "custom": "custom", - "created": 1675845650856, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM", - "channel_category_id": "77a9860xxxxxx2b54881025861c", - "channel_id": "2059xxxxxx1542", - "max_users": 200, - "default_channel": 0 - } -} -``` - -### 将成员移出频道 - -将指定成员移出频道。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/user/remove?userId={user_id}&serverId={server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :--------------------------- | -| `user_id` | String | 是 | 用户 ID。 | -| `server_id` | String | 是 | 社区 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/user/remove?userId=XXX&serverId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -### 批量移除频道成员 - -一次移除多名频道成员。如果所有被移除用户均不是频道成员,则移除失败,并返回错误。移除后,这些成员也会被移除其在该频道中加入的子区。 - -单个请求最多可移除 20 个频道成员。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/users/remove -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :---------- | :----- | :------- | :--------------------------------------------- | -| `server_id` | String | 是 | 社区 ID。 | -| `usernames` | List | 是 | 被移除频道成员的用户 ID 列表,不能超过 20 个。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :--- | :----------------------------------------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `data` | List | 批量移除频道成员的信息,包含被移除的频道成员的用户 ID 和移除结果。 | -| `data.user` | String | 被移除的频道成员的用户 ID。 | -| `data.result` | Bool | 频道成员是否被成功移除:
- `true`:移除成功;
- `false`:移除失败。失败的原因可能是用户不在频道所属的社区中、用户不在频道中、用户为频道所有者等。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -// 将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/users/remove' --d '{ - "server_id" : "19VM9oPBasxxxxxx0tvWViEsdM", - "usernames" : [ - "u1", - "u3", - "u5" - ] -}' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "data": [ - { - "user": "u1", - "result": true - }, - { - "user": "u5", - "result": true - }, - { - "user": "u3", - "result": true - } - ] -} -``` - -### 查询用户是否在频道 - -查询用户是否在频道中。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/user/{user_id}?serverId={server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :------ | :----------------------------------------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `result` | Boolean | 查询结果:
- `true`:用户在频道中;
- `false`:用户不在频道中。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/user/XXX?serverId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "result": true -} -``` - -### 查询频道中指定成员的社区角色 - -查询频道中指定成员的社区角色。社区角色包社区所有者、管理员和普通成员。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/user/role?serverId={server_id}&userId={user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :---------- | :----- | :------- | :---------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `user_id` | Int | 是 | 需要查询角色的用户 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :--- | :------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `role` | Int | 用户在社区中的角色:
- `0`: 所有者;
- `1`:管理员;
- `2`:普通成员。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -// 将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/user/role?serverId=XXX&userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "role": 2 -} -``` - -### 获取频道的成员列表 - -获取指定频道的成员列表: - -- 创建语聊频道时,创建者不加入频道。因此,频道创建者不算入频道成员数量,查询频道成员列表时不返回频道创建者。 - -- 创建文字频道时,创建者直接加入频道。因此,频道创建者算入频道成员数量,查询频道成员列表返回频道创建者。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/users?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `limit` | Int | 否 | 每页获取的成员数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---- | :--- | :----------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的成员数量。 | -| `users` | List | 获取到的成员详情列表。 | -| `users.user_id` | String | 用户 ID | -| `users.role` | Int | 用户在社区中的角色:
- `0`: 所有者;
- `1`:管理员;
- `2`:普通成员。| -| `cursor` | String | 游标,指定下次数据查询的起始位置。| - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/users?serverId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "users": [ - { - "user_id" : "user1", - "role" : 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 获取频道的禁言列表 - -获取频道的禁言列表。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/user/mute/list?serverId={server_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | - -其他参数及描述,详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :---------- | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `limit` | Int | 否 | 每页获取频道内被禁言的用户数量。取值范围为 [1,20],默认值为 20。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 查询游标,指定下次查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :----- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `mute_users` | List | 被禁言用户的详情列表。| -| `mute_users.expire` | Long | 禁言的到期时间,Unix 时间戳,单位为毫秒。 | -| `mute_users.user` | String | 被禁言的成员的用户 ID。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/user/mute/list?serverId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200, - "count" : 2, - "mute_users" : [ - { - "expire" : 86400000, - "user" : "u1" - }, - { - "expire" : 86400000, - "user" : "u2" - } - ] -} -``` - -### 将成员加入频道禁言列表 - -将成员加入频道禁言列表。成员被禁言后,将无法在频道中发送消息。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/user/mute -``` - -##### 路径参数 - -其它参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 备注 | -| :-------- | :----- | :------- | :------------------------- | -| `server_id` | String | 是 | 社区 ID。 | -| `user_id` | String | 是 | 被禁言的成员的用户 ID。 | -| `duration` | Long | 是 | 禁言时长,单位为毫秒。若不传该参数为永久禁言。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/user/mute' -d '{ - "server_id" : "19UyPIsiwxxxxxxxgLrfI9Z", - "user_id" : "u1", - "duration" : 86400 -}' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -### 将成员移出频道禁言列表 - -将成员移出频道禁言列表。成员被解除禁言后,可以在频道中发送消息。 - -#### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/circle/channel/{channel_id}/user/mute?serverId={server_id}&userId={user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `server_id` | String | 是 | 频道所属社区的 ID。 | -| `user_id` | String | 是 | 要禁言的用户 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/channel/XXX/user/mute?serverId=XXX&userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -## 管理子区 - -### 创建子区 - -创建子区。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/thread -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 备注 | -| :--------- | :----- | :------- | :------------ | -| `channel_id` | String | 是 | 频道 ID。 | -| `user_id` | String | 是 | 用户 ID。 | -| `name` | String | 是 | 子区名称。 | -| `message_id` | String | 是 | 消息 ID。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------- | :----- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `thread_id` | String | 子区 ID。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread' -d '{ - "channel_id" : "156900086", - "user_id" : "user1", - "message_id" : 0, - "name" : "thread-name" -}' -``` - -##### 响应示例 - -```json -{ - "code" : 200, - "thread_id" : "15890012560" -} -``` - -### 修改子区信息 - -修改指定子区的信息。 - -#### HTTP 请求 - -```http -PUT https://{host}/{org_name}/{app_name}/circle/thread/{thread_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 备注 | -| :--- | :----- | :------- | :------------ | -| `name` | String | 是 | 子区名称。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/XXX' -d '{ - "name" :"thread-name" -}' -``` - -##### 响应示例 - -```json -{ - "code" : 200 -} -``` - -### 查询子区的详情 - -查询指定子区的详情。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/thread/{thread_id} -``` - -##### 路径参数 - -其它参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `id` | String | 子区 ID。 | -| `msgId` | String | 子区的父消息 ID。 | -| `channelId` | String | 子区所属频道的 ID。| -| `owner` | String | 子区创建者的用户 ID。 | -| `created` | Long | 子区创建时间,Unix 时间戳,单位为毫秒。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](https://docs-im.easemob.com/ccim/rest/errorcode)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "id" : "1895600", - "msgId" : "198008034121000", - "channelId" : "156009089", - "owner" : "user1", - "created" : 1650856033420 -} -``` - -### 删除子区 - -删除指定的子区。 - -#### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/circle/thread/{thread_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| code | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -### 加入子区 - -加入指定的子区。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/thread/{thread_id}/user/join?userId={user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/XXX/user/join?userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200 -} -``` - -### 将成员移出子区 - -将成员移出指定的子区。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/thread/{thread_id}/user/remove?userId={user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `user_id` | String | 是 | 要移出子区的用户 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](https://docs-im.easemob.com/ccim/rest/errorcode)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/XXX/user/remove?userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200 -} -``` - -### 用户获取自己创建的子区 - -用户获取自己创建的子区。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/thread/created?userId={user_id}&channelId={channel_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `user_id` | String | 是 | 用户 ID。 | -| `channel_id` | String | 是 | 子区所属频道的 ID。 | -| `limit` | Int | 否 | 每页获取的频道数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `threads` | List | 获取到的子区详情列表。 | -| `count` | Int | 获取到的子区数量。 | -| `threads.id` | String | 子区 ID。 | -| `threads.msgId` | String | 子区的父消息 ID。 | -| `threads.channelId` | String | 子区所属频道的 ID。 | -| `threads.owner` | String | 子区创建者的用户 ID。 | -| `threads.created` | Long | 子区创建时间,Unix 时间戳,单位为毫秒。 | -| `cursor` | String | 游标,指定下次查询的开始位置。| - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](https://docs-im.easemob.com/ccim/rest/errorcode)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/created?userId=XXX&channelId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200, - "threads" : [ - { - "id" : "1895600", - "msgId" : "198008034121000", - "channelId" : "156009089", - "owner" : "user1", - "created" : 1650856033420 - } - ], - "cursor" : "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06ZGlzY29yZDo2MjI0MjEwMiM5MDoy" -} -``` - -### 用户获取频道中的子区 - -分页获取频道中的子区。 - -#### HTTP 请求 - -```shell -curl -X GET https://{host}/{org_name}/{app_name}/circle/thread/list?channelId={channel_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `channel_id` | String | 是 | 子区所属频道的 ID。 | -| `limit` | Int | 否 | 每页获取的子区数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `threads` | List | 获取到的子区详情列表。 | -| `threads.id` | String | 子区 ID。 | -| `threads.msgId` | String | 子区的父消息 ID。 | -| `threads.channelId` | String | 子区所属频道的 ID。 | -| `threads.owner` | String | 子区创建者的用户 ID。 | -| `threads.created` | Long | 子区创建时间,Unix 时间戳,单位为毫秒。 | -| `cursor` | String | 游标,指定下次查询的开始位置。| - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/list?channelId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200, - "threads" : [ - { - "id" : "1895600", - "msgId" : "198008034121000", - "channelId" : "156009089", - "owner" : "user1", - "created" : 1650856033420 - } - ], - "cursor" : "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06ZGlzY29yZDo2MjI0MjEwMiM5MDoy" -} -``` - -### 用户获取频道中加入的子区 - -用户获取频道中加入的子区。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/thread/joined?userId={user_id}&channelId={channel_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否所需 | 描述 | -| :---- | :------- | :------------------| :----------------------- | -| `user_id` | String | 是 | 用户 ID。 | -| `channel_id` | String | 是 | 子区所属频道的 ID。 | -| `limit` | Int | 否 | 每页获取的子区数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `threads` | List | 获取到的子区详情列表。 | -| `threads.id` | String | 子区 ID。 | -| `threads.msgId` | String | 子区的父消息 ID。 | -| `threads.channelId` | String | 子区所属频道的 ID。 | -| `threads.owner` | String | 子区创建者的用户 ID。 | -| `threads.created` | Long | 子区创建时间,Unix 时间戳,单位为毫秒。 | -| `cursor` | String | 游标,指定下次查询的开始位置。| - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/thread/joined?userId={user_id}&channelId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code" : 200, - "threads" : [ - { - "id" : "1895600", - "msgId" : "198008034121000", - "channelId" : "156009089", - "owner" : "user1", - "created" : 1650856033420 - } - ], - "cursor" : "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aW06ZGlzY29yZDo2MjI0MjEwMiM5MDoy" -} -``` \ No newline at end of file diff --git a/docs/product/circle/channel_mgmt_web.md b/docs/product/circle/channel_mgmt_web.md deleted file mode 100644 index 4bcee085..00000000 --- a/docs/product/circle/channel_mgmt_web.md +++ /dev/null @@ -1,460 +0,0 @@ -# 管理频道 - - - -频道(Channel)是一个社区下不同子话题的讨论分区,因此一个社区下可以有多个频道。社区创建时会自动创建默认频道,该频道中添加了所有社区成员,用于承载各种系统通知。从可见性角度看,频道社区分为公开和私密频道;从功能角度看,频道分为文字频道和语聊频道。社区创建者可以根据自己需求创建频道。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_web.html#解散社区)和[删除频道](#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 支持你通过调用 API 实现如下功能: - -- 创建和管理频道; -- 管理频道成员; -- 监听频道事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成环信即时通讯 Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -本节介绍如何使用环信即时通讯 IM Web SDK 提供的 API 实现上述功能。 - -### 创建和管理频道 - -#### 创建频道 - -1. 社区所有者可以调用 `createChannel` 方法在社区中创建公开或私密频道。 - -每个社区默认最多可创建 100 个频道。如需调整该阈值,请联系商务。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverID', - isPublic: true, - name: 'channelName', - description: 'this is my channel', - ext: 'ext', - maxusers: 8, - mode: 0, - categoryId: 'categoryId', - rtcChannelId: 'rtcChannelId', -} - -WebIM.conn.createChannel(options).then((res) => { - console.log(res) -}) -``` - -创建频道时,需设置以下参数,如下表所示。 - -| 参数 | 类型 | 描述 | 是否必需 | -| :--------- | :----------------------- | :------------------ |:------------------ | -| serverId | String | 社区 ID。 | 是 | -| categoryId | String | 频道分组 ID。 | 否 | -| mode | Number | 频道模式:
- `0`:文字频道;
- `1`:语聊频道。 | 否 | -| name | String | 频道名称,不超过 50 个字符。 | 是 | -| isPublic | Boolean | 频道类型:
- (默认)`true`:公开频道;
- `false`:私密频道。 | 否 | -| description | String | 频道描述,不超过 500 个字符。 | 否 | -| maxusers | Number | 频道最大成员数量:
- 对于语聊频道,该属性的取值范围为 [1,20],默认值为 `8`;
- 对于文字频道,该属性的取值范围为 [1,2000],默认值为 `2000`。 | 否 | -| ext | String | 频道的扩展字段,不超过 500 个字符。 | 否 | -| rtcChannelId | String | RTC 频道 ID。该参数仅在创建语聊频道时需设置。若不设置,服务器使用创建的语聊频道的 ID 作为该参数的值返回。 | 否 | - -2. 邀请用户加入频道。 - -社区中的用户可以自由加入社区下的公开频道,私密频道只能由频道中的成员邀请用户加入。 - -频道创建者调用 `inviteUserToChannel` 方法邀请用户加入频道。受邀用户会收到 `onChannelEvent` 回调,事件为 `inviteToJoin`。 - -- 调用 `inviteUserToChannel` 方法邀请用户加入频道,示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', - userId: 'userId', -} - -WebIM.conn.inviteUserToChannel(options).then(() => { - console.log('发送邀请成功') -}) -``` - -3. 受邀用户确认是否加入频道。 - -用户监听 `onChannelEvent` 回调,事件为 `inviteToJoin`,收到频道加入邀请,确认是否接受邀请。 - - - 用户调用 `acceptChannelInvite` 方法同意加入频道。邀请人会收到 `onChannelEvent` 回调,事件为 `acceptInvite`,频道所有成员(不包括该新加入的成员)收到 `onChannelEvent` 回调,事件为`memberPresence`。示例代码如下: - - ```javascript - let options = { - serverId: 'serverId', - channelId: 'channelId', - inviter: 'inviterUserId', - } - - WebIM.conn.acceptChannelInvite(options) - ``` - - - 用户调用 `rejectChannelInvite` 方法拒绝加入频道。邀请人会收到 `onChannelEvent` 回调,事件为 `rejectInvite`。示例代码如下: - - ```javascript - let options = { - serverId: 'serverId', - channelId: 'channelId', - inviter: 'inviterUserId', - } - - WebIM.conn.rejectChannelInvite(options) - ``` - -4. 用户加入频道后,可在频道中发送和接收消息。 - -#### 修改频道信息 - -仅社区所有者和管理员可调用 `updateChannel` 方法修改频道属性,包括频道名称、类型(公开/私有)、描述、最大成员数量和自定义扩展信息。频道所有成员(除操作者外)会收到 `onChannelEvent` 回调,事件为 `update`。频道创建后,频道模式(文字或语聊)不能修改。 - -若更换频道所属的频道分组,需调用 [`transferChannel`](#更换指定频道的频道分组)方法。 - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId' - name: 'the new channel name', - description: 'the new channel description', -} - -WebIM.conn.updateChannel(options).then((res) => { - console.log(res) -}) - -``` - -#### 解散频道 - -仅社区所有者可以调用 `destroyChannel` 方法解散社区中的频道。频道内其他成员收到 `onChannelEvent` 回调,事件为 `destroy` 并被移出频道。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', -} - -WebIM.conn.destroyChannel(options).then(() => { - console.log('删除频道成功') -}) -``` - -#### 获取频道详情 - -社区成员可以调用 `getChannelDetail` 方法获取频道的详情。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', -} - -WebIM.conn.getChannelDetail(options).then((res) => { - console.log(res) -}) -``` - -#### 获取频道列表 - -##### 获取社区的公开频道列表 - -社区成员可以调用 `getPublicChannels` 方法获取社区下的所有公开频道的列表,示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - pageSize: 20, - cursor: '', -} - -WebIM.conn.getPublicChannels(options).then((res) => { - console.log(res) -}) -``` - -##### 获取社区的私密频道列表 - -社区成员可以调用 `getPrivateChannels` 方法获取社区下所有私密频道的列表,示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - pageSize: 20, - cursor: '', -} - -WebIM.conn.getPrivateChannels(options).then((res) => { - console.log(res) -}) -``` - -##### 获取频道分组的公开频道列表 - -社区成员可以调用 `getCategoryPublicChannels` 方法获取频道分组下的所有公开频道列表,示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - categoryId: 'categoryId', - pageSize: 20, - cursor: '', -} - -WebIM.conn.getCategoryPublicChannels(options).then((res) => { - console.log(res) -}) -``` - -##### 获取频道分组的私密频道列表 - -社区成员可以调用 `getCategoryPrivateChannels` 方法获取频道分组下的所有私密频道列表,示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - categoryId: 'categoryId', - pageSize: 20, - cursor: '', -} - -WebIM.conn.getCategoryPrivateChannels(options).then((res) => { - console.log(res) -}) -``` - -### 发送消息 - -在频道中发送消息与在群组中发送消息的方式类似,唯一的区别在于接收方需要设置为频道 ID。详见 [发送群聊消息](/document/web/message_send_receive.html)。 - -### 管理频道成员 - -#### 频道加人 - -用户加入频道分为两种方式:主动申请和频道成员邀请。 - -邀请用户加入频道,详见 [创建频道](#创建频道)。本节对用户申请加入频道进行详细介绍。 - -只有公开频道支持用户申请加入,私密频道不支持。若申请加入公开频道,用户需执行以下步骤: - -1. 用户可获取[获取社区下的所有公开频道列表](#获取社区的公开频道列表)。 - -2. 调用 `joinChannel` 方法传入社区 ID 和频道 ID,申请加入对应频道。用户加入频道后,频道所有成员(不包括该新加入的成员)会收到 `onChannelEvent` 回调,事件为 `memberPresence`。示例代码如下: - - ```javascript - let options = { - serverId: 'serverId', - channelId: 'channelId' - } - - WebIM.conn.joinChannel(options).then((res) => { - console.log(res) - }) - ``` - -3. 用户加入频道后可以在频道中发送和接收消息。 - -#### 退出频道 - -##### 频道成员主动退出频道 - -频道所有成员可调用 `leaveChannel` 方法退出频道。频道内的其他成员会收到 `onChannelEvent` 回调,事件为 `memberAbsence`。退出频道的成员不会再收到频道消息。 - -:::tip -社区内的默认频道不允许成员主动退出。 -::: - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId' -} - -WebIM.conn.leaveChannel(options).then(() => { - console.log('离开频道成功') -}) -``` - -##### 频道成员被移出频道 - -社区所有者和管理员可以调用 `removeChannelMember` 方法将指定成员移出频道。被移出频道的成员会收到 `onChannelEvent` 回调,事件为 `removed`,频道其他成员会收到 `onChannelEvent` 回调,事件为 `memberAbsence`。被移出频道的成员不会再收到频道消息。 - -:::tip -社区内的默认频道不允许踢出成员。 -::: - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', - userId: 'userId' -} - -WebIM.conn.removeChannelMember(options).then(() => { - console.log('移除频道成员成功') -}) -``` - -#### 将成员加入频道禁言列表 - -仅社区所有者和社区管理员可以调用 `muteChannelMember` 方法将频道成员加入禁言列表。被禁言的频道成员、社区所有者和管理员(除操作者外)会收到 `onChannelEvent` 回调,事件为 `muteMember`。 - -禁言列表中的成员无法在频道中发送消息,但可以接收频道中的消息。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', - userId: 'userId', - duration: -1 -} - -WebIM.conn.muteChannelMember(options).then(() => { - console.log('禁言频道成员成功') -}) -``` - -#### 将成员移出频道禁言列表 - -社区所有者和社区管理员可以调用 `unmuteChannelMember` 方法,将频道禁言列表上的频道成员移出频道禁言列表。被移出禁言列表的频道成员、社区所有者和管理员(除操作者外)会收到 `onChannelEvent` 回调,事件为 `unmuteMember`。频道成员被移出禁言列表后可在频道中正常发送和接收消息。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', - userId: 'userId', -} - -WebIM.conn.unmuteChannelMember(options).then(() => { - console.log('移除禁言成员成功') -}) -``` - -#### 获取频道禁言列表 - -社区所有者和社区管理员可以调用 `getChannelMutelist` 方法获取频道下的禁言列表。 - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', -} - -WebIM.conn.getChannelMutelist(options).then((res) => { - console.log(res) -}) -``` - -#### 获取指定频道的成员列表 - -频道中的成员可以获取该频道下的成员列表: - -- 创建语聊房频道时,创建者不加入频道。因此,频道创建者不算入频道成员数量,查询频道成员列表时不返回频道创建者。 - -- 对于其他模式的频道创建时,创建者直接加入频道。因此,频道创建者算入频道成员数量,查询频道成员列表返回频道创建者。 - - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', - pageSize: 20, - cursor: '' -} - -WebIM.conn.getChannelMembers(options).then((res) => { - console.log(res) -}) -``` - -#### 查询当前用户是否在频道中 - -社区成员可以调用 `isInChannel` 方法查询自己是否在指定频道中。示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - channelId: 'channelId', -} - -WebIM.conn.isInChannel(options).then((res) => { - console.log(res) -}) -``` - -### 监听频道事件 - -Circle 提供 `addEventHandler` 方法用于注册监听事件。开发者可以通过设置此监听,获取频道分组中的事件。 - -```javascript -WebIM.conn.addEventHandler("channelEvent", { - onChannelEvent: (e) => { - const { operation } = e; - switch (operation) { - case "destroy": - // 解散频道。频道的所有成员(除操作者外)会收到该事件。 - break; - case "update": - // 修改频道信息。频道所有成员(除操作者外)会收到该事件。 - break; - case "memberAbsence": - // 有成员主动退出频道。频道内的其他成员会收到该事件。 - break; - case "memberPresence": - // 有用户加入频道。频道的所有成员会收到该事件。 - break; - case "removed": - // 有成员被移出频道。被移出的成员会收到该事件。 - break; - case "muteMember": - // 有成员被添加至频道禁言列表。被添加至禁言列表的成员、社区所有者和管理员(除操作者外)会收到该事件。 - break; - case "unmuteMember": - // 有用户被移出频道禁言列表。被移出禁言列表的成员、社区所有者和管理员(除操作者外)会收到该事件。 - break; - case "inviteToJoin": - // 用户收到频道加入邀请。受邀用户会收到该事件。 - break; - case "rejectInvite": - // 用户拒绝频道加入邀请。邀请人会收到该事件。 - break; - case "acceptInvite": - // 用户同意频道加入邀请。邀请人会收到该事件。 - break; - default: - break; - } - } -}); - -``` \ No newline at end of file diff --git a/docs/product/circle/circle_errorcode_android.md b/docs/product/circle/circle_errorcode_android.md deleted file mode 100644 index 004a4b99..00000000 --- a/docs/product/circle/circle_errorcode_android.md +++ /dev/null @@ -1,13 +0,0 @@ - -# 超级社区错误码 - -本文介绍环信超级社区(Circle) Android SDK 中接口调用或者回调中的错误码。你可以根据错误码判断错误原因。 - -下表中的错误码为超级社区特有,其他的与即时通讯 IM SDK 相同,详见 [Android SDK 错误码](/document/android/error.html)。 - -| 错误码 | 错误信息 | 可能原因 | -| :-----: | :----------------------------- | :--------------------------- | -| 7 | PARTIAL_SUCCESS | 请求返回成功,但有一些错误,例如,批量设置语聊频道的属性,若某条属性其他用户已设置,则设置失败,其它的可以设置成功。 | -| 112 | QUERY_PARAM_REACHES_LIMIT | 参数超过限制,例如,社区名称超过了 50 个字符。 | -| 113 | REACH_LIMIT | 用户加入社区的数量超过限制。 | -| 114 | REPEATED_OPERATION | 用户已经在社区中。 | \ No newline at end of file diff --git a/docs/product/circle/circle_errorcode_ios.md b/docs/product/circle/circle_errorcode_ios.md deleted file mode 100644 index 01d858aa..00000000 --- a/docs/product/circle/circle_errorcode_ios.md +++ /dev/null @@ -1,13 +0,0 @@ - -# 超级社区错误码 - -本文介绍环信超级社区(Circle) iOS SDK 中接口调用或者回调中的错误码。你可以根据错误码判断错误原因。 - -下表中的错误码为超级社区特有,其他的与即时通讯 IM SDK 相同,详见 [iOS SDK 错误码](/document/ios/error.html)。 - -| 错误码 | 错误信息 | 可能原因 | -| :-----: | :----------------------------- | :--------------------------- | -| 7 | EMErrorPartialSuccess | 请求返回成功,但有一些错误,例如,批量设置语聊频道的属性,若某条属性其他用户已设置,则设置失败,其它的可以设置成功。 | -| 112 | EMErrorQueryParamReachesLimit | 参数超过限制,例如,社区名称超过了 50 个字符。 | -| 113 | EMErrorReachLimit | 用户加入社区的数量超过限制。 | -| 114 | EMErrorRepeatedOperation | 用户已经在社区中。 | \ No newline at end of file diff --git a/docs/product/circle/circle_errorcode_web.md b/docs/product/circle/circle_errorcode_web.md deleted file mode 100644 index 15528003..00000000 --- a/docs/product/circle/circle_errorcode_web.md +++ /dev/null @@ -1,3 +0,0 @@ -# 超级社区错误码 - -环信超级社区(Circle) Web SDK 的错误码与即时通讯 IM SDK 相同,详见 [Web SDK 错误码](/document/android/error.html)。 \ No newline at end of file diff --git a/docs/product/circle/circle_overview.md b/docs/product/circle/circle_overview.md deleted file mode 100644 index 7b1b97bd..00000000 --- a/docs/product/circle/circle_overview.md +++ /dev/null @@ -1,200 +0,0 @@ -# 环信超级社区概述 - - - -环信超级社区(Circle)是一款基于环信 IM 打造的类 Discord 实时社区应用场景方案,支持社区(Server)、频道(Channel) 和子区(Thread) 三层结构。一个 App 下可以有多个社区,同时支持陌生人/好友单聊。用户可创建和管理自己的社区,在社区中设置和管理频道将一个话题下的子话题进行分区,在频道中根据感兴趣的某条消息发起子区讨论,实现万人实时群聊,满足超大规模用户的顺畅沟通需求。 - -## 社区、频道和子区介绍 - -![img](/images/circle/circle_product_overview.png) - -### 社区、频道和子区的基本概念与关系 - -社区(Server)是一群有着共同兴趣爱好的人的专属天地,也可以是同学朋友的社交圈子。社区是环信超级社区三层基础架构的最上层,各种消息事件均发生在社区内。社区分为公开社区和私密社区。对于公开社区,任何用户均可查询社区列表,可自由加入或退出社区,无需审批;对于私密社区,用户无法查询社区列表,只能通过社区成员邀请加入社区,无法申请加入社区。 - -频道(Channel)是一个社区下不同子话题的讨论分区,因此一个社区下可以有多个频道。社区下有一个默认频道用于承载各种系统通知。从可见性角度看,频道社区分为公开和私密频道;从功能角度看,频道分为文字频道和语聊频道。社区创建者可以根据自己需求创建频道。此外,多个频道还可以归入一个频道分组,方便管理。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过 RESTful API 或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_android.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](server_mgmt_android.html#解散社区)和[删除频道](channel_mgmt_android.html#解散频道)等 API。** - -子区(Thread)是一个基于频道中某一条消息展开的讨论,用户可以某条消息为中心,与其他对此条消息感兴趣的朋友一起聚焦沟通。 - -通过 Server-Channel-Thread 三层架构,每个用户都可以找到属于自己的兴趣社区,并在其中与自己趣味相投的好友建立圈子。既保证同一个社区中的成员管理秩序,用户关系不会被打散,同时为每个用户提供构建专属于自己和好友的圈子,满足多维度的沟通需求。 - -## 限制条件 - -- 每个 app 下的社区数量以及每个社区内的成员数均无限制。 -- 单个用户最多可创建 100 个社区。单个用户默认最多可加入 100 个社区。如需调整该阈值,请联系商务。 -- 每个社区最多可添加 10 个标签。 -- 每个社区下最多可以创建 50 个频道分组。每个频道分组下最多可包含 100 个频道。如需调整该阈值,请联系商务。 -- 默认情况下,每个社区的默认频道最多可包含 2000 个用户。如需调整该阈值,请联系商务。 -- 每个社区下可创建的频道无上限。用户可加入的频道数量无上限。频道的最大成员数量取决于频道模式: - - 对于文字频道,单个频道的最大成员数量的范围为 [1,2000]。 - - 对于语聊频道,单个频道的最大成员数量的范围为 [1,20],默认值为 `8`。 -- 每条消息只能创建一条子区。每个频道支持的子区数量无限制。 - -## 社区管理 - -### 社区角色类型及权限 - -社区的成员包括社区所有者(Server Owner)、管理员(Server Moderator)和普通成员(User)。 - -|社区成员角色|描述|管理权限| -| :- | :- | :- | -|社区所有者|社区中权限最高的管理者|社区所有者拥有社区、频道分组和频道的创建和所有管理权限:
- 创建社区和管理社区及社区成员,例如获取社区信息、修改社区信息、解散社区以及设置和移除管理员等。
- 管理频道分组,例如创建频道分组、获取社区下的频道分组列表、修改频道分组名称以及删除频道分组等。
- 管理频道和频道成员,例如创建频道、获取频道详情、修改频道信息、解散频道以及禁言和解除禁言频道内的成员等。| -|管理员|社区管理员|拥有社区和频道的查看和管理权限以及对社区和频道中的普通成员的管理权限。| -|普通成员|社区中普通成员|社区的普通成员可以在频道和子区中收发和查看消息。| - -- 每个社区只有一个社区所有者,该所有者是社区下所有频道和频道分组的所有者。 -- 社区所有者可单独设置特定用户为社区管理员。 -- 社区管理员,从权限角度可以理解为社区下所有频道的管理员。 - -### 社区属性管理 - -社区属性包括以下七种: - -- 社区名称,不超过 50 个字符; -- 社区类型,即公开或私密社区; -- 社区描述,不超过 500 个字符; -- 社区头像 URL,不能超过 500 个字符; -- 社区背景 URL,不能超过 500 个字符; -- 社区标签,不能超过 20 个字符; -- 社区自定义字段,不超过 500 个字符。 - -### 社区管理操作 - -|功能|描述| -| :- | :- | -|创建社区|每个用户默认最多可创建 100 个社区,如需调整该阈值,请联系商务。| -|修改社区信息|社区所有者和管理员可修改社区基本信息。| -|解散社区|解散社区需要社区所有者权限。
解散社区后所有成员将收到社区解散的回调信息。| -|添加社区标签|社区所有者和管理员可以给社区增加标签,非社区内用户可以通过搜索标签找到社区。每个社区最多可添加 10 个标签。| -|移除社区标签|社区所有者和管理员可以移除社区已有标签。| -|获取社区标签列表|社区成员可获取社区标签列表。| -|获取社区详情|用户可以获取社区的详情。| -|获取已加入社区|获取用户已加入的社区列表。 | -|搜索公开社区|社区成员可以根据社区名称或标签名称搜索公开社区。 | -|分页获取社区成员列表|分页获取指定社区中的成员列表。| - - -### 社区的成员管理 - - -|功能|描述| -| :- | :- | -|加入社区|社区分为公开和私密社区。
- 对于公开社区,用户可以通过搜索社区名称和标签的方式申请加入社区,或者由社区内成员邀请加入。
- 对于私密社区,只能通过社区内成员邀请加入。用户可以选择同意或拒绝加入社区。| -|退出社区|社区所有者不支持退出社区操作,只能解散社区。
退出社区分为主动退出和被动退出,被动退出即为被社区所有者或管理员踢出社区。社区所有者和管理员可将普通用户踢出社区,管理员只能被社区所有者踢出社区。 | -|查询当前用户是否在社区内|可判断指定用户是否已经加入了指定社区。| -|修改社区中成员角色|社区所有者可以将管理员权限赋予社区中普通用户,或移除管理员权限将其变为普通用户。| -|查询当前用户在社区内角色|社区内成员可以获取社区内用户的角色。| - -## 频道 - -社区所有者可创建频道,并将多个频道归为同一频道分组。 - -频道的划分如下: - -- 从可见性角度,频道分为公开频道和私密频道。 - -公开频道对社区中所有用户可见;私密频道只对社区所有者、管理员(Moderator)和被邀请进私密频道的用户可见。 - -- 从功能角度,频道可分为文字频道和语聊频道。 - -文字频道实现文字消息和图片消息互动,语聊频道实现语音聊天。 - -### 频道属性管理 - -频道的属性包括以下七种: - -- 频道名称,不超过 50 个字符; -- 频道描述,不超过 500 个字符; -- 频道类型,包括公开和私密频道; -- 频道模式,包括文字频道和语聊频道; -- 频道大小,文字频道最多可容纳 2000 人,而语聊频道最多可容纳 20 人; -- 频道自定义字段,不超过 500 个字符; -- 频道分组名称,不超过 50 个字符。 - -### 频道管理操作 - -|功能|描述| -| :- | :- | -|创建频道|社区所有者可以在社区中创建公开或私密频道。| -|修改频道信息|社区所有者和管理员可以修改频道的属性。| -|解散频道|社区所有者可以解散社区中的频道。| -|获取频道详情|社区成员可获取频道的详情。| -|获取社区的公开频道列表|社区成员可以获取社区下的所有公开频道的列表。| -|获取社区的私密频道列表|社区成员可以获取社区下的所有私密频道的列表。| -|获取社区中用户加入的频道列表|社区成员可以获取自己已经加入的频道。| -|获取频道的成员列表|频道成员可以获取该频道下的成员列表。| -|创建频道分组|社区所有者可以创建频道分组。| -|修改频道分组名称|社区所有者可修改频道分组名称。| -|获取社区下的频道分组列表|社区成员可以获取社区下的频道分组列表。| -|删除频道分组|社区所有者可以删除频道分组。| -|分页获取频道分组下的公开频道列表|社区成员可以分页获取频道分组下公开的频道列表。| -|分页获取频道分组下的私密频道列表|社区成员可以分页获取频道分组下的私密频道列表。| -|更换频道所属的频道分组|社区所有者和管理员可以将指定的频道从一个频道分组转移至另一个频道分组中。| - -### 频道的成员管理 - -#### 频道的成员角色权限 - -用户在频道中的角色与其社区中的角色相同,即用户在社区的角色会被继承到频道。 - -#### 频道的成员管理操作 - -|功能|描述| -| :- | :- | -|加入频道|频道分为公开和私密频道。
- 对于公开频道,用户可以获取公开频道列表,然后申请加入频道,或者由频道成员邀请加入。
- 对于私密频道,只能通过频道成员邀请加入。用户可以选择同意或拒绝加入频道。| -|退出频道|退出频道分为主动退出和被动退出,被动退出即被社区所有者或管理员踢出频道。 | -|查询用户是否在频道中|查询指定用户是否在指定频道中。| -|频道禁言/解除禁言|社区所有者和社区管理员可以将频道成员加入或移出禁言列表,禁言列表中的成员无法发送频道消息,可以接收频道中的消息。| -|获取频道下的禁言列表|社区所有者和社区管理员可以获取频道下被禁言用户的列表。| - -## 子区 - -### 子区属性管理 - -子区名称,不超过 50 个字符。 - -### 子区管理操作 - -|功能|描述| -| :- | :- | -|创建子区|频道成员可以在频道中创建子区。| -|加入子区|频道成员可以加入频道下的子区。| -|退出子区|子区成员可以主动退出或被移出自己加入的子区。| -|删除子区|社区所有者可以删除该频道中的子区。| -|获取子区详情|频道成员可以获取子区的详情。| -|获取频道下创建的子区列表|频道成员可以获取在指定频道下创建的子区列表。| -|获取频道下加入的子区列表|频道成员可以获取频道下加入的子区。| -|获取频道的子区列表|频道成员获取频道的所有子区的列表。| -|修改子区名称|社区所有者、社区管理员和子区的创建者可以修改子区的名称。| - -## 参考信息 - -### 用户 - -|功能|描述| -| :- | :- | -|查询用户是否存在|查询 App Key 下用户是否存在。| -|获取用户在离线状态|用户可以获取在离线状态。| -|添加好友|用户可以添加好友。| -|删除好友|用户可以删除好友。| - -### 消息管理 - -消息相关功能可参考官网 [消息管理](/product/product_message_overview.html) 文档,目前不支持已读或未读回执。 - -|功能|描述| -| :- | :- | -|发送消息|用户可以给指定用户、频道或子区发消息/图片/文件。| -|撤回消息|用户可以撤回自己发送的消息。| -|添加 Reaction|用户可以给消息添加 Reaction。| -|获取 Reaction|用户可以获取 Reaction。| -|删除 Reaction|用户可以删除自己添加的 Reaction。| -|获取 Emoji|用户可以获取 Emoji。| -|获取 Emoji 类|用户可以获取 Emoji 类。| \ No newline at end of file diff --git a/docs/product/circle/circle_quickstart_android.md b/docs/product/circle/circle_quickstart_android.md deleted file mode 100644 index 4d4958e1..00000000 --- a/docs/product/circle/circle_quickstart_android.md +++ /dev/null @@ -1,230 +0,0 @@ -# 环信超级社区(Circle)快速开始 - - - -## 集成准备 - -使用 Circle 之前,确保你已经集成环信 Circle SDK(IM Android SDK 3.9.9.2),详见 [环信即时通讯 IM Android 快速开始](/document/android/quickstart.html)。 - -## 技术原理 - -用户需加入一个社区,选择加入社区或社区下频道分组中的频道,然后才能在频道中发送消息。 - -发送和接收消息的逻辑如下: - -1. 发送方获取社区 ID; -2. 发送方获取频道 ID; -3. 发送方通过 `sendMessage` 发送消息; -4. 接收方通过 `EMMessageListener` 添加消息接收的回调通知。 - -## 实现方法 - -### 获取指定的社区 - -你可以通过三种方式获取指定的社区 ID: - -- 创建社区; -- 加入一个现有社区; -- 获取已加入的社区列表。 - -#### 创建社区 - -你可以调用 `createServer` 方法创建一个社区: - -```java -EMCircleServerAttribute attribute = new EMCircleServerAttribute(); - attribute.setName(name); - attribute.setDesc(desc); - attribute.setIcon(icon); -EMClient.getInstance().chatCircleManager().createServer(attribute, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 加入一个现有社区 - -你可以调用 `joinServer` 方法加入一个现有社区: - -```java -EMClient.getInstance().chatCircleManager().joinServer(serverId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer value) { - - } - - @Override - public void onError(int code, String error) { - - } - } -); -``` - -#### 获取已加入的社区列表 - -你可以调用 `fetchJoinedServers` 方法获取已加入的社区列表: - -```java -EMClient.getInstance().chatCircleManager().fetchJoinedServers(20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -### 获取指定的频道 - -你可以通过三种方式获取指定的频道 ID: - -- 创建频道; -- 加入一个现有频道; -- 获取已加入的频道列表; -- 获取社区中的频道列表; - -#### 创建频道 - -你可以调用 `createChannel` 方法创建频道: - -```java -EMCircleChannelAttribute attribute = new EMCircleChannelAttribute(); - attribute.setName(name); - attribute.setDesc(desc); - attribute.setMaxUsers(2000); - attribute.setType(EMCircleChannelStyle.EMChannelStylePublic); - -EMClient.getInstance().chatCircleManager().createChannel(serverId, categoryId, attribute, EMCircleChannelModeChat, new EMValueCallBack() { - - @Override - public void onSuccess(EMCircleChannel value) { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 加入一个现有频道 - -你可以调用 `joinChannel` 方法加入一个频道: - -```java -EMClient.getInstance().chatCircleManager().joinChannel(serverId, channelId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleChannel value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 获取社区的公开频道列表 - -你可以调用 `fetchPublicChannelsInServer` 方法获取社区下的公开频道列表: - -```java -EMClient.getInstance().chatCircleManager().fetchPublicChannelsInServer(serverId, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 获取社区的私密频道列表 - -你可以调用 `fetchVisiblePrivateChannelsInServer` 方法获取社区下所有私密频道的列表: - -```java -EMClient.getInstance().chatCircleManager().fetchVisiblePrivateChannelsInServer(serverId, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -此外,你还可以调用 `fetchPublicChannelsInCategory` 或 `fetchPrivateChannelsInCategory` 方法获取指定频道分组下的公开频道列表或私密频道列表。 - -### 发送和接收一条频道消息 - -在频道中发送和接收消息,你可以参考 [发送和接收消息](/document/android/message_send_receive.html)。 - -#### 发送一条频道消息 - -你可以调用 `sendMessage` 方法在指定频道中发送一条消息: - -```java -// 创建一条文本消息,`content` 为消息文字内容,`channelID` 为频道 ID -EMMessage message = EMMessage.createTextSendMessage(content, channelID); -// 设置消息类型,即设置 `Message` 类的 `ChatType` 为 `GroupChat`。 -message.setChatType(EMMessage.ChatType.GroupChat); -// 设置消息属性为 `Channel Message`。 -message.setIsChannelMessage(true); - -// 发送消息。 -EMClient.getInstance().chatManager().sendMessage(message); -// 发送消息时可以设置 `EMCallBack` 的实例,获得消息发送的状态。可以在该回调中更新消息的显示状态。例如消息发送失败后的提示等。 -message.setMessageStatusCallback(new EMCallBack() { - @Override - public void onSuccess() { - - } - @Override - public void onError(int code, String error) { - - } - @Override - public void onProgress(int progress, String status) { - - } - - }); -EMClient.getInstance().chatManager().sendMessage(message); -``` - -#### 接收一条频道消息 - -你可以注册 `EMMessageListener` 监听器接收消息。 - -```java -EMMessageListener msgListener = new EMMessageListener() { - - // 收到消息,遍历消息队列,解析和显示。 - @Override - public void onMessageReceived(List messages) { - - } -}; -EMClient.getInstance().chatManager().addMessageListener(msgListener); -``` diff --git a/docs/product/circle/circle_quickstart_ios.md b/docs/product/circle/circle_quickstart_ios.md deleted file mode 100644 index 9b242f74..00000000 --- a/docs/product/circle/circle_quickstart_ios.md +++ /dev/null @@ -1,182 +0,0 @@ -# 环信超级社区(Circle)快速开始 - - - -## 集成准备 - -使用 Circle 之前,确保你已经集成环信 Circle SDK(IM iOS SDK 3.9.9.1),详见 [环信即时通讯 IM iOS 快速开始](/document/ios/quickstart.html)。 - -## 技术原理 - -用户需加入一个社区,选择加入社区或社区下频道分组中的频道,然后才能在频道中发送消息。 - -发送和接收消息的逻辑如下: - -1. 发送方获取社区 ID; -2. 发送方获取频道 ID; -3. 发送方通过 `sendMessage` 发送消息; -4. 接收方通过 `EMChatManagerDelegate` 添加消息接收的回调通知。 - -## 实现方法 - -### 获取指定的社区 - -你可以通过三种方式获取指定的社区 ID: - -- 创建社区; -- 加入一个现有社区; -- 获取已加入的社区列表。 - -#### 创建社区 - -你可以调用 `createServer` 方法创建一个社区: - -```swift -let attribute = EMCircleServerAttribute() -attribute.name = name -attribute.icon = icon -attribute.desc = desc -attribute.ext = ext -EMClient.shared().circleManager?.createServer(attribute) { server, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - } else if server != nil { - Toast.show("创建成功", duration: 2) - } -} -``` - -#### 加入一个现有社区 - -你可以调用 `joinServer` 方法加入一个现有社区: - -```swift -EMClient.shared().circleManager?.joinServer(serverId) { server, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - } else if let server = server { - Toast.show("加入成功", duration: 2) - } -} -``` - -#### 获取已加入的社区列表 - -你可以调用 `fetchJoinedServers` 方法获取已加入的社区列表: - -```swift -EMClient.shared().circleManager?.fetchJoinedServers(20, cursor: self.cursor) { result, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - return - } -} -``` - -### 获取指定的频道 - -你可以通过三种方式获取指定的频道 ID: - -- 创建频道; -- 加入一个现有频道; -- 获取已加入的频道列表; -- 获取社区中的频道列表; - -#### 创建频道 - -你可以调用 `createChannel` 方法创建频道: - -```swift -let attribute = EMCircleChannelAttribute() -attribute.name = name -attribute.desc = desc -EMClient.shared().circleManager?.createChannel(self.serverId, categoryId: self.categoryId, attribute: attribute, mode: self.mode, completion: { channel, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - } else { - Toast.show("创建成功", duration: 2) - } -}) -``` - -#### 加入一个现有频道 - -你可以调用 `joinChannel` 方法加入一个频道: - -```swift -EMClient.shared().circleManager?.joinChannel(serverId, channelId: channelId) { channel, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - } else { - Toast.show("加入成功", duration: 2) - } -} -``` - -#### 获取社区的公开频道列表 - -你可以调用 `fetchPublicChannelsInServer` 方法获取社区下的公开频道列表: - -```swift -EMClient.shared().circleManager?.fetchPublicChannels(inServer: serverId, limit: 20, cursor: nil) { result, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - return - } -} -``` - -#### 获取社区的私密频道列表 - -你可以调用 `fetchPrivateChannelsInServer` 方法获取社区下所有私密频道的列表: - -```swift -EMClient.shared().circleManager?.fetchPrivateChannels(inServer: self.serverId, limit: 20, cursor: nil) { result, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - return - } -} -``` - -此外,你还可以调用 `fetchPublicChannelsInCategory` 或 `fetchPrivateChannelsInCategory` 方法获取指定频道分组下的公开频道列表或私密频道列表。 - -### 发送和接收一条频道消息 - -在频道中发送和接收消息,你可以参考 [发送和接收消息](/document/ios/message_send_receive.html)。 - -#### 发送一条频道消息 - -你可以调用 `sendMessage` 方法在指定频道中发送一条消息: - -```swift -let messageBody = EMTextMessageBody(text: text) -let message = EMChatMessage(conversationID: channelId, from: selfUserId, to: channelId, body: messageBody, ext: nil) -message.isChannelMessage = true -message.chatType = .groupChat -EMClient.shared().chatManager.send(message, progress: nil) { message, error in - if let error = error { - Toast.show(error.errorDescription, duration: 2) - } else { - Toast.show("发送成功", duration: 2) - } -} -``` - -#### 接收一条频道消息 - -添加 `ChatManager` 回调的代理对象: - -```swift -EMClient.shared().chatManager?.add(self, delegateQueue: nil) -``` - -代理对象实现 `EMChatManagerDelegate` 接口的 `messagesDidReceive` 方法。 - -```swift -extension ChatViewController : EMChatManagerDelegate { - func messagesDidReceive(_ aMessages: [EMChatMessage]) { - - } -} -``` diff --git a/docs/product/circle/circle_quickstart_web.md b/docs/product/circle/circle_quickstart_web.md deleted file mode 100644 index f505a9b1..00000000 --- a/docs/product/circle/circle_quickstart_web.md +++ /dev/null @@ -1,178 +0,0 @@ -# 环信超级社区 (Circle) 快速开始 - - - -## 集成准备 - -使用 Circle 前,确保你已经集成环信即时通讯 IM Web Circle SDK,Circle SDK 的集成方式与环信即时通讯 IM SDK 相同,详见 [环信即时通讯 IM Web 快速开始](/document/web/quickstart.html)。 - -## 技术原理 - -用户需加入一个社区,选择加入社区或社区下频道分组中的频道,然后才能在频道中发送消息。 - -发送和接收消息的逻辑如下: - -1. 发送方获取社区 ID; -2. 发送方获取频道 ID; -3. 发送方通过 `send` 发送消息; -4. 接收方通过 `addEventHandler` 注册监听器接收各类消息的回调。 - -## 实现方法 - -### 获取指定的社区 - -你可以通过三种方式获取指定的社区 ID: - -- 创建社区; -- 加入一个现有社区; -- 获取已加入的社区列表。 - -#### 创建社区 - -你可以调用 `createServer` 方法创建一个社区: - -```javascript -let options = { - name: 'server name', - icon: 'image url', - description: 'a test server', - ext: '', - isPublic: true, - backgroundUrl: '', -} -WebIM.conn.createServer(options).then(res => { - console.log(res) -}) - -``` - -#### 加入一个现有社区 - -你可以调用 `joinServer` 方法加入一个现有社区: - -```javascript -WebIM.conn.joinServer({serverId: 'serverId'}).then(res=>{ - console.log(res) -}) -``` - -#### 获取已加入的社区列表 - -你可以调用 `getJoinedServers` 方法获取已加入的社区列表: - -```javascript -WebIM.conn.getJoinedServers({pageSize: '10',cursor: ''}).then(res=>{ - console.log(res) -}) -``` - -### 获取指定的频道 - -你可以通过三种方式获取指定的频道 ID: - -- 创建频道; -- 加入一个现有频道; -- 获取已加入的频道列表; -- 获取社区中的频道列表。 - -#### 创建频道 - -你可以调用 `createChannel` 方法创建频道: - -```javascript -let options = { - serverId: 'serverID', - isPublic: true, - name: 'channelName', - description: 'this is my channel', - ext: 'ext', - maxusers: 8, - mode: 0, - categoryId: 'categoryId', - rtcChannelId: 'rtcChannelId', -} -WebIM.conn.createChannel(options).then(res => { - console.log(res) -}) -``` - -#### 加入一个现有频道 - -你可以调用 `joinChannel` 方法加入频道: - -```javascript -WebIM.conn.joinChannel({serverId: 'serverId', channelId: 'channelId'}).then(res => { - console.log(res) -}) -``` - -#### 获取社区的公开频道列表 - -你可以调用 `getPublicChannels` 方法获取社区下的公开频道列表: - -```javascript -let options = { - serverId: 'serverId', - pageSize: 20, - cursor: '' -} -WebIM.conn.getPublicChannels(options).then(res => { - console.log(res) -}) -``` - -#### 获取社区的私密频道列表 - -你可以调用 `getPrivateChannels` 方法获取社区下所有私密频道的列表: - -```javascript -let options = { - serverId: 'serverId', - pageSize: 20, - cursor: '' -} -WebIM.conn.getPrivateChannels(options).then(res => { - console.log(res) -}) -``` - -此外,你还可以调用 `getCategoryPublicChannels` 或 `getCategoryPrivateChannels` 方法获取指定频道分组下的公开频道列表或私密频道列表。 - -### 发送和接收一条频道消息 - -在频道中发送和接收消息,你可以参考 [发送和接收消息](/document/web/message_send_receive.html)。 - -#### 发送一条频道消息 - -你可以调用 `create` 方法构建一条文本消息并在指定频道中发送: - -```javascript -// 在指定频道发送文本消息。 -function sendChannelText() { - let option = { - chatType: 'groupChat', // 会话类型,设置为群聊。 - type: 'txt', // 消息类型。 - to: 'channelId', // 消息接收方(频道 ID)。 - msg: 'message content' // 消息内容。 - } - let msg = WebIM.message.create(option); - WebIM.conn.send(msg).then(() => { - console.log('send text message Success'); - }).catch((e) => { - console.log("Send text message error"); - }) -}; -``` - -#### 接收一条频道消息 - -你可以通过 `addEventHandler` 注册监听器接收文本消息的回调 。 - -```javascript -WebIM.conn.addEventHandler('messageHandler', { - // 收到文本消息。 - onTextMessage: function ( message ) { - console.log(message) - } -}); -``` \ No newline at end of file diff --git a/docs/product/circle/server_mgmt_android.md b/docs/product/circle/server_mgmt_android.md deleted file mode 100644 index 57ebbc3f..00000000 --- a/docs/product/circle/server_mgmt_android.md +++ /dev/null @@ -1,550 +0,0 @@ -# 管理社区 - - - -社区(Server)是一群有着共同兴趣爱好的人的专属天地,也可以是同学朋友的社交圈子。社区是环信圈子三层基础架构的最上层,各种消息事件均发生在社区内。社区分为公开社区和私密社区。对于公开社区,任何用户均可查询社区列表,可自由加入或退出社区,无需审批;对于私密社区,用户无法查询社区列表,只能通过社区成员邀请加入社区,无法申请加入社区。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_android.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](#解散社区)和[删除频道](channel_mgmt_android.html#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 提供 `EMCircleManager` 类和 `EMCircleServer` 类用于社区管理,支持你通过调用 API 在项目中实现如下功能: - -- 创建和管理社区; -- 管理社区成员; -- 监听社区事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.2 版本的初始化,详见 [IM SDK 初始化](/document/android/initialization.html) -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -### 创建和管理社区 - -#### 创建社区 - -社区分为公开社区和私密社区。每个用户最多可以创建 100 个社区。若要提升上限,请联系商务。 - -1. 调用 `createServer` 方法创建社区。 - -示例代码如下: - -```java -EMCircleServerAttribute attribute = new EMCircleServerAttribute(); - attribute.setName(name); - attribute.setDesc(desc); - attribute.setIcon(icon); -EMClient.getInstance().chatCircleManager().createServer(attribute, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -创建社区时,需设置社区属性 `EMCircleServerAttribute`,如下表所示。 - -| 参数 | 类型 | 描述 | 是否必需 | -| :--------- | :----------------------- | :------------------ |:------------------ | -| `name` | String | 社区名称,不能超过 50 个字符。 | 是 | -| `icon` | String | 社区头像 URL,不能超过 500 个字符。 | 否 | -| `type` | EMCircleServerType | 社区类型:
- (默认)`Public`:公开社区;
- `Private`:私密社区。 | 否 | -| `backgroundUrl` | String | 社区背景 URL,不能超过 500 个字符。 | 否 | -| `desc` | String | 社区描述,不能超过 500 个字符。 | 否 | -| `ext` | String | 社区自定义扩展字段,不能超过 500 个字符。 | 否 | - -2. 邀请用户加入社区。 - - 社区成员调用 `inviteUserToServer` 方法邀请用户加入社区。受邀用户收到 `EMCircleServerListener#onReceiveInvitation` 事件。 - -示例代码如下: - -```java - EMClient.getInstance().chatCircleManager().inviteUserToServer(serverId, inviteeUserId, "欢迎加入server", new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } - } -); - -``` - -3. 用户确认是否加入社区。 - - - 若同意加入社区,调用 `acceptServerInvitation` 方法。邀请人收到 `EMCircleServerListener#onInvitationBeAccepted` 事件,社区内所有成员(不包括加入社区的该新成员)会收到 `EMCircleServerListener#onMemberJoinedServer` 事件。示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().acceptServerInvitation(serverId, inviterUserID, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer value) { - - } - - @Override - public void onError(int error, String message) { - - } -}); -``` - - - 若拒绝加入社区,调用 `declineServerInvitation` 方法。邀请人收到 `EMCircleServerListener#onInvitationBeDeclined` 事件。示例代码如下: - - ```java -EMClient.getInstance().chatCircleManager().declineServerInvitation(serverId, inviterUserID, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String message) { - - } -}); - ``` - -#### 修改社区信息 - -社区所有者和管理员可调用 `updateServer` 方法修改社区信息,包括社区名称、类型、描述、头像 URL、背景 URL 和自定义扩展信息。社区信息修改后,社区的所有成员(除操作者外)会收到 `EMCircleServerListener#onServerUpdated` 事件。 - -示例代码如下: - -```java -EMCircleServerAttribute serverAttribute = new EMCircleServerAttribute(); - serverAttribute.setName("name"); - serverAttribute.setIcon("iconUrl"); - serverAttribute.setDesc("update desc"); - serverAttribute.setExt(""); -EMClient.getInstance().chatCircleManager().updateServer(serverId, serverAttribute, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer circleServer) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 解散社区 - -仅社区所有者可调用 `destroyServer` 方法解散社区。社区解散后,社区所有成员(除社区所有者)会收到 `EMCircleServerListener#onServerDestroyed` 事件并被移出社区。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().destroyServer(serverId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 添加社区标签 - -社区所有者和管理员可以调用 `addTagsToServer` 方法为社区添加标签。非社区内用户可以通过搜索标签全名查找社区。每个社区最多可添加 10 个标签。 - -示例代码如下: - -```java -String tag = "动漫"; -ArrayList tags = new ArrayList<>(); -tags.add(tag); - -EMClient.getInstance().chatCircleManager().addTagsToServer(serverId, tags, new EMValueCallBack>() { - @Override - public void onSuccess(List tags) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 移除社区标签 - -社区所有者和管理员可以调用 `removeTagsFromServer` 方法移除社区已有标签。 - -示例代码如下: - -```java -ArrayList tagsRemoved = new ArrayList<>(); -tagsRemoved.add("你要移除的tagId"); -EMClient.getInstance().chatCircleManager().removeTagsFromServer(serverId, tagsRemoved, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 获取社区标签列表 - -社区成员可调用 `fetchServerTags` 方法获取社区的标签列表。 - -```java - EMClient.getInstance().chatCircleManager().fetchServerTags(serverId, new EMValueCallBack>() { - @Override - public void onSuccess(List value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 搜索公开社区 - -社区成员可以调用 `fetchServers` 方法按查询类型(`EMCircleServerSearchType`)搜索公开社区,即按社区名称或社区标签名称查询。 - - 根据社区名称搜索,支持基于通过社区全名搜索和模糊搜索分页获取数据。若使用模糊搜索,你需要传入社区名称中最左侧的单个字或词汇,或包含该字或词汇的关键字。例如社区名称为 `足球社区01`,传入 `足`或`足球` 都可搜索出该社区,而使用 `球` 或 `社区01` 则搜索不到该社区。 - - 若根据标签名称搜索,需传入完整的标签名称,不支持模糊搜索。该类型查询直接获取带有该标签的所有社区,不支持分页查询。 - -```java -EMCircleServerSearchType searchType=EMCircleServerSearchType.EM_CIRCLE_SERVER_SEARCH_TYPE_NAME; -String keyword="足球"; -EMClient.getInstance().chatCircleManager().fetchServers(searchType, keyword, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 获取社区详情 - -社区成员可以调用 `fetchServerDetail` 方法获取社区的详情。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchServerDetail(serverId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 获取已加入社区 - -社区成员可以调用 `fetchJoinedServers` 方法获取已加入的社区列表。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchJoinedServers(20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 分页获取社区成员列表 - -社区成员可以调用 `fetchServerMembers` 方法分页获取指定社区中的成员列表,该列表包含社区创建者。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchServerMembers(serverID, 20, null, new EMValueCallBack>() { - @Override - public void onSuccess(EMCursorResult value) { - - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -### 管理社区成员 - -#### 加入社区 - -每个用户最多可加入 100 个社区,超过需要联系商务。用户可以通过以下两种方式加入社区: - -1. [搜索公开社区获得社区 ID](#搜索公开社区),主动申请加入该社区。 - -2. 社区内成员邀请用户加入。 - -公开社区支持申请加入和邀请加入,而私密社区仅支持邀请加入。通过邀请加入社区,详见 [创建社区](#创建社区)。 - -下面介绍用户如何申请加入公开社区。 - -1. 用户 [搜索公开社区获得社区 ID](#搜索公开社区)。 - -2. 用户调用 `joinServer` 方法加入社区。加入成功后,社区内其他成员会收到 `EMCircleServerListener#onMemberJoinedServer` 事件。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().joinServer(serverId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleServer value) { - - } - - @Override - public void onError(int code, String error) { - - } - } -); -``` - -#### 退出社区 - -社区成员若退出社区,则会退出该社区下的所有频道。社区所有者不支持退出社区操作,只能解散社区。 - -退出社区分为主动退出和被动退出,被动退出即成员被社区所有者或管理员移出社区。 - -#### 用户主动退出社区 - -用户可调用 `leaveServer` 方法退出社区。退出成功后,社区内其他成员会收到 `EMCircleServerListener#onMemberLeftServer` 事件。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().leaveServer(serverId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 用户被移出社区 - -社区所有者和管理员调用 `removeUserFromServer` 方法将普通成员移出社区,管理员只能被社区所有者移出社区。被移出社区的成员、社区所有者和管理员(除操作者外)会收到 `EMCircleServerListener#onMemberRemovedFromServer` 事件。 - -示例代码如下: - -```java - EMClient.getInstance().chatCircleManager().removeUserFromServer(serverId, userId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 查询当前用户是否在社区内 - -用户可调用 `checkSelfIsInServer` 方法查询自己是否已经加入了指定社区。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().checkSelfIsInServer(serverId, new EMValueCallBack() { - @Override - public void onSuccess(Boolean value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 查询当前用户的社区角色 - -用户可调用 `fetchSelfServerRole` 方法查询当前用户在社区中的角色。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().fetchSelfServerRole(serverId, new EMValueCallBack() { - @Override - public void onSuccess(EMCircleUserRole value) { - - } - - @Override - public void onError(int error, String errorMsg) { - - } -}); -``` - -#### 设置社区管理员 - -仅社区所有者可以调用 `addModeratorToServer` 方法设置社区管理员。成功设置后,社区所有成员(除社区所有者外)会收到 `EMCircleServerListener#onRoleAssigned` 事件。 - -社区管理员除了不能创建和解散社区等少数权限外,拥有对社区的绝大部分权限。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().addModeratorToServer(serverId, userId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -#### 移除社区管理员 - -仅社区所有者可以调用 `removeModeratorFromServer` 方法移除社区管理员。成功移除后,社区所有成员(除社区所有者外)会收到 `EMCircleServerListener#onRoleAssigned` 事件。 - -社区管理员被移除管理员权限后,将只拥有社区普通成员的权限。 - -示例代码如下: - -```java -EMClient.getInstance().chatCircleManager().removeModeratorFromServer(serverId, userId, new EMCallBack() { - @Override - public void onSuccess() { - - } - - @Override - public void onError(int code, String error) { - - } -}); -``` - -### 监听社区事件 - -`EMCircleManager` 中提供社区事件的监听接口。开发者可以通过设置此监听,获取社区中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。 - -```java -EMCircleServerListener circleServerListener = new EMCircleServerListener() { - - //社区被创建。参数社区创建的成员(除操作者外)会收到该事件。 - @Override - public void onServerCreated(EMCircleServer server) { - - } - //社区被解散。社区所有成员(除社区所有者外)会收到该事件。 - @Override - public void onServerDestroyed(String serverId, String initiator) { - - } - //社区信息更新。社区所有成员(除操作者外)会收到该事件。 - @Override - public void onServerUpdated(EMCircleServerEvent event) { - - } - //有用户加入社区。社区所有成员(除加入社区的新成员外)会收到该事件。 - @Override - public void onMemberJoinedServer(String serverId, String member) { - - } - //有成员主动退出社区。社区所有者和管理员会收到该事件。 - @Override - public void onMemberLeftServer(String serverId, String member) { - - } - //有成员被移出社区。被移除者、社区所有者和管理员(除操作者外)会收到该事件。 - @Override - public void onMemberRemovedFromServer(String serverId, List members) { - - } - //用户收到社区加入邀请。受邀用户会收到该事件。 - @Override - public void onReceiveInvitation(EMCircleServerEvent event, String inviter) { - - } - //用户同意社区加入邀请。邀请人会收到该事件。 - @Override - public void onInvitationBeAccepted(String serverId, String invitee) { - - } - //用户拒绝社区加入邀请。邀请人会收到该事件。 - @Override - public void onInvitationBeDeclined(String serverId, String invitee) { - - } - //社区成员的角色发生变化。社区所有成员(除操作者外)会收到该事件。 - @Override - public void onRoleAssigned(String serverId, String member, EMCircleUserRole role) { - - } -}; -//添加社区事件监听 -EMClient.getInstance().chatCircleManager().addServerListener(circleServerListener); - -//移除社区事件监听 -EMClient.getInstance().chatCircleManager().removeServerListener(circleServerListener); - -//清空所有社区事件的监听 -EMClient.getInstance().chatCircleManager().clearServerListeners(); -``` diff --git a/docs/product/circle/server_mgmt_ios.md b/docs/product/circle/server_mgmt_ios.md deleted file mode 100644 index d47e24cc..00000000 --- a/docs/product/circle/server_mgmt_ios.md +++ /dev/null @@ -1,346 +0,0 @@ -# 管理社区 - - - -社区(Server)是一群有着共同兴趣爱好的人的专属天地,也可以是同学朋友的社交圈子。社区是环信圈子三层基础架构的最上层,各种消息事件均发生在社区内。社区分为公开社区和私密社区。对于公开社区,任何用户均可查询社区列表,可自由加入或退出社区,无需审批;对于私密社区,用户无法查询社区列表,只能通过社区成员邀请加入社区,无法申请加入社区。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_ios.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](#解散社区)和[删除频道](channel_mgmt_ios.html#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 提供 `IEMCircleManager` 类和 `EMCircleManagerServerDelegate` 类用于社区管理,支持你通过调用 API 在项目中实现如下功能: - -- 创建和管理社区; -- 管理社区成员; -- 监听社区事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 Circle SDK 的初始化,即完成 IM SDK 3.9.9.1 版本的初始化,详见 [IM SDK 初始化](/document/ios/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -### 创建和管理社区 - -#### 创建社区 - -社区分为公开社区和私密社区。每个用户最多可以创建 100 个社区。若要提升上限,请联系商务。 - -1. 调用 `createServer` 方法创建社区。 - -示例代码如下: - -```swift -let attribute = EMCircleServerAttribute() -attribute.name = serverName -attribute.icon = serverIcon -attribute.type = .public -attribute.background = serverBackground -attribute.desc = serverDesc -attribute.ext = serverExt -EMClient.shared().circleManager?.createServer(attribute) { server, error in -} -``` - -创建社区时,需设置社区属性 `EMCircleServerAttribute`,如下表所示。 - -| 参数 | 类型 | 描述 | 是否必需 | -| :--------- | :----------------------- | :------------------ |:------------------ | -| `name` | NSString | 社区名称,不能超过 50 个字符。 | 是 | -| `icon` | NSString | 社区头像 URL,不能超过 500 个字符。 | 否 | -| `type` | EMCircleServerType | 社区类型:
- (默认)`Public`:公开社区;
- `Private`:私密社区。 | 否 | -| `background` | NSString | 社区背景 URL,不能超过 500 个字符。 | 否 | -| `desc` | NSString | 社区描述,不能超过 500 个字符。 | 否 | -| `ext` | NSString | 社区自定义扩展字段,不能超过 500 个字符。 | 否 | - -2. 邀请用户加入社区。 - - 社区成员调用 `inviteUserToServer` 方法邀请用户加入社区。受邀用户收到 `EMCircleManagerServerDelegate#onReceiveServerInvitation` 事件。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.inviteUserToServer(serverId: serverId, userId: userId, welcome: welcome) { error in -} -``` - -3. 用户确认是否加入社区。 - - - 若同意加入社区,调用 `acceptServerInvitation` 方法。邀请人收到 `EMCircleManagerServerDelegate#onServerInvitationBeAccepted` 事件,社区内所有成员(不包括加入社区的该新成员)会收到 `EMCircleManagerServerDelegate#onMemberJoinedServer` 事件。示例代码如下: - -```swift -EMClient.shared().circleManager?.acceptServerInvitation(serverId, inviter: inviter) { server, error in -} -``` - - - 若拒绝加入社区,调用 `declineServerInvitation` 方法。邀请人收到 `EMCircleManagerServerDelegate#onServerInvitationBeDeclined` 事件。示例代码如下: - - ```swift -EMClient.shared().circleManager?.declineServerInvitation(serverId, inviter: inviter) { error in -} - ``` - -#### 修改社区信息 - -社区所有者和管理员可调用 `updateServer` 方法修改社区属性 `EMCircleServerAttribute`,包括社区名称、类型、描述、头像 URL、背景 URL 和自定义扩展信息。社区信息修改后,社区的所有成员(除操作者外)会收到 `EMCircleManagerServerDelegate#onServerUpdated` 事件。 - -示例代码如下: - -```swift -let attribute = EMCircleServerAttribute() -attribute.name = serverName -attribute.desc = serverDesc -if let serverIcon = serverIcon { - attribute.icon = serverIcon -} -EMClient.shared().circleManager?.updateServer(serverId, attribute: attribute) { server, error in -} -``` - -#### 解散社区 - -仅社区所有者可调用 `destroyServer` 方法解散社区。社区解散后,社区所有成员(除社区所有者)会收到 `EMCircleManagerServerDelegate#onServerDestroyed` 事件并被移出社区。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.destroyServer(serverId) { error in -} -``` - -#### 添加社区标签 - -社区所有者和管理员可以调用 `addTagsToServer` 方法为社区添加标签。非社区内用户可以通过搜索标签全名查找社区。每个社区最多可添加 10 个标签。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.addTags(toServer: serverId, tags: ["tag1", "tag2"]) { tags, error in -} -``` - -#### 移除社区标签 - -社区所有者和管理员可以调用 `removeTagsFromServer` 方法移除社区已有标签。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.removeTags(fromServer: serverId, tagIds: ["tagId1", "tagId2"]) { error in -} -``` - -#### 获取社区标签列表 - -社区成员可调用 `fetchServerTags` 方法获取社区的标签列表。 - -```swift -EMClient.shared.circleManager?.fetchServerTags(serverId, completion: { tags, error in - -}) -``` - -#### 搜索公开社区 - -社区成员可以调用 `fetchServersWithType` 方法按查询类型(`EMCircleServerSearchType`)搜索公开社区,即按社区名称或社区标签名称查询。 - - 根据社区名称搜索,支持基于通过社区全名搜索和模糊搜索分页获取数据。若使用模糊搜索,你需要传入社区名称中最左侧的单个字或词汇,或包含该字或词汇的关键字。例如社区名称为 `足球社区01`,传入 `足`或`足球` 都可搜索出该社区,而使用 `球` 或 `社区01` 则搜索不到该社区。 - - 若根据标签名称搜索,需传入完整的标签名称,不支持模糊搜索。该类型查询直接获取带有该标签的所有社区,不支持分页查询。 - -```swift -EMClient.shared().circleManager?.fetchServers(with: .name, keyword: keyword, limit: 20, cursor: nil, completion: { servers, error in - -}) -``` - -#### 获取社区详情 - -社区成员可以调用 `fetchServerDetail` 方法获取社区的详情。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchServerDetail(serverId) { server, error in -} -``` - -#### 获取已加入社区 - -社区成员可以调用 `fetchJoinedServers` 方法获取已加入的社区列表。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchJoinedServers(20, cursor: cursor) { result, error in -} -``` - -#### 分页获取社区成员列表 - -社区成员可以调用 `fetchServerMembers` 方法分页获取指定社区中的成员列表,该列表包含社区创建者。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchServerMembers(serverId, limit: 20, cursor: cursor) { result, error in -} -``` - -### 管理社区成员 - -#### 加入社区 - -每个用户最多可加入 100 个社区,超过需要联系商务。用户可以通过以下两种方式加入社区: - -1. [搜索公开社区获得社区 ID](#搜索公开社区),主动申请加入该社区。 - -2. 社区内成员邀请用户加入。 - -公开社区支持申请加入和邀请加入,而私密社区仅支持邀请加入。通过邀请加入社区,详见 [创建社区](#创建社区)。 - -下面介绍用户如何申请加入公开社区。 - -1. 用户 [搜索公开社区获得社区 ID](#搜索公开社区)。 - -2. 用户调用 `joinServer` 方法加入社区。加入成功后,社区内其他成员会收到 `EMCircleManagerServerDelegate#onMemberJoinedServer` 事件。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.joinServer(serverId) { server, error in -} -``` - -#### 退出社区 - -社区成员若退出社区,则会退出该社区下的所有频道。社区所有者不支持退出社区操作,只能解散社区。 - -退出社区分为主动退出和被动退出,被动退出即成员被社区所有者或管理员移出社区。 - -#### 用户主动退出社区 - -用户可调用 `leaveServer` 方法退出社区。退出成功后,社区内其他成员会收到 `EMCircleManagerServerDelegate#onMemberLeftServer` 事件。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.leaveServer(serverId) { error in -} -``` - -#### 用户被移出社区 - -社区所有者和管理员调用 `removeUserFromServer` 方法将普通成员移出社区,管理员只能被社区所有者移出社区。被移出社区的成员、社区所有者和管理员(除操作者外)会收到 `EMCircleManagerServerDelegate#onMemberRemovedFromServer` 事件。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.removeUser(fromServer: serverId, userId: userId) { error in -} -``` - -#### 查询当前用户是否在社区内 - -用户可调用 `checkSelfIsInServer` 方法查询自己是否已经加入了指定社区。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.checkSelfIs(inServer: serverId) { isIn, error in -} -``` - -#### 查询当前用户的社区角色 - -用户可调用 `fetchSelfServerRole` 方法查询当前用户在社区中的角色。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.fetchSelfServerRole(serverId) { role, error in -} -``` - -#### 设置社区管理员 - -仅社区所有者可以调用 `addModeratorToServer` 方法设置社区管理员。成功设置后,社区所有成员(除社区所有者外)会收到 `EMCircleManagerServerDelegate#onServerRoleAssigned` 事件。 - -社区管理员除了不能创建和解散社区等少数权限外,拥有对社区的绝大部分权限。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.addModerator(toServer: serverId, userId: userId) { error in -} -``` - -#### 移除社区管理员 - -仅社区所有者可以调用 `removeModeratorFromServer` 方法移除社区管理员。成功移除后,社区所有成员(除社区所有者外)会收到 `EMCircleManagerServerDelegate#onServerRoleAssigned` 事件。 - -社区管理员被移除管理员权限后,将只拥有社区普通成员的权限。 - -示例代码如下: - -```swift -EMClient.shared().circleManager?.removeModerator(fromServer: serverId, userId: userId) { error in -} -``` - -### 监听社区事件 - -`IEMCircleManager` 中提供社区事件的监听接口。开发者可以通过设置此监听,获取社区中的事件,并做出相应处理。如果不再使用该监听,需要移除,防止出现内存泄漏。 - -```swift -//添加社区回调代理。 -EMClient.shared().circleManager?.add(serverDelegate: self, queue: nil) -//移除社区回调代理。 -EMClient.shared().circleManager?.remove(serverDelegate: self) -``` - -```swift -//社区信息更新。社区所有成员(除操作者外)会收到该事件。 -func onServerUpdated(_ event: EMCircleServerEvent) { - -} -//社区被解散。社区所有成员(除社区所有者外)会收到该事件。 -func onServerDestroyed(_ serverId: String, initiator: String) { - -} -//用户收到社区加入邀请。受邀用户会收到该事件。 -func onReceiveServerInvitation(_ event: EMCircleServerEvent, inviter: String) { - -} -//用户同意社区加入邀请。邀请人会收到该事件。 -func onServerInvitationBeAccepted(_ serverId: String, invitee: String) { - -} -//用户拒绝社区加入邀请。邀请人会收到该事件。 -func onServerInvitationBeDeclined(_ serverId: String, invitee: String) { - -} -//社区成员的角色发生变化。社区所有成员(除操作者外)会收到该事件。 -func onServerRoleAssigned(_ serverId: String, member: String, role: EMCircleUserRole) { - -} -//有用户加入社区。社区所有成员(除加入社区的新成员外)会收到该事件。 -func onMemberJoinedServer(_ serverId: String, member: String) { - -} -//有成员主动退出社区。社区所有者和管理员会收到该事件。 -func onMemberLeftServer(_ serverId: String, member: String) { - -} -//有成员被移出社区。被移出者、社区所有者和管理员(除操作者外)会收到该事件。 -func onMemberRemoved(fromServer serverId: String, members: [String]) { - -} -``` diff --git a/docs/product/circle/server_mgmt_rest.md b/docs/product/circle/server_mgmt_rest.md deleted file mode 100644 index 1669603d..00000000 --- a/docs/product/circle/server_mgmt_rest.md +++ /dev/null @@ -1,1354 +0,0 @@ -# 管理社区及其成员 - - - -社区(Server)是一群有着共同兴趣爱好的人的专属天地,也可以是同学朋友的社交圈子。社区是环信圈子三层基础架构的最上层,各种消息事件均发生在社区内。社区分为公开社区和私密社区。用户可查询公开社区列表,但无法查询私密社区列表。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者调用 RESTful API 解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](https://docs-im.easemob.com/ccim/circle/rest/channelapi#查询指定频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](https://docs-im.easemob.com/ccim/circle/rest/serverapi#删除社区)和[删除频道](https://docs-im.easemob.com/ccim/circle/rest/channelapi#删除频道)等 API。** - -## 前提条件 - -要调用环信即时通讯 RESTful API,请确保满足以下要求: - -- 已在环信即时通讯控制台 [开通配置环信即时通讯 IM 服务](http://doc.easemob.com/document/server-side/enable_and_configure_IM.html)。 -- 了解环信 IM RESTful API 的调用频率限制,详见 [接口频率限制](http://doc.easemob.com/product/limitationapi.html)。 - -## 公共参数 - -### 请求参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :----------------------------------------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见[获取环信即时通讯 IM 的信息](http://doc.easemob.com/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见[获取环信即时通讯 IM 的信息](http://doc.easemob.com/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见[获取环信即时通讯 IM 的信息](http://doc.easemob.com/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `server_id` | String | 是 | 社区 ID。 | -| `channel_id` | String | 是 | 频道 ID。 | -| `user_id` | String | 是 | 用户 ID。 | -| `role` | Int | 是 | 用户的角色:
- `0`:社区所有者;
- `1`:社区管理员;
- `2`:社区的普通成员。 | - -:::tip -对于分页获取数据列表,若查询参数中的 `limit` 和 `cursor` 均未设置,则服务器返回首页的数据列表。 -::: - -### 响应参数 - -| 参数 | 类型 | 描述 | -| :-----------------| :----- | :----------------------------------------------------------- | -| `name` | String | 社区名称。 | -| `owner` | String | 社区的所有者。 | -| `type` | Int | 社区的类型:
- `0`:公开社区;
- `1`:私密社区。 | -| `description` | String | 社区描述。 | -| `custom` | String | 社区的扩展信息。 | -| `icon_url` | String | 社区头像的 URL。 | -| `background_url` | String | 社区背景的 URL。 | -| `server_tag_id` | String | 社区标签 ID。 | -| `tag_name` | String | 社区标签名称。 | -| `tag_count` | Int | 社区标签数量。 | -| `server_id` | String | 社区 ID。 | -| `default_channel_id` | String | 社区的默认频道的 ID。 | -| `user_id` | String | 环信用户 ID。 | -| `role` | Int | 社区成员的角色:
- `0`:社区所有者;
- `1`:社区管理员;
- `2`:社区的普通成员。 | -| `created` | Long | 社区的创建时间,Unix 时间戳,单位为毫秒。 | - -## 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段: - -Authorization:`Bearer ${YourAppToken}` - -为提高项目的安全性,环信使用 App Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 需使用 App Token 的鉴权方式,详见 [使用环信 App Token 鉴权](http://doc.easemob.com/product/easemob_app_token.html)。 - -### 查询环信超级社区用户是否存在 - -查询环信超级社区用户是否存在。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name_}/{app_name}/circle/user/{user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :------ | :------------------------------------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `result` | Boolean | 查询结果:
- `true`:用户存在;
- `false`:用户不存在。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/user/{user_id}' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "result" : true -} -``` - -### 获取 App 下的社区列表 - -查询 App 下的社区列表,包括公开和私密社区。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/list/by-app?limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------- | :----- | :------- | :----------------------------------------------------------- | -| `limit` | Int | 否 | 每页获取的社区数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页查询时设置。 | -| `cursor` | String | 否 | 游标,指定数据查询的开始位置。该参数仅在分页查询时设置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------- | :----- | :----------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的社区数量。 | -| `servers` | List | 获取到的社区详情。 | -| `cursor` | String | 游标,下次数据查询的起始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/channelapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/list/by-app?limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "servers": [ - { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -## 创建和管理社区 - -### 创建社区 - -社区分为公开社区和私密社区。每个用户最多可以创建 100 个社区。 - -创建社区时,需设置社区名称、社区类型、社区头像的 URL、社区描述、社区背景 URL 和社区扩展信息。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/server -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :---------- | :----- | :------- | :----------------------------------------------------------- | -| `owner` | String | 是 | 社区创建者(即社区所有者)的用户 ID,长度不能超过 64 字节。 | -| `name` | String | 是 | 社区名称,长度不能超过 50 个字符。 | -| `type` | Int | 否 | 社区的类型:
- (默认)`0`:公开社区;
- `1`:私密社区。 | -| `icon_url` | String | 否 | 社区头像的 URL,长度不能超过 500 个字符。 | -| `background_url` | String | 否 | 社区背景的 URL,长度不能超过 500 个字符。 | -| `description` | String | 否 | 社区描述,长度不能超过 500 个字符。 | -| `default_channel_category_name` | String | 否 | 默认频道分组的名称。如果不指定,该频道分组的名称默认为 `文字频道`。 | -| `default_channel_name` | String | 否 | 默认频道的名称。如果不指定,该频道的名称默认为 `通用`。 | -| `custom` | String | 否 | 社区的扩展信息,例如,你可以给社区添加业务相关的标记,长度不能超过 500 个字符。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------- | :----- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `server_id` | String | 社区 ID。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server' -d '{ - "owner" : "user1", - "name" : "server", - "type" : 0, - "icon_url" : "http://circle.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "description" : "community", - "default_channel_category_name" : "category0", - "default_channel_name" : "channel0", - "custom" : "custom" -}' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "server_id": "19VM9oPBasxxxxxx0tvWViEsdM" -} -``` - -### 修改社区信息 - -修改指定社区的信息。你可以修改社区名称、社区头像的 URL、社区描述和社区的扩展信息。 - -#### HTTP 请求 - -```http -PUT https://{host}/{org_name}/{app_name}/circle/server/{server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 备注 | -| :---------- | :----- | :------- | :----------------------------------------------------------- | -| `name` | String | 否 | 社区名称,长度不能超过 50 个字符。 | -| `type` | Int | 否 | 社区类型:
- `0`:公开社区;
- `1`:私密社区。 | -| `icon_url` | String | 否 | 社区头像的 URL,长度不能超过 500 个字符。 | -| `background_url` | String | 否 | 社区背景的 URL,长度不能超过 500 个字符。 | -| `description` | String | 否 | 社区描述,长度不能超过 500 个字符。 | -| `custom` | String | 否 | 社区的扩展信息,例如,可以给社区添加业务相关的标记,长度不能超过 500 个字符。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `server` | List | 社区数据。 | -| `tags` | List | 社区标签数据。 | - -其他字段及描述详见 [公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX' -d '{ - "name" : "easemob", - "icon_url" : "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "description" : "community", - "custom" : ""custom" -}' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "server": { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "tags": [ - { - "server_tag_id": "1", - "tag_name": "社交" - } - ], - "tag_count": 1, - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } -} -``` - -### 为指定社区添加标签 - -每个社区最多可以添加 10 个标签。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/server/{server_id}/tag/add -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :--- | :------- | :----------------------------------------------------------- | -| `tags` | List | 是 | 为社区添加标签的数组,最多可以添加 10 个标签,每个标签的长度不能超过 20 个字符。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `tags` | List | 社区标签数据。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/tag/add' -d '{ - "tags": ["社交"] -}' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "tags": [ - { - "server_tag_id": "1", - "tag_name": "社交" - } - ] -} -``` - -### 获取社区标签 - -获取指定社区的标签。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/{server_id}/tag -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 社区标签数量。 | -| `tags` | List | 社区标签数据。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/tag' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "tags": [ - { - "server_tag_id": "78", - "tag_name": "uur2" - } - ] -} -``` - -### 移除指定社区的标签 - -根据标签的 ID 移除标签,不能使用标签名进行移除。移除标签之前,你可以通过[获取社区详情](https://docs-im.easemob.com/ccim/circle/rest/serverapi#获取指定社区的详情)获取标签 ID。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/server/{server_id}/tag/remove -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -##### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :----- | :--- | :------- | :----------------------------------------------------------- | -| `tagIds` | List | 是 | 要移除的社区标签 ID 的数组,一次移除的标签不能超过 10 个。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/tag/remove' -d '{ - "tagIds" : ["1", "2"] -}' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -### 搜索公共社区 - -你可以根据社区名称或者标签名称搜索公共社区。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/search/{name}?type=0&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `name` | String | 是 | 社区名称或社区标签名称。社区名称不能超过 50 个字符,标签名称不能超过 20 个字符。
- 根据社区名称搜索,支持基于通过社区全名搜索和模糊搜索分页获取数据。若使用模糊搜索,你需要传入社区名称中最左侧的单个字或词汇,或包含该字或词汇的关键字,例如社区名称为 `足球社区01`,传入 `足` 或 `足球` 都可搜索出该社区,而使用 `球` 或 `社区01` 则搜索不到该社区。
- 若根据标签名称搜索,需传入完整的标签名称,不支持模糊搜索。| - -其他参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :----- | :------- | :----------------------------------------------------------- | -| `type` | Int | 否 | 搜索类型:
- (默认)`0`:根据社区名称分页获取社区列表。这种情况下,需将路径参数中的 `name` 设置为社区名称并设置 `limit` 和 `cursor`;
- `1`:根据标签名称获取社区列表,直接获取带有该标签的所有社区。这种情况下,需将路径参数中的 `name` 设置为社区标签名称,而无需设置 `limit` 和 `cursor`。 | -| `limit` | Int | 否 | 每页获取的社区数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。| -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :--------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `servers` | List | 获取的社区详情。 | -| `count` | Int | 获取的社区数量。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/search/XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "servers": [ - { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } - ] -} -``` - -### 获取指定社区的详情 - -获取指定社区的详情。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/{server_id}/by-id -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `server` | List | 社区的详情。 | -| `tags` | List | 社区标签数据。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/by-id' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "server": { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "tags": [ - { - "server_tag_id": "1", - "tag_name": "社交" - } - ], - "tag_count": 1, - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } -} -``` - -### 获取推荐的社区的详情 - -目前,该方法返回最新创建的 5 个社区的详情。若社区数量少于 5 个,则返回实际的社区数量。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/recommend/list -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `servers` | List | 推荐的社区的详情。 | -| `tags` | List | 推荐的社区的标签数据。 | -| `count` | Int | 推荐的社区的数量。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/recommend/list' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "servers": [ - { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "tags": [ - { - "server_tag_id": "1", - "tag_name": "社交" - } - ], - "tag_count": 1, - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } - ] -} -``` - -### 获取当前用户加入的社区的详情 - -分页获取当前用户加入的社区的详情。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/list?userId={user_id}&limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :---- | :------- | :--------------- |:--------------- | -| `user_id` | String | 是 | 用户 ID。| -| `limit` | Int | 否 | 每页获取的社区数量。取值范围为 [1,20],默认值为 `20`。 | -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------ | :--- | :--------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的社区数量。 | -| `servers` | List | 获取到的社区详情。 | -| `tags` | List | 用户加入的社区的标签数据。 | -| `cursor` | String | 游标,下次数据查询的起始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/list?userId=XXX&limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "servers": [ - { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "tags": [ - { - "server_tag_id": "1", - "tag_name": "社交" - } - ], - "tag_count": 1, - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 删除社区 - -删除指定的社区。删除社区后,该社区中的频道分组和频道也将被删除。 - -#### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/circle/server/{server_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -## 管理社区成员 - -### 获取社区成员列表 - -分页获取社区成员列表。 - -#### HTTP 请求 - -```shell -GET https://{host}/{org_name}/{app_name}/circle/server/{server_id}/users?limit={limit}&cursor={cursor} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :---- | :------- | :--------------------------------- |:------------------ | -| `limit` | Int | 否 | 每页获取的社区成员数量。取值范围为 [1,20],默认值为 `20`。该参数仅在分页获取时为必需。 | -| `cursor` | String | 否 | 游标,指定数据查询的起始位置。该参数仅在分页获取时为必需。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---- | :--- | :------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `count` | Int | 获取到的社区成员数量。 | -| `users` | List | 获取到的社区成员详情。 | -| `cursor` | String | 游标,下次数据查询的起始位置。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/users?limit=1&cursor=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "count": 1, - "users": [ - { - "user_id" : "user1", - "role" : 0 - } - ], - "cursor": "ZGNiMjRmNGY1YjczYjlhYTNkYjk1MDY2YmEyNzFmODQ6aXXXXXXXXXXXXXX" -} -``` - -### 获取社区内的成员总数 - -查询社区内的成员总数。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/{server_id}/users/count -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---------- | :--- | :------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `users_count` | Long | 社区内成员总数。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/users/count' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "users_count" : 10 -} -``` - -### 将用户加入社区 - -将单个用户加入社区,每个用户最多可加入 100 个社区。 - -用户加入社区时会自动加入社区的默认频道。默认情况下,社区的默认频道最多可包含 2000 个用户。若达到该阈值,则用户加入社区失败。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/server/{server_id}/join?userId={user_id}&isJoinDefaultChannel={true/false} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :-------------------- | -| `user_id` | String | 是 | 用户 ID。 | -| `isJoinDefaultChannel` | Boolean | 否 | 是否加入社区的默认频道:
- (默认)`true`:加入默认频道; - `false`:不加入社区下的任何频道。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :-------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | -| `server` | List | 用户加入的社区的详情。 | -| `tags` | List | 用户加入的社区的标签数据。 | - -其他字段及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/join?userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "server": { - "name": "server", - "owner": "user1", - "type": 0, - "description": "community", - "custom": "custom", - "tags": [ - { - "server_tag_id": "1", - "tag_name": "社交" - } - ], - "tag_count": 1, - "created": 1658126097514, - "server_id": "19SW5Q85jHxxxxx6T5kexvn", - "icon_url": "http://discord.oss/19b1d7b0-7079-11e9-9bd8-25c5e81b42a1", - "background_url" : "http://circle.oss/89c2e7p8-8794-3u4k-80n5-56m9e8c28b29", - "default_channel_id": "187xxxx09" - } -} -``` - -### 查询用户是否在社区内 - -查询用户是否在社区内。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/{server_id}/user/{user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :------ | :----------------------------------------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | -| `result` | Boolean | 查询结果:
- `true`:用户在社区中;
- `false`:用户不在社区中。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](https://docs-im.easemob.com/ccim/rest/errorcode)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X GET -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/user/XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "result": true -} -``` - -### 查询指定成员在社区内的角色 - -查询指定成员在社区内的角色。 - -#### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/circle/server/{server_id}/user/role?userId={user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :----- | :----- | :------- | -------- | -| `user_id` | String | 用户 ID。 | 是 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :----------------------------------------------------------- | -| `code` | Int | 环信超级社区的服务状态码。 | - -其他字段及描述详见 [公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/user/role?userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200, - "role" : 1 -} -``` - -### 修改社区中指定成员的角色 - -修改社区中指定成员的角色。 - -#### HTTP 请求 - -```http -PUT https://{host}/{org_name}/{app_name}/circle/server/{server_id}/user/role?userId={user_id}&role={role} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--- | :--- | :--------------- | :--------------- | -| `user_id` | String | 是 | 用户 ID。 | -| `role` | Int | 是 | 要修改的成员角色,只能传以下值:
- `1`:表示社区管理员;
- `2`:表示普通成员。
若传 `0`(表示社区所有者)或其他无效值时会报错。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourApp Token}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X PUT -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/user/role?userId=XXX&role=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` - -### 将成员移出社区 - -将指定成员移出社区。一旦成员被移出社区,该成员会自动被移出该社区下的所有频道。 - -#### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/circle/server/{server_id}/user/remove?userId={user_id} -``` - -##### 路径参数 - -参数及描述详见[公共参数](https://docs-im.easemob.com/ccim/circle/rest/serverapi#公共参数)。 - -##### 查询参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :---------------------- | -| `user_id` | String | 是 | 用户 ID。 | - -##### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------ | :----- | :------- | :----------------------------------------------------------- | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization` | String | 是 | 该管理员的鉴权 App Token,格式为 `Bearer ${YourAppToken}`,其中 `Bearer` 是固定字符,后面加英文空格,再加获取到的 App Token 值。 | - -#### HTTP 响应 - -##### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--- | :--- | :------------------ | -| `code` | Int | 环信超级社区的服务状态码。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考[响应状态码](http://doc.easemob.com/document/server-side/error.html)了解可能的原因。 - -#### 示例 - -##### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST -H 'Accept: application/json' -H 'Authorization: Bearer ' 'http://XXX/XXX/XXX/circle/server/XXX/user/remove?userId=XXX' -``` - -##### 响应示例 - -```json -{ - "code": 200 -} -``` \ No newline at end of file diff --git a/docs/product/circle/server_mgmt_web.md b/docs/product/circle/server_mgmt_web.md deleted file mode 100644 index 6d5bc5e4..00000000 --- a/docs/product/circle/server_mgmt_web.md +++ /dev/null @@ -1,393 +0,0 @@ -# 管理社区 - - - -社区(Server)是一群有着共同兴趣爱好的人的专属天地,也可以是同学朋友的社交圈子。社区是环信圈子三层基础架构的最上层,各种消息事件均发生在社区内。社区分为公开社区和私密社区。对于公开社区,任何用户均可查询社区列表,可自由加入或退出社区,无需审批;对于私密社区,用户无法查询社区列表,只能通过社区成员邀请加入社区,无法申请加入社区。 - -**超级社区中的频道基于即时通讯 IM 的群组或聊天室(频道 ID 为群组 ID 或聊天室 ID)创建,解散群组或聊天室时需注意以下几点:** - -**1. 在环信控制台或者通过客户端解散群组或聊天室、群组或聊天室加人、踢人等操作时请谨慎操作,需确保操作的群组或者聊天室不是超级社区使用的。** -**2. 如果将超级社区使用的频道对应的群组或者聊天室删除,会出现数据不一致情况,导致用户加入不了社区、频道、在频道内发不了消息等情况发生。** -**3. 在清理群组或者聊天室数据时,需先确认要删除的群组 ID 或聊天室 ID 与超级社区的频道 ID 是否一致。你可以调用[获取频道详情 API](channel_mgmt_web.html#获取频道详情) 确认要删除的群组或聊天室是否为超级社区的频道。如果是,请不要进行删除。** -**4. 如果需要清理超级社区数据,调用[删除社区](#解散社区)和[删除频道](channel_mgmt_web.html#解散频道)等 API。** - -## 技术原理 - -环信 Circle Android SDK 支持你通过调用 API 实现如下功能: - -- 创建和管理社区; -- 管理社区成员; -- 监听社区事件。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成环信即时通讯 IM Web Circle SDK 的初始化。Circle SDK 初始化与 IM SDK 相同,详见 [IM SDK 初始化](/document/web/initialization.html)。 -- 了解环信即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 -- 了解 Circle 的使用限制,详见 [使用限制](circle_overview.html#限制条件)。 - -## 实现方法 - -### 创建和管理社区 - -#### 创建社区 - -社区分为公开社区和私密社区。每个用户最多可以创建 100 个社区。若要提升上限,请联系商务。 - -1. 调用 `createServer` 方法创建社区。 - -示例代码如下: - -```javascript - let options = { - name: 'server name', - icon: 'image url', - description: 'a test server', - ext: '', - isPublic: true, - backgroundUrl: '', -} -WebIM.conn.createServer(options).then(res => { - console.log(res) -}) -``` - -创建社区时,需设置以下参数,如下表所示。 - -| 参数 | 类型 | 描述 |是否必需 | -| :--------- | :----------------------- | :------------------ | :------------------ | -| name | String | 社区名称,不能超过 50 个字符。 |是| -| icon | String | 社区头像 URL,不能超过 500 个字符。 |否| -| description | String | 社区描述,不能超过 500 个字符。 |否| -| ext | String | 社区自定义扩展字段,不能超过 500 个字符。 |否| -| isPublic | Boolean | 是否为公开社区:
- (默认)`true`:公开社区;
- `false`:私密社区。 |否| -| backgroundUrl | String | 社区背景 URL,不能超过 500 个字符。 |否| - -2. 邀请用户加入社区。 - -社区成员调用 `inviteUserToServer` 方法邀请用户加入社区。受邀用户会收到 `onServerEvent` 回调,事件为 `inviteToJoin`。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - userId: 'userId', - message: 'welcome', -} -WebIM.conn.inviteUserToServer(options).then(res => { - console.log(res) -}) -``` - -3. 用户确认是否加入社区。 - - - 若同意加入社区,调用 `acceptServerInvite` 方法。邀请人收到 `onServerEvent` 回调,事件为 `acceptInvite`。社区内所有成员(不包括加入社区的该新成员)会收到 `onMemberJoinedServer` 事件。示例代码如下: - - 示例代码如下: - - ```javascript - let options = { - serverId: 'serverId', - inviter: 'userId', - } - WebIM.conn.acceptServerInvite(options).then(res => { - console.log(res) - }) - ``` - - - 若拒绝加入社区,调用 `rejectServerInvite` 方法。邀请人收到 `onServerEvent` 回调,事件为 `refuseInvite`。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - inviter: 'userId', -} -WebIM.conn.rejectServerInvite(options).then(res => { - console.log(res) -}) -``` - -#### 修改社区信息 - -社区所有者和管理员可调用 `updateServer` 方法修改社区基本信息,包括社区名称、类型、描述、头像 URL、背景 URL 和自定义扩展信息。社区信息修改后,社区的所有成员(除操作者外)会收到 `onServerEvent` 回调,事件为 `update`。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - name: 'new name', - icon: 'image url', - description: 'a test server', - ext: '', - isPublic: true, - backgroundUrl: '', -} -WebIM.conn.updateServer(options).then(res => { - console.log(res) -}) -``` - -#### 解散社区 - -仅社区所有者可调用 `destroyServer` 方法解散社区。社区解散后,除社区所有者外的社区所有成员会收到 `onServerEvent` 回调,事件为 `destroy`,并被移出社区。 - -示例代码如下: - -```javascript -WebIM.conn.destroyServer({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` - -#### 添加社区标签 - -社区所有者和管理员可以调用 `addServerTags` 方法为社区添加标签。非社区内用户可以通过搜索标签全名查找社区。每个社区最多可添加 10 个标签。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - tags: ['学习', '体育'], -} -WebIM.conn.addServerTags(options).then(res => { - console.log(res) -}) -``` - -#### 移除社区标签 - -社区所有者和管理员可以调用 `removeServerTags` 方法移除社区已有标签。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', - tags: ['tagId', 'tagId'], -} -WebIM.conn.removeServerTags(options).then(res => { - console.log(res) -}) -``` - -#### 获取社区标签列表 - -社区成员可调用 `getServerTags` 方法获取社区的标签列表。 - -示例代码如下: - -```javascript -let options = { - serverId: 'serverId', -} -WebIM.conn.getServerTags(options).then(res => { - console.log(res) -}) -``` - -#### 搜索公开社区 - -社区成员可以调用 `getServers` 方法按查询类型搜索公开社区,即按社区名称或社区标签名称查询。 - - 根据社区名称搜索,支持基于通过社区全名搜索和模糊搜索分页获取数据。若使用模糊搜索,你需要传入社区名称中最左侧的单个字或词汇,或包含该字或词汇的关键字。例如社区名称为 `足球社区01`,传入 `足`或 `足球` 都可搜索出该社区,而使用 `球` 或 `社区01` 则搜索不到该社区。 - - 若根据标签名称搜索,需传入完整的标签名称,不支持模糊搜索。该类型查询直接获取带有该标签的所有社区,不支持分页查询。 - -示例代码如下: - -```javascript -WebIM.conn.getServers({keyword: 'keyword',type:'serverName'}).then(res => { - console.log(res) -}) -``` - -#### 获取社区详情 - -社区成员可以调用 `getServerDetail` 方法获取社区的详情。 - -示例代码如下: - -```javascript -WebIM.conn.getServerDetail({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` - -#### 获取已加入社区 - -社区成员可以调用 `getJoinedServers` 方法获取已加入的社区列表。 - -示例代码如下: - -```javascript -WebIM.conn.getJoinedServers({pageSize: '10',cursor: ''}).then(res => { - console.log(res) -}) -``` - -#### 分页获取社区成员列表 - -社区成员可以调用 `getServerMembers` 方法分页获取指定社区中的成员列表,该列表包含社区创建者。 - -示例代码如下: - -```javascript -WebIM.conn.getServerMembers({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` - -### 管理社区成员 - -#### 加入社区 - -每个用户最多可加入 100 个社区,超过需要联系商务。用户可以通过以下两种方式加入社区: - -1. [搜索公开社区获得社区 ID](#搜索公开社区),主动申请加入该社区。 - -2. 社区内成员邀请用户加入。 - -公开社区支持申请加入和邀请加入,而私密社区仅支持邀请加入。通过邀请加入社区,详见 [创建社区](#创建社区)。 - -下面介绍用户如何申请加入公开社区。 - -1. 用户[搜索公开社区获得社区 ID](#搜索公开社区)。 - -2. 用户调用 `joinServer` 方法加入社区。加入成功后,社区内其他成员收到 `onServerEvent` 回调,事件为 `memberPresence`。 - -示例代码如下: - -```javascript -WebIM.conn.joinServer({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` - -#### 退出社区 - -社区成员若退出社区,则会退出该社区下的所有频道。社区所有者不支持退出社区操作,只能解散社区。 - -退出社区分为主动退出和被动退出,被动退出即成员被社区所有者或管理员移出社区。 - -#### 用户主动退出社区 - -用户可调用 `leaveServer` 方法退出社区。退出成功后,社区内其他成员会收到 `onServerEvent` 回调,事件为 `memberAbsence`。 - -示例代码如下: - -```javascript -WebIM.conn.leaveServer({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` -#### 用户被移出社区 - -社区所有者和管理员调用 `removeServerMember` 方法将普通成员移出社区,管理员只能被社区所有者移出社区。被移出社区的成员、社区所有者和管理员(除操作者外)会收到 `onServerEvent` 回调,事件为 `removed`。 - -示例代码如下: - -```javascript -WebIM.conn.removeServerMember({serverId: 'serverId',userId:'userId'}).then(res => { - console.log(res) -}) -``` - -#### 查询当前用户是否在社区内 - -用户可调用 `isInServer` 方法查询自己是否已经加入了指定社区。 - -示例代码如下: - -```javascript -WebIM.conn.isInServer({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` -#### 查询当前用户的社区角色 - -用户可调用 `getServerRole` 查询当前用户在社区中的角色。 - -示例代码如下: - -```javascript -WebIM.conn.getServerRole({serverId: 'serverId'}).then(res => { - console.log(res) -}) -``` - -#### 设置社区管理员 - -仅社区所有者可以调用 `setServerAdmin` 方法设置社区管理员。成功设置后,社区所有成员(除社区所有者外)收到 `onServerEvent` 回调,事件为 `updateRole`。 - -社区管理员除了不能创建和解散社区等少数权限外,拥有对社区的绝大部分权限。 - -示例代码如下: - -```javascript -WebIM.conn.setServerAdmin({serverId: 'serverId',userId:'userId'}).then(res => { - console.log(res) -}) -``` - -#### 移除社区管理员 - -仅社区所有者可以调用 `removeServerAdmin` 方法移除社区管理员。成功移除后,社区所有成员(除社区所有者外)会收到 `onServerEvent` 回调,事件为 `updateRole`。 - -若社区管理员被移除管理员权限后,将只拥有社区普通成员的权限。 - -示例代码如下: - -```javascript -WebIM.conn.removeServerAdmin({serverId: 'serverId',userId:'userId'}).then(res => { - console.log(res) -}) -``` - -### 监听社区事件 - -Circle 提供 `addEventHandler` 方法用于注册监听事件。开发者可以通过设置此监听,获取频道分组中的事件。 - -```javascript -WebIM.conn.addEventHandler('CIRCLE',{ - onServerEvent:(msg) => { - switch (msg.operation){ - case "create": - //创建社区。 - break; - case "update": - //社区信息更新。社区所有成员(除操作者外)会收到该事件。 - break; - case "destroy": - //社区被解散。社区所有成员(除社区所有者外)会收到该事件。 - break; - case "memberPresence": - //有用户加入社区。社区所有成员(除加入社区的新成员外)会收到该事件。 - break; - case "memberAbsence": - //有成员主动退出社区。社区所有者、管理员会收到该事件。 - break; - case "inviteToJoin": - //用户收到社区加入邀请。受邀用户会收到该事件。 - break; - case "acceptInvite": - //用户同意社区加入邀请。邀请人会收到该事件。 - break; - case "refuseInvite": - //用户拒绝社区加入邀请。邀请人会收到该事件。 - break; - case "removed": - //有成员被移出社区。被移出者、社区所有者和管理员(除操作者外)会收到该事件。 - break; - case "updateRole": - //社区成员的角色发生变化。社区所有成员(除操作者外)会收到该事件。 - break; - default: - break; - } - }, -}); -``` \ No newline at end of file diff --git a/docs/product/data_center.md b/docs/product/data_center.md deleted file mode 100644 index 653b66c1..00000000 --- a/docs/product/data_center.md +++ /dev/null @@ -1,121 +0,0 @@ -# 数据中心和加速节点 - -针对客户不同的业务覆盖区域,环信为客户提供了多地数据中心和加速节点的选择。目前环信支持的国内、国外数据中心: - -| 类型 | 名称 | -| :--------- | :----- | -| 国内数据中心 | 国内 1 区、国内 2 区、国内 VIP 区 | -| 海外数据中心 | 新加坡 1 区、新加坡 2 区、美东 1 区、德国 2 区 | - -目前支持的海外加速节点: - -| 类型 | 名称 | -| :--------- | :----- | -| 海外加速节点 | 全球 | - -## 数据中心说明 - -| 名称 | 用途 | -| :--------- | :----- | -| 国内 1 区、国内 2 区 | 环信 IM 社区版、企业版、旗舰版、免费版和专业版客户所在集群 | -| 国内 VIP 区 | 尊享版客户、单独购买 VIP 集群服务客户所在集群 | -| 新加坡 1 区、新加坡 2 区 | 环信海外客户所在集群 | -| 美东 1 区 | 环信海外客户所在集群 | -| 德国 2 区 | 环信海外客户所在集群 | - -应用所在数据中心可以在环信用户管理后台的**即时通讯>服务概览**页面中查看: - -![img](/images/product/data_center.png) - -## 国内数据中心 - -### 应用场景 - -绝大部分终端用户均在国内的应用。 - -### 集成说明 - -移动端 SDK 默认连接国内数据中心,目前采取的策略是随机分配用户到国内 1 区、国内 2 区,2 个集群服务没有区别。Web 端和桌面端 SDK 集成需要根据所在数据中心,填写配置对应的 webSocket 地址。 - -| 数据中心名称 | socket3.0 地址 | socket2.0(老版本)地址 | -| :--------- | :----- | :----- | -| 国内 1 区 | im-api-v2.easemob.com 或 im-api-v2.easecdn.com | im-api.easemob.com 或 im-api.easecdn.com | -| 国内 2 区 | im-api-v2-31.easemob.com 或 im-api-v2-31.easecdn.com | im-api-31.easemob.com 或 im-api-31.easecdn.com | -| 国内 VIP 区 | 请咨询你的商务经理 | | - -不同数据中心 RESTful 接口调用不同,具体地址如下: - -| 数据中心名称 | RESTful API 请求地址 | -| :--------- | :----- | -| 国内 1 区 | a1.easemob.com 或 a1.easecdn.com | -| 国内 2 区 | a31.easemob.com 或 a31.easecdn.com | -| 国内 VIP 区 | 请咨询你的商务经理 | - -不同数据中心微信小程序、支付宝小程序的具体地址如下: - -| 数据中心名称 | 微信小程序 | 支付宝小程序 | -| :--------- | :----- | :----- | -| 国内 1 区 | im-api-wechat.easemob.com 或 im-api-wechat.easecdn.com | im-api-alipay.easemob.com 或 im-api-alipay.easecdn.com | -| 国内 2 区 | im-api-wechat-31.easemob.com 或 im-api-wechat-31.easecdn.com | im-api-alipay-31.easemob.com 或 im-api-alipay-31.easecdn.com | -| 国内 VIP 区 | 请咨询你的商务经理 | 请咨询你的商务经理 | - -### 国内集群迁移到海外 - -请查看[平滑迁移文档](/product/solution_common/migrate_to_easemob.html)。 - -## 海外数据中心 - -### 应用场景 - -绝大部分终端用户均在国外的应用。 - -### 集成说明 - -移动端SDK配置海外集群 App Key 后,会自动连接到对应的海外集群。Web 端和桌面端 SDK集成需要填写配置对应的 webSocket 地址。 - -| 集群名称 | WebSocket 地址 | -| :--------- | :----- | -| 新加坡 1 区 | im-api-sgp-v2.easemob.com 或 im-api-sgp-v2.easecdn.com | -| 新加坡 2 区 | msync-api-61.easemob.com 或 msync-api-61.easecdn.com | -| 美东 1 区 | msync-api-41.easemob.com 或 msync-api-41.easecdn.com | -| 德国 2 区 | msync-api-71.easemob.com 或 msync-api-71.easecdn.com | - -不同数据中心 RESTful 接口调用不同,RESTful 接口调用具体地址如下: - -| 集群名称 | RESTful API请求地址 | -| :--------- | :----- | -| 新加坡 1 区 | a1-sgp.easemob.com 或 a1-sgp.easecdn.com | -| 新加坡 2 区 | a61.easemob.com 或 a61.easecdn.com | -| 美东 1 区 | a41.easemob.com 或 a41.easecdn.com | -| 德国 2 区 | a71.easemob.com 或 a71.easecdn.com | - -不同集群名称微信小程序的具体地址如下: - -| 集群名称 | 微信小程序 | -| :--------- | :----- | -| 新加坡 1 区 | im-api-wechat-sgp.easemob.com 或 im-api-wechat-sgp.easecdn.com | -| 新加坡 2 区 | im-api-wechat-61.easemob.com 或 im-api-wechat-61.easecdn.com | -| 美东 1 区 | im-api-wechat-41.easemob.com 或 im-api-wechat-41.easecdn.com | -| 德国 2 区 | im-api-wechat-71.easemob.com 或 im-api-wechat-71.easecdn.com | - -:::tip -根据海外数据隐私保护协议规定,选择新加坡 1 区、新加坡 2 区、美东 1 区、德国 2 区集群后不可迁移至其他集群。 -::: - -### 海外加速服务 - -#### 应用场景 - -一部分终端用户在国内、一部分终端用户在海外,跨国用户之间需要发消息沟通。 - -#### 使用说明 - -根据你所在的数据中心及终端用户分布,我们将为你开通需要的网络加速节点。加速节点默认带宽为 1 Mbps,可以根据实际流量需求配置合适的带宽。具体服务开通请联系你的商务经理。 - -#### 节点分布 - -| 名称 | 节点 | -| :--------- | :----- | -| 海外加速节点 | 全球 | - -节点价格请查看[价格页](https://www.easemob.com/pricing/im)。 \ No newline at end of file diff --git a/docs/product/demo_sourcecode_address.md b/docs/product/demo_sourcecode_address.md deleted file mode 100644 index 314fa9fb..00000000 --- a/docs/product/demo_sourcecode_address.md +++ /dev/null @@ -1,37 +0,0 @@ -# 各端 Demo 源码地址 - -## 体验 Demo - -我们提供 Android、iOS、Web、Flutter 和 React Native 平台的 Demo。 - -你可以点击[这里](https://www.easemob.com/download/demo)扫描二维码体验各端 Demo。 - -## Demo 源码地址 - -我们在 Github 提供了各端 Demo 源码地址供你查看和参考。 - -### Android - -- **新 Demo**:4.6.0 及之后版本的 Demo,为 Kotlin 语言。点击[这里](https://github.com/easemob/easemob-demo-android)查看 Demo 源码地址。 -- **老 Demo**:4.5.0 及之前版本的 Demo,为 Java 语言。点击[这里](https://github.com/easemob/chat-android)查看 Demo 源码地址。环信已不再维护该地址的 Demo 源码。 - -### iOS - -- **新 Demo**:4.6.0 及之后版本的 Demo,为 Swift 语言。点击[这里](https://github.com/easemob/easemob-demo-ios)查看 Demo 源码地址。 -- **老 Demo**:4.5.0 及之前版本的 Demo,为 Objective-C 语言。点击[这里](https://github.com/easemob/easemob-demo-ios/tree/OCDemo)查看 Demo 源码地址。环信已不再维护该地址的 Demo 源码。 - -### Web - -- Vue 2:点击[这里](https://github.com/easemob/webim-vue-demo/tree/dev-4.0)查看 Demo 源码地址。环信已不再维护该地址的 Demo 源码。 -- Vue 3:点击[这里](https://github.com/easemob/webim-vue-demo/tree/demo-vue3)查看 Demo 源码地址。 -- React:点击[这里](https://github.com/easemob/easemob-demo-react/tree/dev_4.0)查看 Demo 源码地址。 -- 微信小程序:点击[这里](https://github.com/easemob/webim-weixin-xcx)查看 Demo 源码地址。 -- uniapp:点击[这里](https://github.com/easemob/webim-uniapp-demo)查看 Demo 源码地址。 - -### Flutter - -点击[这里](https://github.com/easemob/easemob-demo-flutter)查看 Demo 源码地址。 - -### React Native - -点击[这里](https://github.com/easemob/easemob-uikit-reactnative)查看 Demo 源码地址。 \ No newline at end of file diff --git a/docs/product/easemob_app_token.md b/docs/product/easemob_app_token.md deleted file mode 100644 index 4cac4d9b..00000000 --- a/docs/product/easemob_app_token.md +++ /dev/null @@ -1,94 +0,0 @@ -# 使用环信 App Token 鉴权 - - - -环信提供的 REST API 需要 app token (管理员权限 token) 才能使用,即发送 HTTP 请求时需要携带 app token。本文介绍如何获取 app token。 - -另外,环信 Server SDK 提供了用户、消息、群组、聊天室等资源的操作管理能力,详见 [Java Server SDK](/document/server-side/java_server_sdk.html) 和 [PHP Server SDK](/document/server-side/php_server_sdk.html)。 - -## 获取管理员权限 Token - -获取 token 时,服务器会返回 token 有效期,即响应中的 `expires_in` 字段的值。由于网络延迟等原因,系统不保证 token 在此值表示的有效期内绝对有效。如果发现 token 使用异常,如返回 HTTP 状态码 401,请重新获取新的 token。 - -:::tip -请不要频繁向服务器发送获取 token 的请求,同一账号发送此请求超过一定频率会被服务器封禁。 -::: - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/token -``` - -#### 路径参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------- | :----- | :------- | :---------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | - -#### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------- | :----- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `grant_type` | String | 是 | 授权方式。该参数设置为固定字符串 `client_credentials`,即客户端凭证模式。 | -| `client_id` | String | 是 | App 的 `client_id`,用于生成 app token 调用 REST API。详见 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的`应用详情`页面。 | -| `client_secret` | String | 是 | App 的 `client_secret`,用于生成 app token 调用 REST API。详见 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的`应用详情`页面。 | -| `ttl` | Long | 否 | token 有效期,单位为秒。
- 若传入该参数,token 有效期以传入的值为准。
- 若不传该参数,以 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的`用户认证`页面的 token 有效期的设置为准。
- 若设置为 `0`,则 token 永久有效。
注意:VIP 5 集群该参数单位为毫秒。| - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示成功返回 token。响应 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :------------- | :----- | :--------------------------------------------------- | -| `access_token` | String | 有效的 Token 字符串。 | -| `expires_in` | Long | Token 有效时间,单位为秒,在有效期内不需要重复获取。 | -| `application` | String | 当前 App 的 UUID 值。 | - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{ - "grant_type": "client_credentials", - "client_id": "YXA6i-Ak8Ol4Eei2l11ZjV-EAg", - "client_secret": "YXA6VunqiNxoB7IwXHInk1cGiXOOJfc", - "ttl": 1024000 - }' 'http://a1.easemob.com/easemob-demo/testapp/token' -``` - -#### 响应示例 - -```json -{ - "access_token": "YWMte3bGuOukEeiTkNP4grL7iwAAAAAAAAAAAAAAAAAAAAGL4CTw6XgR6LaXXVmNX4QCAgMAAAFnKdc-ZgBPGgBFTrLhhyK8woMEI005emtrLJFJV6aoxsZSioSIZkr5kw", - "expires_in": 1024000, - "application": "8be024f0-e978-11e8-b697-5d598d5f8402" -} -``` - -#### 错误码 - -如果返回的 HTTP 状态码非 `200`,表示请求失败,可能提示以下错误码: - -| HTTP 状态码 | 错误类型 | 错误提示 | 可能原因 | 处理建议 | -| :---------- | :-------- | :-------------- | :------------ | :----| -| 400 | illegal_argument | client_id must be provided. | 请求 body 中没有传 `client_id`。| 详见 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的 **应用详情** 页面中 app key 对应的 **Client ID** 参数。 | -| 400 | illegal_argument | client_secret must be provided | 请求 body 中没有传 `client_secret`。 | 详见 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的 **应用详情** 页面中 app key 对应的 **ClientSecret** 参数。 | -| 400 | invalid_grant | client_id does not match | app key 对应的 `client_id` 与请求 body 中传入的 `client_id` 不匹配。 | 详见 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的 **应用详情** 页面中 app key 对应的 **Client ID** 参数,确保请求 body 中传入的与该参数一致。 | -| 400 | invalid_grant | client_secret does not match | app key 对应的 `client_secret` 与请求 body 中传入的 `client_secret` 不匹配。 | 详见 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的 **应用详情** 页面中 app key 对应的 **ClientSecret** 参数,确保请求 body 中传入的与该参数一致。 | -| 404 | organization_application_not_found | Could not find application for XXX/XXX from URI: XXX/XXX/users | App key 不存在。 | 检查 `orgName` 和 `appName` 是否正确或[创建应用](/product/enable_and_configure_IM.html#创建应用)。 | diff --git a/docs/product/easemob_user_token.md b/docs/product/easemob_user_token.md deleted file mode 100644 index 840888ee..00000000 --- a/docs/product/easemob_user_token.md +++ /dev/null @@ -1,238 +0,0 @@ -# 使用环信 User Token 鉴权 - - - -客户端 SDK 不提供获取 token 的 API。如果你的用户在客户端使用环信 token 登录和鉴权,你需要在应用服务器(App Server)集成环信服务端获取 token 的 API,实现获取 Token 的业务逻辑。 - -环信服务端支持以下三种方式获取用户 token: - -- 通过“用户 ID”和“密码”获取:用户注册后,使用 “用户 ID” 和 “密码” 登录。登录成功后,你的 App Server 会为客户端提供一个用户 token。 - -- 通过“用户 ID”获取:用户在客户端上登录时,你的应用服务器会下发用户 token,SDK 使用用户 ID 和用户 token 进行登录。开发者可通过 RESTful API 在你的应用服务器上对用户 token 进行管理,设置有效期,并确定当用户不存在时是否自动创建用户。 - -- 基于 `AppKey、AppSecret` 和 `userId`(即注册用户时传入的 `username`)生成动态 Token。 - -## 前提条件 - -要调用环信即时通讯 RESTful API,请确保满足以下要求: - -- 已在环信即时通讯控制台 [开通配置环信即时通讯 IM 服务](/product/enable_and_configure_IM.html)。 -- 已从服务端获取 app token,详见 [使用 App Token 鉴权](/product/easemob_app_token.html)。 -- 了解环信 IM API 的调用频率限制,详见[接口频率限制](/product/limitationapi.html)。 - -## 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 `Authorization` 字段: - -Authorization:`Bearer YourAppToken` - -为提高项目的安全性,环信使用 token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 推荐使用 app token 的鉴权方式,详见 [使用 App Token 鉴权](easemob_app_token.html)。 - -## 通过用户 ID 和密码获取用户 token - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/token -``` - -#### 路径参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------- | :----- | :------- | :--------------------- | -| `host`| String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。| -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。| - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------- | :----- | :------- | :---------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | - -#### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :----------- | :----- | :------- | :------------------- | -| `grant_type` | String | 是 | 授权方式。
- 若值为 `password`,通过用户 ID 和密码获取 token,需设置 `username` 和 `password` 参数。在该请求中,该参数需设置为 `password`。
- 若值为 `inherit`,通过用户 ID 获取 token,只需设置 `username` 参数。 | -| `username` | String | 是 | 用户 ID。 | -| `password` | String | 是 | 用户的登录密码。 | -| `ttl` | Long | 否 | token 有效期,单位为秒。
- 若传入该参数,token 有效期以传入的值为准。
- 若不传该参数,以 [环信即时通讯云控制台](https://console.easemob.com/user/login/)的`用户认证`页面的 token 有效期的设置为准。
- 若设置为 `0`,则 token 永久有效。
注意:VIP 5 集群该参数单位为毫秒。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 200,表示成功获取 token,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------------- | :----- | :---------------- | -| `access_token` | String | 有效的用户 token。 | -| `expires_in` | Long | token 有效期,单位为秒。在有效期内无需重复获取。
注意:VIP 5 集群该参数单位为毫秒。 | -| `user` | JSON | 用户相关信息。 | -| `user.uuid` | String | 用户的 UUID。即时通讯服务为该请求中的 app 或用户生成的唯一内部标识,用于生成用户 token。 | -| `user.type` | String | 对象类型,无需关注。 | -| `user.created` | Long | 注册用户的 Unix 时间戳,单位为毫秒。 | -| `user.modified` | Long | 最近一次修改用户信息的 Unix 时间戳,单位为毫秒。 | -| `user.username` | String | 用户 ID。 | -| `user.activated` | Bool | 用户是否为活跃状态:
- `true`:用户为活跃状态。
- `false`:用户为封禁状态。如要使用已被封禁的用户账户,你需要调用[解禁用户的 API](/document/server-side/account_system.html#账号解禁)对账号解除封禁。 | - -如果返回的 HTTP 状态码非 200,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{ - "grant_type": "password", - "username": "C", - "password": "1", - "ttl": "1024000" - }' 'http://XXXX/XXXX/XXXX/token' -``` - -#### 响应示例 - -```json -{ - "access_token": "YWMtrR6ECkz8Eeyx6Y9j1eX9kbsMrFep3U6BvVj7KSnNonWqRx7gTPwR7Kzl-Q_xISNOAwMAAAF9UPZqbQAPoAAtYK9fWgaTNyuWoB3-6nGf_TXBx3Nt3XRZST-elU0x2A", - "expires_in": 1024000, - "user": { - "uuid": "aa471ee0-XXXX-XXXX-ace5-f90ff121234e", - "type": "user", - "created": 1637740861395, - "modified": 1637740861395, - "username": "c", - "activated": true - } -} -``` - -## 通过用户 ID 获取用户 token - -你通过用户 ID 获取用户 token。若用户 ID 不存在,你可以确定是否自动创建用户。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/token -``` - -#### 路径参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------- | :----- | :------- | :---------------------------------- | -| `host`| String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。| -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。详见 [获取环信即时通讯 IM 的信息](enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。| - -#### 请求 header - -| 参数 | 类型 | 是否必需 | 描述 | -| :------------- | :----- | :------- | :---------------------------------- | -| `Content-Type` | String | 是 | 内容类型。请填 `application/json`。 | -| `Accept` | String | 是 | 内容类型。请填 `application/json`。 | -| `Authorization`| String | 是 | App 管理员的鉴权 token,格式为 `Bearer YourAppToken`,其中 `Bearer` 为固定字符,后面为英文空格和获取到的 app token。 | - -#### 请求 body - -| 参数 | 类型 | 是否必需 | 描述 | -| :----------- | :----- | :------- | :------------------- | -| `grant_type` | String | 是 | 授权方式。
- 若值为 `password`,通过用户 ID 和密码获取 token,需设置 `username` 和 `password` 参数。
- 若值为 `inherit`,通过用户 ID 获取 token,只需设置 `username` 参数。在该请求中,该参数需设置为 `inherit`。 | -| `username` | String | 是 | 用户 ID。 | -| `autoCreateUser` | Boolean | 是 | 当用户不存在时,是否自动创建用户。**自动创建用户时,需保证授权方式(`grant_type`)必须为 `inherit`,API 请求 header 中使用 App token 进行鉴权**。 | -| `ttl` | Long | 否 | token 有效期,单位为秒。设置为 `0` 则 token 有效期为永久。若不传该参数,有效期默认为 60 天。此外,也可通过[环信即时通讯云控制台](https://console.easemob.com/user/login/)的`用户认证`页面设置。该参数值以最新设置为准。
注意:VIP 5 集群该参数单位为毫秒。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示成功获取 token。如果返回的 HTTP 状态码非 200,表示请求失败。你可以参考[响应状态码](/document/server-side/error.html)了解可能的原因。 - -关于响应包体中的字段的描述,详见[通过用户 ID 和密码获取 token 的 API](#通过用户-id-和密码获取用户-token) 中的响应字段的描述。 - -### 示例 - -#### 请求示例 - -```shell -# 将 替换为你在服务端生成的 App Token - -curl -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Bearer ' -d '{ - "username": "test2333", - "grant_type": "inherit", - "autoCreateUser": true, - "ttl": 1024000 - }' 'http://XXXX/XXXX/XXXX/token' -``` - -#### 响应示例 - -自动创建用户并获取 token 的响应如下: - -```json -{ - "access_token": "YWMthyeiFhbyEe2eMGeYZSLlT7sMrFep3U6BvVj7KSnNonUiDB-wFvIR7a5Ttx2-01MYAwMAAAGCfIeryQAPoAAsuveDfkUrePkEM2Hgy6SaOTeTx3ETgh5cnXcP_HfBPg", - "expires_in": 1024000, - "user": { - "uuid": "220c1fb0-XXXX-XXXX-ae53-b71dbed35318", - "type": "user", - "created": 1659946472753, - "modified": 1659946472753, - "username": "test2333", - "activated": true - } -} -``` - -## 错误码 - -调用获取用户 token 接口时,如果返回的 HTTP 状态码非 `200`,表示请求失败,可能提示以下错误码: - -| HTTP 状态码 | 错误类型 | 错误提示 | 可能原因 | 处理建议 | -| :---- | :------------| :------| :------| :-------| -| 400 | illegal_argument | username [XXX] is not legal | 请求 body 中 `grant_type` 为 `inherit`,`autoCreateUser` 为 `true`时,若用户不存在,注册用户的 `username` 不合法。 | 请按照用户名的规范进行注册用户。 | -| 400 | illegal_argument | USERNAME_TOO_LONG | 请求 body 中 `grant_type` 为 `inherit`,`autoCreateUser` 为 `true`,若用户不存在,注册用户的 `username` 长度超限。 | 请按照用户名的规范进行注册用户。 | -| 400 | invalid_grant | user not activated | 用户被封禁。 | 解禁用户后,再获取用户 token。 | -| 400 | invalid_grant | invalid password | 用户的密码错误。 | 请求传入用户正确的密码。 | -| 401 | unauthorized | Unable to authenticate (OAuth) | token 不合法,可能过期或 token 错误。 | 使用新的 token 访问。 | -| 401 | auth_bad_access_token | Unable to authenticate due to corrupt access token | token 权限错误(可能使用的是用户 token)或生成 token 时使用的 app key 与 请求 url 中使用的 app key 不相同。 | 请保证使用的 token 正确。 | -| 404 | invalid_grant | user not found | 用户不存在。 | 先注册用户或者检查用户名是否正确。| -| 404 | organization_application_not_found | Could not find application for XXX/XXX from URI: XXX/XXX/users | App key 不存在。 | 检查 `orgName` 和 `appName` 是否正确或[创建应用](/product/enable_and_configure_IM.html#创建应用)。| -| 404 | entity_not_found | User null not found | 用户不存在。 | 先注册用户或者检查用户名是否正确。 | -| 409 | concurrent_operation_error | concurrency create app user failed | 同一秒内多次获取用户 token 时,若自动创建用户(即请求 body 中的 `grant_type` 为 `inherit`,`autoCreateUser` 为 `true`),引起的并发注册用户问题。 | 避免同一秒内多次调用该 API 自动创建用户获取用户 token。 如果获取 token 的用户已注册,并发调用该 API 则不会报错。 | -| 429 | resource_limited | You have exceeded the limit of the community edition,Please upgrade to the enterprise edition | 请求 body 中 `grant_type` 为 `inherit`,`autoCreateUser` 为 `true`(用户不存在时,自动注册用户) ,在使用注册用户的数量超过版本的限制 | 联系商务开通付费版。 | - -## 生成动态的用户 Token - -动态 Token 的生成方法依赖 `AppSecret`,因此生成逻辑务必在客户的服务器侧完成,以免 `AppSecret` 泄露。 - -动态 Token 临时有效,有效期由你自行设置,建议不要太长。 - -你可以按照如下步骤生成动态用户 token: - -1. 在[环信控制台](https://console.easemob.com/user/login)创建应用,生成 `AppKey`、`Client ID` 和 `ClientSecret`。 - -2. 基于 `AppKey、AppSecret` 和 `userId`(即注册用户时传入的 `username`),参考如下示例生成 token。 - -``` -a. 获取当前时间戳,单位为秒。 - CurTime = 1686207557 -b. 设置过期时间,单位为秒。 - ttl = 600 -c. 生成 signature,将 clientId、appkey、userId、curTime、ttl、clientSecret 六个字段拼成一个字符串,进行 sha256 编码并将编码内容得到的字节转换为十六进制字符串。 - str = clientId + appkey + userId + curTime + ttl + clientSecret - sha256hash = sha256.Sum256([]byte(str)) - signature = fmt.Sprintf("%x", shaBytes) -d. 组装为 json。 - json = {"signature": "xx", "appkey":"xx#xx", "userId":"xx", "curTime":1686207557, "ttl": 600} -e. 将 token 类型 "dt-" 放到 json 转成的字符串前,生成最终的字符串。 - str = "dt-" + jsonStr -f. 进行 base64 编码,生成最终的 token。 - token = base64.urlEncode.encode(str) -``` - -3. 使用上述方法生成 Token 后,客户端 SDK 将该 Token 填入并登录,服务器校验成功后即登录成功。 - diff --git a/docs/product/enable_and_configure_IM.md b/docs/product/enable_and_configure_IM.md deleted file mode 100644 index 719a5bc7..00000000 --- a/docs/product/enable_and_configure_IM.md +++ /dev/null @@ -1,488 +0,0 @@ -# 开通配置环信即时通讯 IM 服务 - - - -## 前提条件 - -配置环信即时通讯 IM 服务前,请确保已经具备以下条件: - -- 创建一个环信开发者账号。 - -## 创建应用 - -参照以下步骤在环信即时通讯云控制台创建应用和购买即时通讯 IM 服务。 - -1. 登录[环信即时通讯云控制台](https://console.easemob.com/user/login),在首页的**应用列表**区域点击 **添加应用** 按钮,创建即时通讯 IM 应用。 - -![img](/images/product/console.png) - -2. 在 **创建应用** 对话框中,输入新应用的相关信息,点击 **创建** 按钮创建应用。新建应用的服务版本默认为免费版。 - -:::tip -1. `appname`:你设置的应用名称,用于生成 App Key。该参数的值只能包含小写字母、数字和连字符,不能超过 32 个字符。 -2. `Appkey`:即时通讯服务分配给每个应用的唯一标识,由 `orgname` 和 `appname` 参数的值组成,生成后无法修改。 -3. `数据中心`:设置后无法修改。 -::: - -![img](/images/product/create-app.png) - -## 购买服务 - -1. 创建应用后,在 **应用列表** 中点击所创建应用的 **操作** 栏中的 **管理** 按钮,进入 **应用详情** 页面。 - -![img](/images/product/app-setting.png) - -2. 开通或升级版本。 - -你可以通过以下方法开通或升级版本。 - -- 在页面左侧的导航栏,选择 **即时通讯** > **功能配置** > **版本开通**,查看各种套餐的详情,选择需要的版本,点击 **立即开通**。 - -![img](/images/product/select-version.png) - -- 在页面左侧的导航栏,选择 **即时通讯** > **服务概览**,在 **服务版本** 区域中单击 **升级版本**,进入即时通讯 IM 服务版本购买页面。 - -![img](/images/product/upgrade-version.png) - -- 在页面左侧的导航栏,选择 **即时通讯** > **功能配置** > **功能配置总览**,点击各功能的 **操作** 一栏中的 **升级** 或 **增值服务**。 - -在 **即时通讯IM 服务版本** 页面,根据业务实际需求选择所需的服务版本和可选增值服务。该页面的配置参数说明如下表所示: - -| 参数项 | 描述 | -| :----------------------- | :-------------------------------------------- | -| 选择要开通服务的 Appkey | 请确认 App Key 是否选择正确,购买后无法修改。 | -| 请选择服务版本 | 服务版本的选择如下:
- 当 App Key 为免费版时,可购买专业版或旗舰版,不可单独购买增值服务。
- 当 App Key 为专业版时,可购买旗舰版或单独购买增值服务。| -| 可选增值服务 | 请根据实际需求选择增值功能:
- 单个群成员数上限和单个用户可加入群组数上限:不支持叠加购买;以单个群成员数上限举例说明,如果旗舰版购买了 8000 人/群的增值服务,则表示单个群成员上限配置提升至 8000 人/群。
- 消息云存储时长和 REST API 接口调用频率上限:支持可叠加购买,即支持多倍购买;以消息云存储时长举例说明,如购买时选择了 10 份,则表示消息云存储时长延长 300 天(30 天*10)。 | - -:::tip -服务购买页显示的预估费用仅用于做参考,预估费用仅包含基础费用,具体费用以每月账单为准。 -::: - -![img](/images/product/add-service.png) - -3. 勾选 **我已阅读并同意《环信云服务购买协议》**。 - -4. 核对所选服务信息,单击 **立即购买** 即生成订单。 - -购买成功后即刻生效,当天开始计费,每月 1 号自动扣除上月总消耗费用。 - -![img](/images/product/success.png) - -## 获取环信即时通讯 IM 的信息 - -在环信即时通讯云控制台,你可以查看你的环信即时通讯 IM 服务的如下信息: - -| 应用信息 | 描述 | 如何查看 | -| :--------- | :----- | :------- | -| `Orgname` | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。该参数是 `APPKEY` 的一部分。 | 在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **应用详情** 页面查看。 | -| `Appname` | 你在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建应用时填入的应用名称。该参数是 `AppKey` 的一部分。| 在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **应用详情** 页面查看。 | -| `APPKEY` | 应用的唯一标识,由 `Orgname` 和 `Appname` 组成,生成后不允许修改。 | 在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **应用详情** 页面查看。 | -| 服务器域名(`host`) | RESTful API 请求域名。环信为应用提供的 REST API 和 WebSocket 的请求域名。 | 在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **服务概览** 页面查看。 | -| 数据中心 | 环信 IM 提供的分布在全球的多个数据中心:
- 国内数据中心:北京 1 区和北京 Vip6 区
- 海外数据中心:新加坡 1 区、 法兰克福(法国)和弗吉尼亚(美国) | 在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **服务概览** 页面查看。 | - -## 查看和配置功能 - -创建应用后,参照以下步骤在环信即时通讯云控制台上查看环信即时通讯 IM 服务的详情以及进行配置。 - -在环信即时通讯云控制台的首页的 **应用列表** 中,点击目标应用的 **操作** 栏中的 **管理** 按钮,在左侧导航栏选择 **即时通讯** > **功能配置** > **功能配置总览**,您可以查看到当前 App Key 的服务配置并根据实际业务需求管理相关配置,具体操作说明如下: - -1. **免费开通**:指该功能当前服务版本里已包含,可根据实际业务需求选择是否开通;点击 **免费开通**,则可立即开通该功能; -2. **设置**:指该功能已开通且有需要设置的配置项,点击 **设置**,即可进入对应设置页配置; -3. **升级**:功能如果当前服务版本中不包含、或需要提高功能状态中的参数值,则可点击 **升级**,购买升级至符合业务需求的服务版本即可; -4. **增值服务**:点击**增值服务**,进入增值服务购买页面,根据实际需求选择购买。 - -![img](/images/product/functional.png) - -## 设置消息撤回(REST & 客户端) - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **功能配置总览**。在 **功能配置总览** 页面的 **基础功能** 页签下,搜索找到消息撤回(REST&客户端),单击右侧的 **设置**(已开通状态下)。 -2. 在弹出的 **消息撤回时间设置** 对话框中,设置消息可撤回时长。端消息撤回时长和 REST 消息撤回时长均不能超过 7 天。 -3. 单击 **确定** 保存配置。 - -![img](/images/product/rest.png) - -## 设置群消息已读回执 - -群聊消息的已读回执使用前,需要开通该功能。 - -在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **功能配置总览**。在 **功能配置总览** 页面的 **基础功能** 页签下,搜索找到**消息已读回执(群聊)**开通功能。 - -![img](/images/product/message/message_receipt.png) - -## 设置通过 RESTful API 发送的消息写入会话列表 - -通过 RESTful 接口发送的消息默认不写入会话列表,若需要此类消息写入会话列表,需要开通。 - -在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **功能配置总览**。在 **功能配置总览** 页面的 **基础功能** 页签下,搜索找到**rest发消息写会话列表**,然后点击**设置**。 - -![img](/images/product/enable_and_configure/message_rest_conversation.png) - -## 配置推送证书 - -使用离线推送通知之前,需完成各平台的证书配置。当前支持以下平台:苹果 APNs、谷歌 FCM、华为、小米、OPPO、VIVO 和魅族。 - -开启环信即时通讯 IM 服务后,按照以下步骤添加消息推送证书: - -1. 在环信即时通讯云控制台首页的**应用列表**中,在目标应用的 **操作** 栏中,点击 **管理**。 - -![img](/images/product/push/push_app_list.png) - -2. 在左侧导航栏,选择 **即时通讯** > **功能配置** > **消息推送** > **证书管理**,进入 **证书管理** 页面。 - -![img](/images/product/push/push_settings.png) - -3. 点击 **添加推送证书** 按钮,打开 **添加推送证书** 对话框。 - -![img](/images/product/push/push_settings_window.png) - -4. 在 **添加推送证书** 对话框中,填写各厂商平台的相关推送信息,点击 **保存** 按钮,完成证书配置。 - -![img](/images/product/push/push_settings_form.png) - - -## 配置推送模板 - -若使用推送模板,你首先要在环信即时通讯云控制台选择 **即时通讯** > **功能配置** > **功能配置总览** 开启离线推送高级功能。 - -开启后,你可以配置默认推送模板和自定义推送模板。 - -![img](/images/product/push/enable_advanced_function.png) - -### 使用默认推送模板 - -默认推送模板主要用于服务器提供的默认配置不满足你的需求时,可使你设置全局范围的推送标题和推送内容。例如,服务器提供的默认设置为中文和英文的推送标题和内容,你若需要使用韩语或日语的推送标题和内容,则可以设置对应语言的推送模板。 - -要使用默认模板,你需要在环信即时通讯云控制台或[调用 RESTful 接口](/document/server-side/push.html#创建离线推送模板)创建默认推送模板,模板名称为 **default**。设置完毕,消息推送时自动使用默认模板,创建消息时无需传入模板名称。 - -按照以下步骤创建默认推送模板: - -1. 在环信即时通讯云控制台首页的**应用列表**中,在目标应用的 **操作** 栏中,点击 **管理**。 - -![img](/images/product/push/push_app_list.png) - -2. 在左侧导航栏,选择 **即时通讯** > **功能配置** > **消息推送** > **模板管理**,进入 **模板管理** 页面。 - -![img](/images/product/push/push_template.png) - -3. 点击 **添加推送模板**,在弹出的窗口中配置**模板名称**、**标题**和**内容**。 - -- **模板名称**:推送模板名称,String 类型,默认模板为 **default**。该参数必须填写。模板名称最多可包含 64 个字符,支持以下字符集: - - 26 个小写英文字母 a-z; - - 26 个大写英文字母 A-Z; - - 10 个数字 0-9。 -- **标题**/**内容**:推送标题/内容。Array 类型,该参数必须填写。这两个参数的设置方式如下: - - 输入固定的推送标题,例如,标题为 “您好”,内容为“您有一条新消息”。 - - 内置参数填充: - - `{$dynamicFrom}`:按优先级从高到底的顺序填充好友备注、群昵称(仅限群消息)和推送昵称。 - - `{$fromNickname}`:推送昵称。 - - `{$msg}`:消息内容。 - - 自定义参数填充:模板输入数组索引占位符,格式为: {0} {1} {2} ... {n} - - 对于推送标题和内容来说,前两种设置方式在创建消息时无需传入该参数,第三种设置方式则需要通过扩展字段传入。 - - 推送模板参数在消息扩展 `ext.em_push_template` 中。推送模板参数的 JSON 结构如下: - - ```json - { - "ext":{ - "em_push_template":{ - "title_args":[ - "环信" - ], - "content_args":[ - "欢迎使用im-push", - "加油" - ] - } - } - } - - # title: {0} = "环信" - # content: {0} = "欢迎使用im-push" {1} = "加油" - ``` - - 群昵称即群成员在群组中的昵称,群成员在发送群消息时通过扩展字段设置,JSON 结构如下: - -```json - { - "ext":{ - "em_push_ext":{ - "group_user_nickname":"Jane" - } - } - } -``` - - ![img](/images/product/push/push_template_add.png) - -### 使用自定义推送模板 - -自定义推送模板,即名称为 `default` 之外的推送模板。你可以参考以下步骤使用自定义推送模板: - -1. 若使用自定义推送模板,你需要在环信即时通讯云控制台或[调用 RESTful 接口](/document/server-side/push.html#创建离线推送模板)创建自定义推送模板。**添加推送模板** 对话框中参数的描述,详见[使用默认推送模板](#使用默认推送模板)。使用自定义模板时,**标题** 和 **内容** 参数无论通过哪种方式设置,创建消息时均需通过扩展字段传入。 - -2. 创建消息时需通过使用扩展字段传入模板名称、推送标题和推送内容,通知栏中的推送标题和内容分别使用模板中的格式。 - -## 配置消息回调 - -环信即时通讯 IM 提供消息回调服务。**旗舰版 IM 服务包含回调服务,而专业版 IM 服务不包含回调服务,需要按以下步骤单独购买**。 - -### 开通消息回调 - -1. 在环信即时通讯云控制台首页的**应用列表**中,在目标应用的 **操作** 栏中点击 **管理**。 - -![img](/images/product/push/push_app_list.png) - -2. 选择**即时通讯** > **功能配置** > **功能配置总览**,在**基础功能**页签的功能列表上,点击**回调**对应的 **增值服务**。 - -![img](/images/callback/callback_activation.png) - -3. 在弹出页面的**可选增值服务**区域,选择**回调**对应的**付费开通**,确定购买时长,选择 **我已阅读并同意《环信云服务购买协议》**,然后点击**提交订单**。 - -![img](/images/callback/callback_purchase.png) - -4. 在支付页面,点击**立即支付**支付费用后即可使用。 - -![img](/images/callback/callback_payment.png) - -### 配置回调规则 - -你可以按照以下步骤添加消息回调规则,最多可以配置 4 条发送前和发送后回调规则。配置回调规则后,环信服务器会自动为该规则生成 secret,向你的 app server 发送数据时会基于该 secret 生成签名(即请求中的 `security` 参数),作为你的服务器识别环信服务器的依据。若要使用自定义密钥,可以联系环信商务经理。 - -1. 在左侧导航栏,选择 **即时通讯** > **功能配置** > **消息回调**,进入 **消息回调** 页面。 - -![img](/images/product/callback_rule_list.png) - -2. 点击 **添加回调地址** 按钮,打开回调配置对话框,填写回调相关配置信息,点击 **保存** 按钮,完成回调配置。 - -- 配置发送前回调规则 - -![img](/images/callback/pre_delivery_rule_add.png) - -在**发送前回调**对话框中配置以下参数: - -| 参数 | 是否必填 | 描述 | -| :----------------- | :------- | :--------------- | -| 规则名称 | 是 | 填写文字,支持中英文,长度限制为 32 字符。每个规则的名称必须唯一 。 | -| 会话类型 | 是 | 会话类型:
• 单聊;
• 群组;
• 聊天室。 | -| 消息类型 | 是 | 支持发送前回调的消息类型包括文本、图片、视频、位置、语音、文件和自定义消息(“TEXT”,“IMAGE”,“VIDEO”,“LOCATION”,“VOICE” 和 ”FILE”)。 | -| 等待响应时间 | 是 | 后台判断超时时间,默认 200,单位为毫秒。如果回调超时无应答,消息默认会正常下发,支持修改消息处理逻辑。 | -| 调用失败时默认策略 | 是 | 当您的服务器返回结果异常或等待时间内未返回结果时,消息放行或不放行。 | -| 消息拦截报错时显示 | 是 | 当消息被拦截时,是否通知发送者 SDK 消息发送失败:
• 报错:通知发送者 SDK 消息发送失败,发送者会感知到消息发送失败;
• 不报错:不通知发送者 SDK 消息发送失败,发送者无感知。 | -| 启用状态 | 是 | 回调规则是否马上生效:
• 启用:马上生效;
• 不启用:暂不生效。 (建议首次创建配置为“不启用”,等您的服务器配置好验证信息后再修改为“启用”) | -| 回调地址 | 是 | 回调 URL,环信 IM 对 HTTP 和 HTTPS 的回调地址均支持。 | - -- 配置发送后回调规则 - -![img](/images/callback/post_delivery_rule_add.png) - -在**发送后回调**对话框中配置以下参数: - -| 参数
| 是否必填 | 内容 | -| :--------------------- | :------- | :--------------- | -| 规则名称 | 是 | 唯一的规则名称,只支持字母、数字和下划线,不支持中文字符,且长度不超过 32 字符。 | -| 回调地址 | 是 |环信 IM 服务器会将消息推送到指定的 URL 地址,支持针对不同类型的消息配置不同的 HTTP 和 HTTPS 回调地址。 | -| 启用状态 | 是 |是否启用该规则。| -| 回调类型 | 是 |回调类型。你可以选择对各种类型的单聊、群聊、和聊天室消息以及各种事件进行回调,详见[回调事件](/document/server-side/callback_message_send.html)。对于表情回复 Reaction 和子区 Thread,如要获取回调事件,无需单独配置,只需选择对应的消息类型即可。例如,如果需要单聊文本消息的 Reaction,你需要选中 **单聊消息 > 文本消息**,服务器发送回调事件时即会返回 Reaction 信息。| -| 消息类型 | 是 |需要回调的类型:
- **聊天消息**:发送成功的消息,包括通过客户端和 REST API 发送的消息。这些消息与通过 REST 导出的聊天记录查询到的消息一致。例如,用户 u1 向用户 u2 发送消息,则会产生一条聊天消息,与接收方是否在线无关。收到的消息中 `from` 为 u1,`to` 为 u2。用户 u1 在群组 g1 中发送消息,则会产生一条聊天消息,收到的消息中 `from` 为 u1,`to` 为 g1,且返回值包含 `group_id` 字段。
- **离线消息**:消息发送时接收方为离线的消息。例如:单聊中发送消息,若对端用户不在线,则会产生一条离线消息;在群聊中发送消息,若有几个群成员不在线,则会产生几条离线消息,这些离线消息的 `to` 参数为接收消息用户的 ID,并不是群组 ID。App 可以通过推送服务对这些消息进行个性化推送。| -| REST 消息是否需要回调 | 是 | 通过 REST API 发送的消息是否需要回调:
- **是**:需要;
- **否**:不需要。 | -| From ID | 否 |消息发送方或操作者的用户 ID。每行输入一个用户 ID,一次最多输入 50 条。设置该参数后,环信服务器只针对该用户发送的消息及执行的操作(例如好友、群组或聊天室相关操作)进行回调。若不指定该参数,规则对发送方或操作者不限制。 | -| To ID | 否 | 单聊的消息或事件接收方的用户 ID。每行输入一个用户 ID,一次最多输入 50 条。若不指定该参数,规则对接收方不限制。| -| 群组/聊天室 ID | 否 | 群组或聊天室 ID。每行输入一个群组 ID 或聊天室 ID,一次最多输入 50 条。设置该参数后,环信服务器只针对该群组中的消息或事件进行回调。若不指定该参数,规则对群组和聊天室不限制。| -| 扩展字段中的 Key | 否 | 消息扩展字段中的属性 key。每行输入一个 key,一次最多输入 50 条。设置该参数后,只针对包含该属性 Key 的消息进行回调。若不指定该参数,规则对消息扩展字段不限制。| - -其中,**From ID**、**To ID**、**群组/聊天室 ID** 和**扩展字段中的 Key** 为配置发送后回调规则时需指定的高级筛选条件,配置示例如下: - -- 仅对单聊的回调:仅设置 **From ID** 和 **To ID**。指定的发送方向接收方发单聊消息或对该好友进行操作(如删除好友)时收到回调消息。例如,**From ID** 设置为 test 1,**To ID** 设置为 test 2,test 1 向 test 2 发单聊消息时收到回调。 - -- 仅对群组或聊天室的回调:仅设置**群组/聊天室 ID** 参数。这种情况下,只有在指定的群组或聊天室中发送消息或进行操作时收到回调。例如,**群组/聊天室 ID** 设置为群组 ID 228978,则仅在该群组中发送消息时收到回调。 - -- 仅对群聊中某个用户的回调:仅设置 **From ID** 和 **群组/聊天室 ID**。这种情况下,只有群组或聊天室中的指定用户发送消息或执行操作时收到回调。例如,**From ID** 设置为 test 1,**群组/聊天室 ID** 设置为群组 ID 228978,仅 test 1 用户在群组中发送消息时收到回调。 - -:::tip - -若 **From ID**、 **To ID** 和**群组/聊天室 ID** 同时设置,发送方向接收方发送单聊、群聊消息时不会收到回调。 - -::: - -## 消息举报 - -环信即时通讯 IM 提供消息举报功能。你的用户可以在客户端举报违规消息。当服务器收到举报消息后,会将举报消息存储到数据库,并在[环信即时通讯云控制台](https://console.easemob.com/user/login)展示。你可在环信即时通讯云控制台查看举报记录,并进行相应处理。 - -1. 开通消息举报功能。 - -在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **功能配置总览**。在 **功能配置总览** 页面的 **基础功能** 页签中搜索找到 **消息举报**,进行开通。 - -对于专业版,消息举报为增值服务,你需要点击 **增值服务** 单独付费开通,如下图所示。 - -对于旗舰版,该功能免费提供,你只需要点击 **免费开通**,开通即可使用。 - -:::tip -消息举报功能与内容审核功能为两个独立的功能,没有任何关联,因此使用该功能无需提前开通内容审核功能。 -::: - -![img](/images/product/enable_and_configure/message_report_enable.png) - -2. 查看消息举报记录。 - -消息举报服务开通后,你可以在环信即时通讯云控制台的左侧导航栏中选择 **内容审核 > 消息举报** 查看消息举报记录。 - -## 敏感词设置 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **功能配置总览**。在 **功能配置总览** 页面的 **基础功能** 页签中搜索找到敏感词,单击右侧的 **设置**(已开通状态下),打开敏感词配置页面。 -2. 在敏感词配置页面,单击 **服务设置** 旁边的 **编辑**,在弹出的 **敏感词服务** 对话框中,按需求选择对应设置。 -3. 单击 **确定** 保存配置。 - -![img](/images/product/sensitive-words.png) - -## REST-IP 白名单设置 - -### 添加 IP 白名单 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **功能配置总览**。在 **功能配置总览** 页面的 **基础功能** 页签中搜索找到 **REST-IP 白名单**,单击右侧的 **设置**(已开通状态下),打开**安全配置**页面。 -2. 在 **安全配置** 页面,单击 **添加IP**,在弹出的 **添加 IP** 对话框中,输入 IP 地址。 -:::tip -1. 每次只能输入 1 个 IP 地址,最多可添加 8 个。 -2. 添加 IP 地址成功后 10 分钟后生效。 -3. 若白名单列表为空,则所有 IP 地址均可发 REST 消息。 -::: -3. 单击 **保存** 完成配置。 - -![img](/images/product/ip-whitelist.png) - -### 删除 IP 白名单 - -如果你不再允许某个 IP 地址继续发送 REST 消息,可以在 IP 白名单中将其删除。如果你删除了 IP 白名单中所有 IP,即白名单列表为空,则默认所有 IP 地址均可发送 REST 消息。 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **功能配置** > **安全配置**。 - -2. 在 **IP白名单** 列表中,单击目标 IP 右侧的 **删除**。 - -![img](/images/product/delete-ip-allow-list.png) - -3. 单击 **确认**,则删除该 IP 地址。 - -## 好友关系检查 - -环信即时通信 IM 默认支持陌生人之间发送单聊消息,即无需添加好友即可聊天。若仅允许好友之间发送单聊消息,你需要按以下步骤开启好友关系检查。 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **服务概览**。 -2. 在 **设置** 区域,点击 **好友关系检查**对应的 **打开**,则该功能的状态为**已开启**。若关闭该功能,点击 **关闭**。 - -该功能开启后,SDK 会在用户发起单聊时检查好友关系,若用户向陌生人发送单聊消息,SDK 会提示错误码 221。 - -## 创建 IM 用户 - -### 正式环境 - -在正式开发环境中,你可以采取以下步骤创建用户: - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯 > 运营服务 > 用户管理**。 - -2. 在 **用户管理** 页面,点击 **创建IM用户** 按钮,在弹出的对话框中填写用户 ID、昵称和密码,然后点击 **保存**。 - - 各参数的设置要求,详见[注册用户 RESTful API](/document/server-side/account_system.html#开放注册单个用户)。 - -![img](/images/product/user_create.png) - -创建用户后,你可以点击 **操作** 栏中的 **更多** 对该用户进行管理,包括修改用户信息和查看好友等。 - -![img](/images/product/user_operation.png) - -### 测试环境 - -在测试环境中,例如实现快速开始,你可以采取以下步骤创建用户: - -1. 在环信即时通讯云的左侧导航栏中,选择 **应用概览 > 用户认证**。 - -2. 在**用户认证**页面,点击**创建IM用户**按钮,在弹出的对话框中填写用户 ID 和密码,然后点击 **保存**。 - -![img](/images/product/user_create_test.png) - -创建用户后,你可以查看用户 token、设置 token 有效时间、重置密码、查询用户以及删除用户。 - -注意:设置 token 有效时间对当前 App Key 下的 app 和用户 token 均生效,仅对修改后新生成的 token 生效,不影响修改之前已生成的 token。 - -![img](/images/product/user_operation_test.png) - -## 创建群组 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯 > 运营服务 > 群组管理**。 - -2. 在 **群组管理** 页面,点击 **创建群组**,在弹出的对话框中设置群组名称、描述、群主、最大人数、群组类型、申请入群方式、邀请方式和被邀请用户是否需要确认,然后点击 **创建**。 - - 各参数的设置要求,详见[创建群组 RESTful API](/document/server-side/group_manage.html#创建群组)。 - -创建群组后,你可以通过以下步骤管理群组信息和成员: - -- 点击 **操作** 栏中的 **更多** 进行群组管理,包括查看群组成员、查看群组黑名单、发送rest消息和删除群组等。 - -- 要添加用户,选择 **查看群组成员**,在弹出的对话框中,输入用户 ID,点击 **添加成员**。成员添加后会显示在下方的成员列表中,你可以移除该成员。 - -- 在群组列表上,你可以点击群组 ID,修改群组信息,包括群组名称、描述和公告,以及管理群成员,包括全员禁言、将成员添加/移除禁言列表和黑名单,添加和移除管理员。 - -## 创建聊天室 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯 > 运营服务 > 聊天室管理**。 - -2. 在 **聊天室管理** 页面,点击 **创建聊天室**,在弹出的对话框中设置聊天室名称、描述、超级管理员和普通管理员的用户 ID 以及最大成员数,然后点击 **保存**。 - - 各参数的设置要求,详见[创建聊天室 RESTful API](/document/server-side/chatroom.html#创建聊天室)。 - -创建群组后,你可以通过以下步骤管理聊天室信息和成员: - -- 点击 **操作** 栏中的 **更多** 进行聊天室管理,包括修改聊天室信息、查看聊天室成员、查看聊天室管理员、查看聊天室黑名单、查看聊天室禁言名单和删除聊天室。 - -- 要添加用户,选择 **查看聊天室成员**,在弹出的对话框中,输入用户 ID,点击 **添加成员**。成员添加后会显示在下方的成员列表中,你可以移除该成员。 - -- 在聊天室列表上,你可以点击聊天室 ID,修改聊天室信息,包括聊天室名称、描述和公告,以及管理聊天室成员,包括全员禁言、将成员添加/移除禁言列表和黑名单,添加和移除管理员。 - -## IM 用户设备日志 - -环信即时通讯云控制台支持查询用户设备端的日志,或将设备端的日志上传到环信日志服务器。目前,仅支持使用了高于 3.3.2 的 Android/iOS SDK 的设备。 - -![img](/images/product/enable_and_configure/user_device_log.png) - -### 上传设备日志到环信日志服务器 - -输入用户 ID 后,点击**下发上传log指令**,服务端将对指定用户设备下发指令: - -- 如果当前用户在线,则会开始上传设备日志,正常情况预计 5s 内可完成上传。 - -- 如果当前用户不在线,则需要等用户下次上线时开始上传设备日志,日志保留时间为 7 天。 - -上传指令和日志保留时间为 7 天,即如果下发指令后 7 天内用户均未上线,则 7 天后指令失效,不会触发上传日志。 - -### 查询用户设备端日志 - -输入用户 ID 后,点击**查询**,查询用户设备端的日志。若设备已上传日志,则会查询到;若设备未上传过日志,则查询不到。 - -## 账户中心 - -登录环信即时通讯云控制台,选择 **费用中心** > **账户中心**,可查看你当前的账户余额和支出明细。 - -![img](/images/product/account-bills.png) - -## 查看订单记录 - -登录环信即时通讯云控制台,选择 **费用中心** > **订单中心**,可查看你当前的所有订单记录。 - -![img](/images/product/order-records.png) - -**订单中心**页面上的订单状态说明如下: - -- **开通中**:用户生成订单后,需要 3-5 分钟完成功能配置。此时订单显示为**开通中**状态,表示购买的服务正在配置;配置完成后,订单变为**服务中**状态。 -- **服务中**:表示当前订单中购买的服务在使用中。同一 App Key 同时仅能有 1 个服务版本的订单状态为**服务中**。 -- **已完结**:表示当前订单中购买的服务已关闭。当客户升级新服务后,原服务版本订单和相关增值服务订单均会自动关闭,变为**已完结**状态。 - -![img](/images/product/order-status.png) - -点击 **操作** 栏中的 **详情**,可查看订单详情。 - -![img](/images/product/order-detail.png) - -## 查看账单记录 - -登录环信即时通讯云控制台,选择 **费用中心** > **消费账单**,可查看你当前的已生成的账单记录。 - -![img](/images/product/bill-records.png) \ No newline at end of file diff --git a/docs/product/faq_integration_issues.md b/docs/product/faq_integration_issues.md deleted file mode 100644 index f7544a9a..00000000 --- a/docs/product/faq_integration_issues.md +++ /dev/null @@ -1,53 +0,0 @@ -# 集成类问题 - - - -## 如何实现跨 app 聊天 - -如果您需要两个 app 之间可以互相通信,只要将 AppKey 写成同一个就可以实现跨 app 聊天。同时,您需要在环信即时通讯云控制台上传对应 app 的推送证书(可以是多个),这样可以确保您的两个 app 都能收到推送。 - -## 获取设备本地日志文件 - -在排查移动端集成或者使用问题的时候,会遇到需要查看设备本地 SDK 的 log 来确认问题,在此提供移动端获取本地 log 的方法。 - -### Android - -#### 通过 API 获取 - -SDK 的 log 文件在 app 的安装目录中,可以通过 API 获取,获取时需要确保 SDK 已经完成初始化。 - -通过 API 获取 log 文件路径, 返回格式为 `xxxxx/xxxx/log.gz` - -```java -logPath = EMClient.getInstance().compressLogs(); -``` - -#### 从手机或者模拟器获取日志文件 - -前提条件 - -- 确保电脑上安装了 adb 工具,可以参考 [SDK Platform Tools](https://developer.android.com/studio/releases/platform-tools) -- 手机连接到电脑,adb 的使用可以参考:[Android Debug Bridge]( https://developer.android.com/studio/command-line/adb) - -```shell -adb pull /sdcard/android/data/(your_package_name)/(appkey)/core_log/easemob.log -``` - -### iOS - -#### 通过 API 获取 - -SDK 的 Log 文件在 app 的 sandbox 中,如需获取可通过 SDK 提供的`getLogFilesPath:` 获取,获取时需要确保SDK已经完成初始化。 - -``` -EMError *error = nil; -NSString *logPath = [EMClient.sharedClient getLogFilesPath:&error]; -``` - -返回格式为 `xxxxx/xxxx/log.gz`。 `error` 为错误信息,无错误是返回`nil`。 - -#### 从手机或者模拟器获取日志文件 - -通过 XCode debug 时,可以连接手机或者模拟器,找到应用的 sandbox 目录,然后提取日志文件。 - -App_Sandbox_path/Application Support/HyphenateSDK/easemobLog \ No newline at end of file diff --git a/docs/product/faq_quality_issues.md b/docs/product/faq_quality_issues.md deleted file mode 100644 index f898bd53..00000000 --- a/docs/product/faq_quality_issues.md +++ /dev/null @@ -1,93 +0,0 @@ -# 质量类问题 - - - -## 如何排查 环信即时通讯 IM 单聊消息丢失 - -### 问题描述 - -在使用 环信即时通讯 IM 聊天的过程中,如果遇到用户 A 给用户 B 发消息,用户 B 没有接收到的情况(视为消息丢失),可以按照下面的说明进行排查。 - -### 问题原因 - -可能是以下原因: - -- 用户 A 消息发送失败; -- 接收消息的用户 ID 错误; -- 用户 B 把 A 设为黑名单了; -- 用户 B 在其他设备上登录时接收了消息; -- 用户 B 离线消息数量超过 500 条等。 - -### 排查方案 - -#### 一、APP 未上线时,在使用环信即时通讯 IM SDK 集成阶段测试用户出现消息丢失 - -分为用户 B 在线和不在线两种情况: - -- 用户 B 在线的情况下收不到用户 A 发的消息: - 1. 检查用户 A 发送的消息是否成功,可以根据 SDK 发消息方法返回的结果判断消息是否发送成功,如果发送失败,则用户 B 收不到消息。 - 2. 检查用户 A 给用户 B 发消息时,B 的 ID 是否正确,如果传的不是用户 B 的 环信即时通讯 IM ID,那么用户 B 收不到消息。 - 3. 检查用户 B 是否将用户 A 加入黑名单 ,如果用户 B 将用户 A 加入黑名单,那么用户 B 将收不到用户 A 发的消息,详见 [获取黑名单](/document/server-side/user_relationship.html#获取黑名单)。 -- 用户 B 不在线时,用户 A 给用户 B 发消息,用户 B 重新登录后收不到消息: - 1. 可能存在用户 B 有在其他设备上登录的情况,把消息接收走了,所以在当前设备登录时将不再接收消息。 - 2. 确认用户 B 的离线数量是不是很大,如果超过 500 条,那么用户 B 只会收到最新的 500 条消息,超过500条的那部分消息将接收不到。 - -#### 二、APP 已经上线后,线上用户出现消息丢失 - -1. 先与自己的客户确认是否存在 “用户 B 不在线时,用户 A 给用户 B 发消息,用户 B 重新登录后收不到消息”下描述的 1,2 两种情况。 -2. 提供 App Key、环信即时通讯 IM ID、丢失的消息内容和发送消息的时间,然后登录环信即时通讯云控制台,提交工单,让环信即时通讯 IM 的技术支持排查。[环信即时通讯云控制台](https://console.easemob.com/user/login))。 - -## 排查环信即时通讯 IM 群聊消息丢失 - -### 问题描述 - -用户有时反馈环信即时通讯 IM 丢消息,在用户 A 与用户 B 在同一个群组,用户 A 向群组中发消息这种情况下,我们建议先按以下步骤自查。如果没发现问题,可以提交工单由技术支持同事协助排查。 - -### 问题原因 - -可能的原因包括用户 A 构建消息时传的消息类型不是群聊类型、用户 A 消息发送失败、用户 B 不在群组中、用户 B 屏蔽了该群组消息、用户 B 被加入了群组黑名单、用户 B 在其他设备上登录时接收了消息以及用户 B 群组离线消息数量超过 200 条等。 - -### 排查方案 - -#### 一、App 未上线时,使用环信即时通讯 IM SDK 集成阶段测试用户出现消息丢失 - -- 用户 B 在线的情况下收不到用户 A 发的群组消息: - 1. 检查用户 A 在构建消息时,传的消息类型是不是群聊类型的,如果不是则用户 B 收不到用户 A 发的群组消息,详见 [Android 版构建消息](/document/android/message_send_receive.html#发送和接收文本消息) 或 [iOS 版构建消息](/document/ios/message_send_receive.html#发送和接收文本消息)。 - 2. 检查用户 A 发送的消息是否成功,可以根据 SDK 发消息方法返回的结果判断消息是否发送成功,如果发送失败,则用户 B 收不到用户 A 发送的群组消息。 - 3. 检查用户 A 给用户 B 发消息时,传的群组 ID 是否正确(是否为 A 与 B 共同加入的群组 ID),如果传的不是正确的群组 ID,那么用户 B 收不到消息用户 A 发的群组消息。 - 4. 检查用户 B 是否在群组中,可以获取群组详情,看群组中是否有用户 B,详见 [获取群组详情](/document/server-side/group_manage.html#获取群组详情)。 - 5. 检查用户 B 是否屏蔽了该群组消息,如果用户 B 屏蔽了该群组消息,那么将收不到用户 A 发的群组消息,详见 [Android 屏蔽和解除群消息](/document/android/group_manage.html) 或 [iOS 屏蔽和解除群消息](/document/ios/group_manage.html)。 - 6. 检查用户 B 是否被加入了群组黑名单,如果用户 B 被加入到了群组黑名单,那么将收不到用户 A 发的群组消息,详见 [获取群组黑名单](/document/server-side/group_member.html#查询群组黑名单)。 -- 用户 B 不在线时,用户 A 向群组中发送消息,用户 B 重新登录后收不到群组消息: - 1. 可能存在用户 B 在其他设备上登录把消息接收走了的情况,则在当前设备登录时将不再接收消息。 - 2. 确认用户 B 所在的群组的离线数量是不是很大,如果超过200条,那么用户 B 只会收到最新的 200 条群组消息,超过 200 条的那部分群组消息将接收不到。 - -#### 二、App 已经上线后,线上用户出现群组消息丢失 - -1.先与 App 的用户确认是否存在以下情况: -- “用户 B 在线的情况下收不到用户 A 发的群组消息”的 3、4 和 5 的情况 -- “用户 B 不在线时,用户 A 向群组中发送消息,用户 B 重新登录后收不到群组消息”的 1 和 2 的情况。 - -2.若排除以上情况,可根据 App Key、发送者 ID 或消息 ID、消息发送时间在 [环信即时通讯云控制台](https://console.easemob.com/user/login) 自行查询消息投递状态,具体操作如下: - -1. 登录环信即时通讯云控制台。 -2. 在首页的 应用列表 区域中,点击具体应用的 **操作** 栏中的 **管理**。 -3. 在界面左侧导航栏中选择**应用详情**下的**即时通讯** > **实时查询** > **IM消息投递查询**。 - -![img](/images/product/faq-msgdeliveryquery.png) - -## 参考 - -### 如何判断用户是否在线 - -在使用环信即时通讯 IM 基础聊天业务的场景下,处理特定业务需求时需知晓某些用户是否在线。为此,环信即时通讯 IM 提供单个用户以及批量用户是否在线状态的查询,详见 [用户在线状态回调](/document/server-side/callback_login_logout.html)。 - -除此之外,可以在 [环信即时通讯云控制台](https://console.easemob.com/user/login) 上查询用户连接状态,具体操作如下: - -1. 登录环信即时通讯云控制台。 -2. 在首页的 **应用列表** 区域中,点击具体应用的 **操作** 栏中的 **管理**。 -3. 在界面左侧导航栏中选择 **应用详情** 下的 **即时通讯** > **实时查询** > **IM用户连接状态**。 - -![img](/images/product/faq-userconnectionstatus.png) - -说明: 环信即时通讯 IM SDK 未提供直接查询用户是否在线的方法,客户端可以封装查询用户是否在线的接口调用或者让自己服务器端来调用再与自己客户端交互。 \ No newline at end of file diff --git a/docs/product/glossary.md b/docs/product/glossary.md deleted file mode 100644 index 48258b39..00000000 --- a/docs/product/glossary.md +++ /dev/null @@ -1,205 +0,0 @@ -# 术语表 - - - -## 环信即时通讯 IM SDK - -环信即时通讯 IM SDK 是环信提供的用于实现即时通讯,比如:单聊、群聊、聊天室的 SDK。 - -### 环信即时通讯 IMKit - -IMKit 是环信即时通讯 IM SDK 的一个开源 UI 组件,提供应用内聊天的常用页面和 UI 组件,帮助开发者快速构建应用的 UI。 - -## 环信即时通讯 CallKit - -CallKit 提供应用内聊天中音视频通话的页面和 UI 组件,帮助开发者快速构建音视频通话功能。 - -### 环信通讯云控制台(Easemob Console) - -[环信通讯云控制台](https://console.easemob.com/user/login)是环信提供给开发者管理环信各项服务的工具。 - -## Demo - -环信即时通讯 IM 示例开源项目,目前支持 Android、iOS 和 Web 平台。 - -## 日活用户 - -日活用户(DAU),指日活跃用户数,即一个自然日内与环信服务器进行业务行为交互(包含但不局限于登录、收发消息)的用户总数。 - -## 会话和消息 - -### 会话 - -会话是一个单聊、群聊、聊天室或者子区所有消息的集合。用户需在会话中发送消息或查看历史消息或清空历史消息等操作。 - -### 会话列表 - -会话列表是指会话依照一定顺序排列的列表,会话的排列顺序依赖于会话中最近一条消息的接收时间等因素。 - -### 广播消息 - -广播消息是指通过 RESTful API 对应用内的所有用户发送消息。当用户离线时,消息会自动转换为系统离线推送。 - -### 离线消息 - -当接收方不在线时,环信即时通讯 IM 服务器会暂时保存消息,用户上线时,会接收到服务器保存的离线消息。不同套餐版本的离线消息保存时长不同。单聊和群聊支持离线消息,聊天室不支持离线消息。 - -### 历史消息 - -环信即时通讯 IM 服务器会保存历史消息以供查询。开发者可以通过 RESTful API 下载历史消息压缩包文件。 - -### 漫游消息 - -多端登录时,用户在其中一端发送的消息会同步到所有其他客户端,此类消息称为漫游消息。 - -### 文本消息 - -消息内容是普通文本,其中可以包括超链接,客户端收到消息后存入数据库、计入未读消息数。表情消息为开发者自定义。实质上是发文本消息。接收方收到文本消息后,首先查询文本消息是否是表情消息,如果是,则显示该文本消息为对应的表情图片。 - -### 图片消息 - -图片消息内容属于附件类型消息,内容图片 URL 地址、尺寸、图片大小等信息。最大支持 10 MB。 - -### 位置消息 - -消息内容为地理位置标题、经度和纬度信息。 - -### 语音消息 - -语音数据属于附件类型,需要提供时长信息,以秒为单位。最大支持 10 MB。 - -### 视频消息 - -消息内容为视频文件的 URL 地址、时长、大小、格式等信息,默认支持 10 MB。 - -### 文件消息 - -消息内容为文件的 URL 地址、大小、格式等信息,格式不限,默认支持 10 MB。 - -### 透传消息 - -透传消息可视为一条指令,通过发送这条指令给对方,通知对方要执行的操作,对方收到消息可自定义处理。透传消息不会存入本地数据库中,在 UI 上不显示,也不计入未读消息。具体功能可以根据自身业务需求自定义,例如实现头像或昵称的更新等。 - -### 消息自定义扩展 - -当基础的消息类型不满足需求时,可以使用消息自定义扩展增强基础消息类型,例如消息中需要携带被回复的消息内容等场景。 - -使用扩展后,消息大小不能超过原类型消息的大小。消息自定义扩展作为消息内容会存入本地数据库。 - -### 自定义消息 - -发者自定义的消息类型,例如红包消息、石头剪刀布等形式的消息。 - -### 消息回调 - -消息回调,即聊天服务器会在事件发生之前或之后,向客户的应用服务器发送请求,应用服务器可据此进行必要的数据同步,或者根据业务需求干预事件的后续处理流程。 - -### 消息云存储 - -将用户发送的单聊、群聊、聊天室消息存储到聊天服务器,方便用户在更换设备或删除本地消息后,通过服务端获取历史消息。消息存储时间,详见各套餐版本的[消息存储时长](limitation.html#消息存储时长限制)。 - -## 用户相关 - -### 用户 ID - -用户 ID 即用户名,是 App Key 内用户的唯一标识,代码中出现的“username”、“userId”、“user”参数指定了用户 ID。用户 ID 不同于即时通讯系统服务器为用户创建的 UUID。 - -### UUID - -即时通讯服务器为 App Key 内用户创建的唯一 ID,不同于用户 ID。 - -### 用户属性 - -用户属性指用户的信息,如用户昵称、头像、邮箱、电话、性别、签名、生日等。例如,在招聘场景下,利用用户属性功能,可以存储性别、邮箱、用户类型(面试者)、职位类型(Web 研发)等。当查看用户信息时,可以直接查询服务器存储的用户属性信息。 - -### 离线 - -离线是指用户成功登出环信即时通讯 IM 系统或与即时通讯 IM 系统断开连接后的状态。用户登出即时通讯 IM 系统之后,无法发送和接收消息,在下次登录后可以接收到离线消息。 - -## 封禁用户 - -禁止用户使用即时通讯 IM 服务。封禁后,用户无法连接即时通讯 IM 服务器。 - -### 用户黑名单 - -用户将不会接收黑名单中用户发送的消息。 - -## 单聊 - -单聊即一对一聊天,支持全类型消息。参与聊天的双方可以是好友也可以是陌生人。 - -## 群组 - -群组是支持多人沟通的即时通讯系统,成员关系相对稳定。所有群成员可在群中收发送消息。当群成员离线时,可以收到推送消息。群组分为公开群和私有群,公开群可以被搜索到,非群成员可以加入;私有群不能被搜索到,需要群主或群管理员添加用户进入。群组成员支持多种角色:群主、群管理员、群成员。群组提供丰富的管理能力,例如,群组禁言、黑名单和白名单等。 - -### 群主 - -群主即群组的创建者,在群中拥有最高权限,可以指定管理员、解散群组、更改群组信息以及对群组成员进行管理。 - -群主也可以将群主权限转移给群组其他成员。 - -### 群管理员 - -由群主授权,协助进行管理,拥有一定管理权限。可以对群组成员进行管理。 - -### 群成员 - -群组的普通成员,可以收发消息和查看群组描述信息,不具备群组管理权限。 - -### 群组黑名单 - -群主和管理员可以将群组成员加入黑名单,加入群黑名单的用户不能在群中发送消息。 - -### 群组白名单 - -群主和管理员可以将群组成员加入白名单。群组开启全局禁言时,只有白名单中的用户可以在群组中发送消息。 - -## 聊天室 - -聊天室是支持多人加入的组织。聊天室中的成员没有固定关系,一旦离线后,不会收到聊天室中的任何消息,(除了聊天室白名单中的成员)超过 2 分钟会自动退出聊天室。聊天室可以应用于直播、消息广播等。 - -### 聊天室黑名单 - -聊天室创建者和管理员可以将聊天室成员加入黑名单,被加入聊天室黑名单的用户不能在聊天室中发送消息。 - -### 聊天室白名单 - -聊天室创建者和管理员可以将聊天室成员加入白名单,聊天室开启全局禁言时,只有白名单中的用户可以在聊天室中发送消息。 - -### 聊天室创建者 - -聊天室的创建者,在聊天室中拥有最高权限。可以指定管理员、解散聊天室、更改聊天室信息、对聊天室成员进行管理。 - -### 聊天室管理员 - -由聊天室所有者授权,协助进行管理,拥有一定管理权限。可以对聊天室成员进行管理。 - -### 聊天室成员 - -聊天室的普通成员,不具备聊天室管理权限。 - -## RESTful 接口 - -环信即时通讯 IM 的服务器端接口都是通过 RESTful 服务方式提供的,RESTful API 基于最简单的 HTTP 协议,在各个编程语言中都提供了良好的支持。 - -环信即时通讯 IM RESTful 平台提供一个多租户用户体系,以集合(Collection)的形式的形式管理资源,一个集合包括数据库、企业、应用、用户、群组、消息和文件等。 - -## 离线推送 - -离线推送是指当应用被杀死时,通过厂商推送接收消息。iOS 设备使用苹果推送通知服务(APNs),Android 设备为谷歌云消息传递服务(FCM)、华为推送、小米推送、魅族推送、OPPO 推送和 vivo 推送。 - -## 在线状态订阅 - -用户在线状态(即 Presence)包含用户的在线、离线以及自定义状态。环信即时通讯 IM 提供发布、订阅和查询用户的在线状态的功能。 - -## 消息表情回复 Reaction - -在单聊和群聊中对消息添加、删除表情。表情可以直观地表达情绪,利用 Reaction 可以提升用户的使用体验。同时在群组中,利用 Reaction 可以发起投票,根据不同表情的追加数量来确认投票。 - -## 子区 - -子区是建立在群组内一条消息上的支持多人沟通的即时通讯系统,子区成员是群组成员的子集。 - -## 子区消息 - -子区消息是子区内发送和接收的消息。 \ No newline at end of file diff --git a/docs/product/help.md b/docs/product/help.md deleted file mode 100644 index de92cc95..00000000 --- a/docs/product/help.md +++ /dev/null @@ -1,31 +0,0 @@ -# 帮助中心 - - - -## 技术支持 - -环信即时通讯云提供三种形式的技术支持:智能助手咨询,支持邮箱和工单咨询。 - -### 智能助手 - -登录 IM Console,点击屏幕下方的智能助手,咨询问题。 - -### 支持邮箱 - -技术咨询邮箱:support@easemob.com。 - -### 提交工单 - -登录 IM Console,请进入您遇到问题的 APP,然后点击屏幕下方的技术咨询,提交工单。工单的响应时间是一个工作日内。 - -![](/images/product/help-ticket1.jpeg) - -![](/images/product/help-ticket2.jpeg) - -## IM Geek 社区 - -[IM Geek 开发者社区](https://www.imgeek.net) 中的环信专区/环信技术交流板块提供了集成常见问题的讨论和解答,供您参考。您也可以登录该社区后,在导航栏点击 **发起** > **问题**发帖提问,我们的技术和服务人员会及时解答您的疑问! - -## 开发者周刊 - -[环信开发者周刊](https://www.easemob.com/weekly) 是为环信开发者量身定制的技术周刊,包含产品快递、行业新闻、行业活动、社区活动、问答专栏,帮助开发者全面了解环信。 \ No newline at end of file diff --git a/docs/product/introduction.md b/docs/product/introduction.md deleted file mode 100644 index 2f051c41..00000000 --- a/docs/product/introduction.md +++ /dev/null @@ -1,198 +0,0 @@ -# 产品概述 - - - -环信即时通讯为开发者提供高可靠、低时延、高并发、安全、全球化的通信云服务,支持单聊、群聊、聊天室。提供多平台 SDK 支持,包括:Android、iOS、Web、Windows、Linux、Unity、Flutter、React Native、小程序、uni-app 和 Electron;同时,提供 EaseIM 和 EaseIMKit 以及服务端 REST API,帮助开发者快速构建端到端通信的场景。 - -## 平台架构 - -![环信 IM 后台](/images/product/framework.png) - -## 集成概述 - -在 [环信即时通讯控制台](enable_and_configure_IM.html) 注册和开通服务后,开发者需要了解服务端和客户端的交互过程,如下图所示。 - -![img](/images/product/integration-overview.png) - -服务端和客户端集成以及 Demo 介绍详见下表中的链接文档。 - -| 项目 | 链接 | -| :--------- | :----- | -| 服务端集成 | [环信即时通讯 REST API 概览](/document/server-side/overview.html)。 | -| 客户端 Demo 体验 |
- [Android Demo(EaseIM App)](/document/android/demo.html)
- [iOS Demo(EaseIM App)](/document/ios/demo.html)
- [React Demo(WebIM)](/document/web/demo_react.html)
- [Vue Demo(WebIM)](/document/web/demo_vue.html) | -| 客户端集成|
- [Android 快速开始](/document/android/quickstart.html) 和 [集成概述](/document/android/integration.html)
- [iOS 快速开始](/document/ios/quickstart.html)和 [集成概述](/document/ios/integration.html)
- [Web 快速开始](/document/web/quickstart.html)和[集成概述](/document/web/integration.html)
- [Windows 快速开始](/document/windows/quickstart.html)和 [集成概述](/document/windows/integration.html)
- [Linux 集成概述](/document/linux/overview.html)
- [Unity 快速开始](/document/unity/quickstart.html)和[集成概述](/document/unity/integration.html)
- [Flutter 快速开始](/document/flutter/quickstart.html)和[集成概述](/document/flutter/integration.html);
- [React Native 快速开始](/document/react-native/quickstart.html)和[集成概述](/document/react-native/integration.html)
- [Electron 集成概述](/document/electron/overview.html)
- [uni-app 集成概述](/document/applet/uniapp.html)| - - -## 功能概述 - -用环信即时通讯能实现以下功能: - -### 单聊 - -单聊,即一对一聊天,支持丰富的消息类型,以及离线消息、漫游消息等功能。 - -### 群组聊天和聊天室 - -[群组聊天](/document/android/group_overview.html)和[聊天室](/document/android/room_overview.html),支持丰富的消息类型,支持完整的群组和聊天室管理能力。 - -群组和聊天室的聊天功能类似,区别详见 [群组概述](/document/android/group_overview.html#群组与聊天室的区别)。下表以群组为例,介绍群组和聊天室的功能。 - -| 功能 | 描述 | -| :--------- | :----- | -| [群组管理](/document/android/group_manage.html) |
- 创建、解散群组;
- 获取群组详情、群组列表和群成员列表;
- 查询当前用户已加入的群组数量;
- 屏蔽和解除屏蔽群消息。 | -| [群成员管理](/document/android/group_members.html) |
- 加入、退出群组;
- 设置和获取群成员的自定义属性;
- 变更群主和群管理员的管理;
- 白名单;
- 黑名单;
- 禁言。| -| [群组属性管理](/document/android/group_attributes.html) |
- 修改群组名称、描述和公告;
- 管理群组共享文件;
- 支持群扩展字段| - -### 消息 - -消息表示发送方对接收方发送的内容,消息包括多种类型,如:文本、图片、语音、视频、位置、透传、红包和礼物等自定义消息、合并消息和定向消息等。消息功能如下所示: - -- [发送、接收消息](/document/android/message_send_receive.html); -- [获取服务端和本地消息](/document/android/message_retrieve.html); -- [撤回消息](/document/android/message_recall.html); -- [修改消息](/document/android/message_modify.html); -- [消息回执](/document/android/message_receipt.html):送达回执和已读回执; -- [消息翻译](/document/android/message_translation.html); -- [搜索](/document/android/message_search.html)、[导入、插入](/document/android/message_import_insert.html)和[删除](/document/android/message_delete.html)消息; -- [获取消息流量统计](/document/android/message_traffic_statis.html)。 - -### 会话 - -会话是一个单聊、群聊或者聊天室所有消息的集合。用户需在会话中发送消息、查看或清空历史消息等操作。 - -会话功能如下所示: - -- [会话列表](/document/android/conversation_list.html):获取服务端和本地的会话列表。 -- [会话未读数](/document/android/conversation_unread.html):获取会话未读数和清零。 -- [置顶](/document/android/conversation_pin.html)、[标记](/document/android/conversation_mark.html)、[删除](/document/android/conversation_delete.html)会话。 - -### 用户管理 - -支持用户体系、用户属性和用户关系管理功能: - -- [用户体系](/document/server-side/user_relationship.html):用户账号的注册、删除、修改用户密码、获取用户在线状态和指定账号的在线登录设备。 -- [用户属性](/document/android/userprofile.html):设置和获取用户属性,包括用户头像、昵称和自定义信息。 -- [用户关系](/document/android/user_relationship.html):好友管理,包括添加/删除好友,将好友添加或移除黑名单等。 - -### 离线推送 - -客户端断开连接或应用进程被关闭等原因导致用户离线时,即时通讯 IM 会通过第三方消息推送服务向该离线用户的设备推送消息通知。当用户再次上线时,服务器会将离线期间的消息发送给用户,确保用户收到离线期间的消息。 - -[Android 推送](/document/android/push/push_overview.html)支持 Firebase Cloud Message(FCM)、华为、OPPO、小米、vivo 和魅族推送。[iOS 推送](/document/ios/push/push_overview.html)使用 Apple Push Notification service(APNs) 。 - -### 多设备登录 - -环信支持同一账号同时登录多台设备,可实现终端用户的消息通过服务器保存和同步,确保各端均能收发消息同步。 - -[多设备登录](/document/android/multi_device.html)的情况下,可同步以下信息和操作: - -- 消息:包括在线消息、离线消息、推送通知(若开启了第三方推送服务,离线设备收到)以及对应的回执和已读状态等; -- 好友和群组相关操作; -- 子区相关操作; -- 会话相关操作。 - -### 在线状态订阅 - -[用户在线状态](/document/android/presence.html)(即 Presence)包含用户的在线、离线以及自定义状态。 - -- [发布自定义在线状态](/document/android/presence.html#发布自定义在线状态); -- [订阅](/document/android/presence.html#订阅指定用户的在线状态)/[取消订阅](/document/android/presence.html#取消订阅指定用户的在线状态)用户的在线状态; -- [查询订阅列表](/document/android/presence.html#查询被订阅用户列表)、[查询用户当前在线状态](/document/android/presence.html#获取用户的当前在线状态)。 - -### 消息表情回复 - -环信即时通讯 IM 提供消息表情回复(简称 “Reaction”)功能。用户可以在单聊和群聊中对消息添加、删除表情。表情可以直观地表达情绪,利用 Reaction 可以提升用户的使用体验。同时在群组中,利用 Reaction 可以发起投票,根据不同表情的追加数量来确认投票。 - -Reaction 的功能如下: - -- [添加](/document/android/reaction.html#在消息上添加-reaction)、[删除](/document/android/reaction.html#删除消息的-reaction) Reaction; -- [获取消息的 Reaction 列表](/document/android/reaction.html#获取消息的-reaction-列表); -- [获取 Reaction 详情](/document/android/reaction.html#获取-reaction-详情)。 - -### 子区 - -子区是群组成员的子集,是支持多人沟通的即时通讯系统,支持以下功能: - -- [子区管理](/document/android/thread.html):创建、解散、加入、退出子区; -- [获取子区信息](/document/android/thread.html#获取子区详情):获取子区详情、最新消息、子区列表和成员列表; -- [子区消息管理](/document/android/thread_message.html):发送、接收、撤回和获取子区消息。 - -### 内容审核 - -支持使用 IM [内容审核服务](/product/moderation/moderation_overview.html)对消息内容进行多样化场景检测,帮助您对应用消息内容进行管控,规避内容违规风险。 - -- 多消息类型审核:智能识别文本、图片和音视频文件; - -- 自定义消息处置规则:自定义消息下发或拦截的策略; - -- 消息审核结果可回调:支持将消息审核结果回调至客户服务器; - -- 一站式内容审核后台:提供可视化的内容审核后台,支持查询审核记录、审核数据统计。 - -### 场景方案 - -#### 超级社区 - -[环信超级社区(Circle)](/product/circle/circle_overview.html)是一款基于环信 IM 打造的类 Discord 实时社区应用场景方案,支持社区(Server)、频道(Channel) 和子区(Thread) 三层结构。一个 App 下可以有多个社区,同时支持陌生人/好友单聊。用户可创建和管理自己的社区,在社区中设置和管理频道将一个话题下的子话题进行分区,在频道中根据感兴趣的某条消息发起子区讨论,实现万人实时群聊,满足超大规模用户的顺畅沟通需求。 - -#### 语聊房 - -[环信语聊房(Easemob Chat Room)](/product/voiceroom/demo_scenario_introduction.html)场景方案是环信打造的一款低门槛、高可用的语聊房场景方案。该场景方案融合了环信即时通讯云的聊天室和声网 RTC 的音频技术,提供市面主流的语聊房 App 的功能,其核心功能包括房间管理、麦位控制、聊天打赏和音频特效等,覆盖语音游戏、语音社交、相亲交友等场景,能够较为全面满足客户的语聊房开发需求。同时,环信 IM 的聊天室中的 KV 属性管理和自动销毁以及消息优先级等功能能够对语聊房的功能性进行有效补充和拓展。 - -## 适用场景 - -环信适用于端到端实时消息沟通的场景: - -- 应用内聊天(如:陌生人社交、相亲等) - - 支持丰富的消息类型、好友关系管理 - - 支持群管理能力、群公告设置、群角色设置等 -- 应用内通知 - - 支持广播消息、自定义通知消息等 - - 支持用户管理,包括储存用户信息、用户封禁等 -- 视频/语音直播 - - 支持聊天室管理能力 - - 支持丰富类型的聊天室消息,包括弹幕、红包、礼物等 -- 企业协作 - - 支持用户管理,设置企业组织架构、好友关系管理 - - 支持群管理能力、群公告设置、群附件发送、群角色设置等 -- 买家卖家沟通 - - 支持订单通知、问候语设置、自定义消息发送 - - 支持卖家内部管理、公告设置、成员管理等 -- 线上问诊 - - 支持丰富的消息类型,图文病情描述、语音消息等 - - 支持用户信息存储、用户身份管理等 - -## 产品优势 - -环信主要有以下优势: - -### 全球部署 - -环信在全球设有五大数据中心、200+ 边缘加速节点,网络服务覆盖全球 200 多个国家和地区。 - -### 低延时 - -环信全球平均延时小于 200 毫秒,相同区域平均延时小于 100 毫秒。 - -### 高并发 - -环信支持同时在线人数无上限,聊天室亿级消息并发。 - -### 高可靠性 - -环信数据中心同城三中心部署,SLA 99.95%。 优异的弱网对抗能力,70% 丢包情况下消息到达率 100%。 - -### 多平台 - -环信即时通讯 IM 支持 Android、iOS、Web 等平台,而且各平台之间可互通。下表为即时通讯支持的各平台版本: - -| 平台 | 支持的版本 | -| ------------ | ------------------------------------------------------------ | -| Android | Android 5.0 或以上版本(API 级别 21 或以上) | -| iOS | iOS 10.0 或以上版本 | -| Web |
- Internet Explorer 9 或以上
- FireFox 10 或以上
- Chrome 54 或以上 Safari 6 或以上
- Edge 12 或以上
- Opera 58 或以上
- iOS Safari 7 或以上
- Android Browser 4.4 (KitKat) 或以上 | -| HarmonyOS | HarmonyOS NEXT(API 级别 12 或以上) | -| Unity | Unity 2017 或以上版本 | -| Windows | Windows 10 或以上版本 | -| React Native | React Native 0.63.4 或以上版本 | -| Flutter | Flutter 2.10 | \ No newline at end of file diff --git a/docs/product/limitation.md b/docs/product/limitation.md deleted file mode 100644 index efd895fb..00000000 --- a/docs/product/limitation.md +++ /dev/null @@ -1,252 +0,0 @@ -# 产品相关限制 - - - -本文简要介绍环信即时通讯 IM 的使用限制条件,包括调用频率、字符串大小和编码格式等。 - -## 消息相关 - -### 消息大小 - -对于不同的消息类型,消息长度限制如下: - -| 消息类型 | 消息长度限制 | -| :------------- | :----------------------------------- | -| 文本消息 | 5 KB。 | -| 图片消息 | 图片不能超过 10 MB,图片消息大小限制为 5 KB。 | -| 语音消息 | 音频文件不能超过 10 MB,语音消息大小限制为 5 KB。 | -| 视频消息 | 视频文件不能超过 10 MB,视频消息大小限制为 5 KB。 | -| 文件消息 | 附件大小不能超过 10 MB,文件消息大小限制为 5 KB。 | -| 透传消息 | 5 KB。 | -| 自定义消息 | 5 KB。 | -| 合并消息 | 5 KB。 | -| 定向消息 | 5 KB。 | - -:::tip -默认情况下,消息附件,例如图片、音频、视频和其他文件不能超过 10 MB,存储天数详见[消息存储](#消息存储)。 -::: - -### 消息存储 - -- **历史消息**:在服务器上的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。 -- **聊天记录文件**:可从服务端获取用户的聊天记录文件。 - - 单次请求获取从指定起始时间开始一小时内的发送的聊天记录文件。 - - 你最多可以获取最近 3 天的聊天记录。若要提升该限制,你需要联系环信商务。 - - 查询历史消息记录时存在一定延时,无法实时获取。 -- **消息附件/文件**:默认情况下,消息附件,例如图片、音频、视频和其他文件可存储 7 天。若要提升其中一个上限,请联系商务。消息附件的大小及存储时间限制与群组共享文件的相同。如果消息附件的其中一个限制进行了上调,群组共享文件的对应限制也会随之自动调整,反之亦然。 -- **离线消息**:对于单聊和群聊,离线消息默认保存 7 天。对于每个终端用户,所有的单聊会话可存储 500 条离线消息,所有的群聊会话可存储 200 条离线消息。若超过存储天数和条数的上限,最新的离线消息会挤掉最早的。如需提升上限,可联系商务。 -- **各类事件通知**:事件通知的存储时间与消息的存储一致。 - - -### 消息撤回 - -默认情况下,发送方可撤回发出 2 分钟内的消息。你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**功能配置** > **功能配置总览** > **基础功能**页面设置消息撤回时长,该时长不超过 7 天。 - -:::tip -除了透传消息,其他各类型的消息都支持撤回。 -::: - -### 消息回执 - -- 单聊会话支持消息送达回执、会话已读回执和消息已读回执。 -- 群聊会话只支持消息已读回执。 - -群消息已读回执特性的使用限制如下表所示: - -| 使用限制| 默认 | 描述 | -| :--------- | :----- | :------- | -| 功能开通 | 关闭 | 若要使用该功能,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **功能配置** > **功能配置总览**> **基础功能**页签下,搜索找到 **消息已读回执(群聊)** 开通功能。具体费用详见[产品价格](/product/pricing.html#增值服务费用)。 | -| 使用权限 | 所有群成员 | 默认情况下,所有群成员发送消息时可要求已读回执。如果仅需群主和群管理员发消息时要求已读回执,可联系商务修改。 | -| 已读回执有效期 | 3 天 | 群聊已读回执的有效期为 3 天,即群组中的消息发送时间超过 3 天,服务器不记录阅读该条消息的群组成员,也不会发送已读回执。 | -| 群规模 | 200 人 | 该特性最大支持 200 人的群组。如果超过 200 人/群,群成员发送的消息不会返回已读回执。你可以联系商务提升群成员人数上限。 | -| 查看返回已读回执数量 | 消息发送方 | 对消息返回的已读回执数量(或返回已读回执的人数),默认仅消息发送方可查看。如需所有群成员均可查看,可联系商务开通。 | - -### 修改消息 - -- 只能修改单聊或群组聊天会话中已经发送成功的文本消息。 -- 聊天室会话不支持消息修改功能。 -- 一条消息默认最多可修改 10 次。 - -### 转发消息 - -合并转发支持嵌套,最多支持 10 层嵌套,每层最多 300 条消息。 - -### 定向消息 - -- 适用于群组或聊天室会话。 -- 最多可向 20 个成员发送定向消息。 -- 适用于文本消息、图片消息和音视频消息等全类型消息。 -- 对于单聊会话,只有消息发送方才能对消息进行修改。 -- 对于群聊会话,普通群成员只能修改自己发送的消息。群主和群管理员除了可以修改自己发送的消息,还可以修改普通群成员发送的消息。 - -### 聊天室全局广播消息 - -你可以[调用 REST API 发送聊天室全局广播消息](/document/server-side/message_chatroom.html#发送聊天室全局广播消息)。该功能默认关闭,如果需要,请联系环信商务开通。 - -### 置顶消息 - -- 该功能只支持群组和聊天室会话,不支持单聊。 -- 单个会话默认可置顶 20 条消息。你可以联系环信商务提升该上限,最大可调整至 100。 - -### 消息仅投递在线用户 - -该功能只支持单聊和群组聊天,不支持聊天室。 - -### 消息表情回复 - -- 一个消息表情即为一个 Reaction,若不同用户重复添加同一消息表情,Reaction 数量计为 1。 -- 对于同一条 Reaction,一个用户只能添加一次,重复添加会报错误 1301。 -- 每条消息默认可添加 20 个 Reaction,若需提升该上限,需联系环信商务。 -- 创建 Reaction 时,设置的表情 ID 长度不能超过 128 个字符,对支持的字符集类型没有限制,但服务端与客户端的设置必须保持一致。若使用特殊字符,获取和删除 Reaction 时需对特殊字符进行 URL 编码。 - -### 获取消息流量统计 - -- SDK 只支持统计该功能开启后最近 30 天内发送和接收的消息。 -- 仅 Android and iOS 端 SDK 支持该功能。 - -### 消息举报 - -举报消息的原因不能超过 512 字节。 - -## 会话 - -### 会话列表 - -对于每个终端用户,服务器默认存储 100 条会话。若提升该上限,需联系环信商务。如果你的会话条数超过了上限,新会话会覆盖之前的不活跃会话。 - -### 置顶会话 - -你最多可以置顶 50 个会话。 - -### 会话标记 - -- 支持对单聊和群组会话添加标记,不支持为聊天室聊天添加会话标记。 -- 一个会话最多可添加 20 个标记。 -- 每次最多可为 20 个会话添加标记。 -- 每次最多可移除 20 个会话的同一标记。 - -## 群组 - -### 群组/群成员数量 - -- 群组总数、单个群的成员数和用户可加入的群组数取决于套餐版本,详见[套餐包功能详情](pricing.html#套餐包功能详情)。 -- 对于单个群组,群主加管理员数量不能超过 100,即管理员最多可添加 99 个。 -- 群组按照规模,可以分为普通群和大型群: - - 普通群:群成员总数不超过 3000 人。 - - 大型群:群成员总数超过 3000 人。大型群不支持离线推送。如需默认创建大型群,请联系环信商务。 - -### 群组/群成员属性 - -- 群组名称,字符串类型,最大长度为 128 字符。 -- 群组描述,字符串类型,最大长度为 512 字符。 -- 群公告的长度限制为 512 个字符。 -- 群组扩展信息,例如可以给群组添加业务相关的标记,最大长度为 8 KB。 -- 单个群成员的自定义属性(key-value)总长度不能超过 4 KB。对于单个自定义属性,属性 key 不能超过 16 字节,value 不能超过 512 个字节。 - -### 群组共享文件 - -- 单个群组共享文件大小上限默认 10 MB。如果需要提升限制,请联系商务。 - 该限制与消息附件的相同。如果消息附件的长度进行了上调,群组共享文件大小也会随之自动调整,反之亦然。 -- 单个群组最多上传 10,000 个共享文件。 -- 群组共享文件在服务器的存储时间与消息附件相同,即默认为 7 天。如果需要提升限制,请联系商务。 - 如果消息附件在服务器上的存储时间进行了上调,群组共享文件的存储时间也会随之自动调整,反之亦然。 - -### 子区 - -- 单个 app 下的子区总数默认为 10 万,如需调整请联系商务。 -- 子区名称,不能超过 64 个字符。 - -## 聊天室 - -不同套餐版本支持的聊天室总数,详见[套餐包功能详情](pricing.html#套餐包功能详情)。 - -### 聊天室成员 - -- 聊天室成员数上限(包括聊天室所有者)默认最大值为 10,000,如需调整请联系商务。 -- 聊天室创建者和管理员的数量之和不能超过 100,即管理员最多可添加 99 个。 -- 聊天室中的成员(除了聊天室白名单中的成员)离线超过 2 分钟会自动退出聊天室。 - -### 聊天室基本属性 - -- 聊天室名称,字符串类型,最大长度为 128 字符。 -- 聊天室描述,字符串类型,最大长度为 512 字符。 -- 聊天室公告,字符串类型,最大长度为 512 字符。 -- 聊天室扩展信息不能超过 8 KB。 - -### 聊天室自定义属性(key-value) - -每个聊天室最多支持 100 个自定义属性,每个应用的聊天室自定义属性总大小不超过 10 GB。 - -聊天室自定义属性为键值对(key-value)结构,单个 key 不能超过 128 个字符,支持以下字符集: -- 26 个小写英文字母 a-z; -- 26 个大写英文字母 A-Z; -- 10 个数字 0-9; -- “_”, “-”, “.”。 - -每个聊天室属性 value 不能超过 4096 个字符。 - -## 用户相关 - -### 用户注册 - -- 用户 ID:长度不能超过 64 字节,支持以下字符集: - - 26 个小写英文字母 a-z; - - 26 个大写英文字母 A-Z; - - 10 个数字 0-9; - - “_”, “-”, “.”。 - -:::tip -- 该参数不区分大小写,因此 Aa 和 aa 为相同用户名。 -- 请确保同一个 app 下,用户 ID 唯一。 -- 用户 ID 是会公开的信息,请勿使用 UUID、邮箱地址、手机号等敏感信息。 -::: - -- 密码:用户的登录密码,长度不可超过 64 个字符。 - -### 用户属性 - -- 默认单个用户的属性总长不得超过 2 KB。 -- 默认单个 app 下所有用户的属性总长度不得超过 10 GB。 - -### 用户关系 - -- 单个 App Key 下的每个用户的好友数量上限与套餐包版本相关,详见[套餐包功能详情](/product/pricing.html#套餐包功能详情)。 -- 好友备注的长度不能超过 100 个字符。 -- 每个用户的黑名单最多可存 500 个用户。 - -### 在线状态订阅 - -- 订阅时长最长为 30 天,过期需重新订阅。如果未过期的情况下重复订阅,新设置的有效期会覆盖之前的有效期。 -- 每次调用接口最多只能订阅 100 个账号,若数量较大需多次调用。 -- 每个用户 ID 订阅的用户数不超过 3000。如果超过 3000,后续订阅也会成功,但默认会将订阅剩余时长较短的替代。 -- 每个用户最多可被 3000 个用户订阅。 - -## 离线推送 - -### 推送昵称 - -离线推送时在接收方的客户端推送通知栏中显示的发送方的昵称支持自定义,长度不能超过 100 个字符,支持以下字符集: -- 26 个小写英文字母 a-z; -- 26 个大写英文字母 A-Z; -- 10 个数字 0-9; -- 中文; -- 特殊字符。 - -### 推送模板名称 - -- 添加默认的推送模板时,模板名称应设置为 `default`。 -- 自定义模板的名称最多可包含 64 个字符,支持以下字符集: - - 26 个小写英文字母 a-z; - - 26 个大写英文字母 A-Z; - - 10 个数字 0-9。 - -### 多设备登录 - -- 多端登录时,即时通讯 IM 每端默认最多支持 4 个设备同时在线。如需提升上限,可联系环信商务。 - -- 自定义设置登录设备的平台时,设备平台的取值范围为 [1,100],设备数量的取值范围为 [0,4]。 - -## 调用频率限制 - -关于 RESTf API 的调用频率限制,详见 [Rest API 调用频率限制](limitationapi.html)。 - diff --git a/docs/product/limitationapi.md b/docs/product/limitationapi.md deleted file mode 100644 index 85709ccc..00000000 --- a/docs/product/limitationapi.md +++ /dev/null @@ -1,274 +0,0 @@ -# Restful API 调用频率限制 - - - -除部分 API 接口有特殊说明外,API 调用频率限制默认为 100 次/秒,你可以按模块查看每个接口的调用频率限制。 - -在环信即时通讯 IM 系统中,大部分客户端接口的调用实际上是通过对应的 RESTful API 来实现的。 -- 下表中标注 * 的 RESTful API 没有对应的客户端接口,因此它们的调用频率仅由相应的 RESTful API 的调用频率决定。若这些接口的调用频率达到上限,你可以联系环信商务提升。 -- 其他接口,其调用频率则为 RESTful API 和对应客户端接口调用频率的总和。若这些接口的调用频率达到上限,你可以查看是否是客户端 API 调用过于频繁。如果需要提升调用频率上限,可联系环信商务。 - - -## 消息管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :-------- | :----- | :---------------- | :--------------------- | -| * 发送单聊消息 | POST | /{org_name}/{app_name}/messages/users | 对于单个 app,该 REST API 存在以下三个限制:
- 100 次/秒/App Key
- 6000 条/分钟
- 600 人/次。若一次向 600 人发消息,视为 600 条消息。 | -| * 发送群聊消息 | POST | /{org_name}/{app_name}/messages/chatgroups | 对于单个 app,该 REST API 存在以下三个限制:
- 20 条/秒/App Key
- 20 次/秒
- 3 个群/次 | -| * 发送定向消息 | POST | /{org_name}/{app_name}/messages/chatgroups/users | 100 条/秒/App Key | -| * 发送聊天室消息 | POST | /{org_name}/{app_name}/messages/chatrooms | 对于单个 app,该 REST API 存在以下三个限制:
- 100 条/秒
- 20 次/秒
- 10 个聊天室/次 | -| * 发送聊天室广播消息 | POST | /{org_name}/{app_name}/messages/chatrooms/broadcast | 每分钟最多可发 10 次,而且每天最多可发 100 次广播消息。 | -| 上传文件 | POST | /{org_name}/{app_name}/chatfiles | 100 次/秒/App Key | -| 下载文件 | GET | /{org_name}/{app_name}/chatfiles/{file_uuid} | 100 次/秒/App Key | -| * 获取历史消息(聊天记录)文件 | GET | /{org_name}/{app_name}/chatmessages/${time} | 10 次/分钟/App Key | -| * 设置指定消息附件的存储方式 | POST | /{org_name}/{app_name}/users/{username}/chatfiles/lifetime | 100 次/秒/App Key | -| * 服务端消息撤回 | POST | /{org_name}/{app_name}/messages/recall | 100 次/秒/App Key | -| 服务端单向删除会话 | DELETE | /{org_name}/{app_name}/users/{userName}/user_channel | 5 次/分钟/单用户 ID,100 次/秒/App Key | -| 修改文本或自定义消息 | PUT | /{org_name}/{app_name}/messages/rewrite/{msg_id} | 100 次/秒/App Key | -| 根据消息 ID 单向删除单聊漫游消息 | DELETE | /{org_name}/{app_name}/rest/message/roaming/chat/user/{userId}?userId={userId}&msgIdList={msgIdList} | 100 次/秒/App Key | -| 根据消息 ID 单向删除群聊漫游消息 | DELETE | /{org_name}/{app_name}/rest/message/roaming/group/user/{userId}?groupId={groupId}&msgIdList={msgIdList} | 100 次/秒/App Key | -| 单向清空指定用户的漫游消息 | POST | /{org_name}/{app_name}/rest/message/roaming/user/{userId}/delete/all | 100 次/秒/App Key | -| 单向清空单聊会话某个时间点及之前的漫游消息 | POST | /{org_name}/{app_name}/rest/message/roaming/chat/user/{userId}/time?userId={userId}&delTime={delTime} | 100 次/秒/App Key | -| 单向清空群组或聊天室会话某个时间点及之前的漫游消息 | POST | /{org_name}/{app_name}/rest/message/roaming/group/user/{userId}/time?groupId={groupId}&delTime={delTime} | 100 次/秒/App Key | -| 导入单聊消息 | POST | /{org_name}/{app_name}/messages/users/import | 100 条/秒/App Key | - -### 消息表情回复 Reaction - -| RESTful API 接口 | 方法 | 接口 URL | 接口最高调用频率(默认值) | -| :------------------- | :----- | :------------------------ | :----------- | -| 创建/添加 Reaction | POST | /{org_name}/{app_name}/reaction/user/{userId} | 100 次/秒/App Key | -| 根据消息 ID 获取 Reaction | GET | /{org_name}/{app_name}/reaction/user/{userId} | 100 次/秒/App Key | -| 删除 Reaction | DELETE | /{org_name}/{app_name}/reaction/user/{userId} | 100 次/秒/App Key | -| 根据消息 ID 和表情 ID 获取 Reaction 信息 | GET | /{org_name}/{app_name}/reaction/user/{userId}/detail | 100 次/秒/App Key | - -## 群组 - -### 群组管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :--------------- |:------ | :------------ | :----------- | -| 分页获取 app 中的群组 | GET | /{org_name}/{app_name}/chatgroups?limit={N}&cursor={cursor} | 100 次/秒/App Key | -| 获取一个用户加入的所有群组 | GET | /{org_name}/{app_name}/chatgroups/user/{username}?pagesize={}&pagenum={} | 50 次/秒/App Key | -| 查看指定用户是否已加入群组 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/user/{user_id}/is_joined | 100 次/秒/App Key | -| 获取群组详情 | GET | /{org_name}/{app_name}/chatgroups/{group_ids} | 100 次/秒/App Key | -| 创建群组 | POST | /{org_name}/{app_name}/chatgroups | 100 次/秒/App Key | -| 封禁群组 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/disable | 100 次/秒/App Key | -| 解禁群组 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/enable | 100 次/秒/App Key | -| 修改群组信息 | PUT | /{org_name}/{app_name}/chatgroups/{group_id} | 100 次/秒/App Key | -| 解散群组 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id} | 100 次/秒/App Key | -| 获取群组公告 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/announcement | 100 次/秒/App Key | -| 修改群组公告 | POST| /{org_name}/{app_name}/chatgroups/{group_id}/announcement | 100 次/秒/App Key | -| 分页获取群组共享文件 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/share_files?pagenum=1&pagesize=10 | 100 次/秒/App Key | -| 上传群组共享文件 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/share_files | 100 次/秒/App Key | -| 下载群组共享文件 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/share_files/{file_id} | 100 次/秒/App Key | -| 删除群组共享文件 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/share_files/{file_id} | 100 次/秒/App Key | - -### 群成员管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :--------------- |:------ | :------------ | :----------- | -| 分页获取群组成员 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/users | 100 次/秒/App Key | -| 添加单个群组成员 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/users/{username} | 100 次/秒/App Key | -| 批量添加群组成员 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/users | 100 次/秒/App Key | -| 移除单个群组成员 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/users/{username} | 100 次/秒/App Key | -| 批量移除群组成员 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/users/{usernames} | 100 次/秒/App Key | -| 设置群成员自定义属性 | PUT | /{org_name}/{app_name}/metadata/chatgroup/{group_id}/user/{username} | 100 次/秒/App Key | -| 批量设置群成员自定义属性 | PUT | /{org_name}/{app_name}/metadata/chatgroup/{group_id}/users/batch | 100 次/秒/App Key | -| 获取单个群成员的所有自定义属性 | GET | /{org_name}/{app_name}/metadata/chatgroup/{group_id}/user/{username} | 100 次/秒/App Key | -| 根据属性 key 获取多个群成员的自定义属性 | POST | /{org_name}/{app_name}/metadata/chatgroup/{group_id}/get | 100 次/秒/App Key | -| 获取群管理员列表 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/admin | 100 次/秒/App Key | -| 添加群管理员 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/admin | 100 次/秒/App Key | -| 移除群管理员 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/admin/{oldadmin} | 100 次/秒/App Key | -| 转让群组 | PUT | /{org_name}/{app_name}/chatgroups/{group_id} | 100 次/秒/App Key | -| 查询群组黑名单 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/blocks/users | 100 次/秒/App Key | -| 添加单个用户至群组黑名单 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/blocks/users/{username} | 100 次/秒/App Key | -| 批量添加用户至群组黑名单 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/blocks/users | 100 次/秒/App Key | -| 从群组黑名单移除单个用户 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/blocks/users/{username} | 100 次/秒/App Key | -| 批量从群组黑名单移除用户 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/blocks/users/{usernames} | 100 次/秒/App Key | -| 查询群组白名单 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/white/users | 100 次/秒/App Key | -| 添加单个用户至群组白名单 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/white/users/{username} | 100 次/秒/App Key | -| 批量添加用户至群组白名单| POST | /{org_name}/{app_name}/chatgroups/{group_id}/blocks/users | 100 次/秒/App Key | -| 将用户移除群组白名单 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/white/users/{username} | 100 次/秒/App Key | -| 获取禁言列表 | GET | /{org_name}/{app_name}/chatgroups/{group_id}/mute | 100 次/秒/App Key | -| 禁言单个群成员 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/mute | 100 次/秒/App Key | -| 禁言全体成员 | POST | /{org_name}/{app_name}/chatgroups/{group_id}/ban | 100 次/秒/App Key | -| 解除成员禁言 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/mute/{member1}(,{member2},…) | 100 次/秒/App Key | -| 解除全员禁言 | DELETE | /{org_name}/{app_name}/chatgroups/{group_id}/ban | 100 次/秒/App Key | - -### 子区管理 - -| RESTful API 接口 | 方法 | 接口 URL | 接口最高调用频率(默认值) | -| :------------------- | :----- | :------------------------ | :----------- | -| 分页获取 app 中的子区 | GET | /{org_name}/{app_name}/thread | 100 次/秒/App Key | -| 分页获取单个用户加入的所有子区 | GET | /{org_name}/{app_name}/threads/user/{username} | 100 次/秒/App Key | -| 分页获取单个用户在指定群组中加入的所有子区 | GET | /{org_name}/{app_name}/threads/chatgroups/{group_id}/user/{username} | 100 次/秒/App Key | -| 创建子区 | POST | /{org_name}/{app_name}/thread | 100 次/秒/App Key | -| 修改子区 | PUT | /{org_name}/{app_name}/thread/{thread_id} | 100 次/秒/App Key | -| 删除子区 | DELETE | /{org_name}/{app_name}/thread/{thread_id} | 100 次/秒/App Key | -| 分页获取子区成员列表 | GET | /{org_name}/{app_name}/thread/{thread_id}/users | 100 次/秒/App Key | -| 用户批量加入子区 | POST | /{org_name}/{app_name}/thread/{thread_id}/users | 100 次/秒/App Key | -| 批量踢出子区成员 | DELETE | /{org_name}/{app_name}/threads/{thread_id}/users | 100 次/秒/App Key | - -## 聊天室 - -### 聊天室管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :--------------- |:------ | :------------ | :----------- | -| 获取 app 中的聊天室 | GET | /{org_name}/{app_name}/chatrooms?limit={N}&cursor={cursor} | 50 次/秒/App Key | -| 获取用户加入的聊天室 | GET | /{org_name}/{app_name}/users/{username}/joined_chatrooms | 50 次/秒/App Key | -| 获取聊天室详情 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id} | 100 次/秒/App Key | -| 创建一个聊天室 | POST | /{org_name}/{app_name}/chatrooms | 50 次/秒/App Key | -| 修改聊天室信息 | PUT | /{org_name}/{app_name}/chatrooms/{chatroom_id} | 100 次/秒/App Key | -| 转让聊天室 | PUT | /{org_name}/{app_name}/chatrooms/{chatroom_id} | 100 次/秒/App Key | -| 解散聊天室 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id} | 100 次/秒/App Key | -| 获取聊天室公告 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/announcement | 100 次/秒/App Key | -| 修改聊天室公告 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/announcement | 100 次/秒/App Key | -| 获取聊天室自定义属性 | POST | /{org_name}/{app_name}/metadata/chatroom/{chatroom_id} | 100 次/秒/App Key | -| 设置聊天室自定义属性 | PUT | /{org_name}/{app_name}/metadata/chatroom/{chatroom_id}/user/{username} | 100 次/秒/App Key | -| 强制设置聊天室自定义属性 | PUT | /{org_name}/{app_name}/metadata/chatroom/{chatroom_id}/user/{username}/forced | 100 次/秒/App Key | -| 删除聊天室自定义属性 | DELETE | /{org_name}/{app_name}/metadata/chatroom/{chatroom_id}/user/{username} | 100 次/秒/App Key | -| 强制删除聊天室自定义属性 | DELETE | /{org_name}/{app_name}/metadata/chatroom/{chatroom_id}/user/{username}/forced | 100 次/秒/App Key | - -### 聊天室成员管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :--------------- |:------ | :------------ | :----------- | -| 分页获取聊天室成员 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users | 100 次/秒/App Key | -| 添加单个聊天室成员 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users/{username} | 100 次/秒/App Key | -| 批量添加聊天室成员 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users | 100 次/秒/App Key | -| 删除单个聊天室成员 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users/{username} | 100 次/秒/App Key | -| 批量删除聊天室成员 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users/{usernames} | 100 次/秒/App Key | -| 获取聊天室管理员列表 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/admin | 100 次/秒/App Key | -| 添加聊天室管理员 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/admin | 100 次/秒/App Key | -| 移除聊天室管理员 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/admin/{oldadmin} | 100 次/秒/App Key | -| 查询聊天室黑名单 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/blocks/users | 100 次/秒/App Key | -| 添加单个用户至聊天室黑名单 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/blocks/users/{username} | 100 次/秒/App Key | -| 批量添加用户至聊天室黑名单 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/blocks/users | 100 次/秒/App Key | -| 从聊天室黑名单移除单个用户 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/blocks/users/{username} | 100 次/秒/App Key | -| 批量从聊天室黑名单移除用户 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/blocks/users/{usernames} | 100 次/秒/App Key | -| 查询聊天室白名单 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/white/users` | 100 次/秒/App Key | -| 添加单个用户至聊天室白名单 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/white/users/{username} | 100 次/秒/App Key | -| 批量添加用户至聊天室白名单 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/white/users | 100 次/秒/App Key | -| 将用户移除聊天室白名单 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/white/users/{username} | 100 次/秒/App Key | -| 获取聊天室的禁言列表 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/mute | 100 次/秒/App Key | -| 禁言聊天室成员 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/mute | 100 次/秒/App Key | -| 禁言聊天室全体成员 | POST | /{org_name}/{app_name}/chatrooms/{chatroom_id}/ban | 100 次/秒/App Key | -| 解除聊天室禁言成员 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/mute/{member1}(,{member2},…) | 100 次/秒/App Key | -| 解除聊天室全员禁言 | DELETE | /{org_name}/{app_name}/chatrooms/{chatroom_id}/ban | 100 次/秒/App Key | -| 按聊天室用户标签禁言 | PUT | /{org_name}/{app_name}/chatrooms/{chatroom_id}/tag/mute | 100 次/秒/App Key | -| 设置用户在聊天室中的标签 | PUT | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users/{username}/tag | 100 次/秒/App Key | -| 获取用户聊天室标签 | GET | /{org_name}/{app_name}/chatrooms/{chatroom_id}/users/{username}/tag | 100 次/秒/App Key | -| 获取超级管理员列表 | GET | /{org_name}/{app_name}/chatrooms/super_admin | 100 次/秒/App Key | -| 添加超级管理员 | POST | /{org_name}/{app_name}/chatrooms/super_admin | 100 次/秒/App Key | -| 移除超级管理员 | DELETE | /{org_name}/{app_name}/chatrooms/super_admin/{superAdmin} | 100 次/秒/App Key | - -## 用户相关 - -### 用户体系管理 - -| Restful API 接口 |方法 | 接口 URL| -| :------------ | :--- | :--------------------------- | -| 注册单个用户 | POST | /{org_name}/{app_name}/users | -| * 批量注册用户 | POST | /{org_name}/{app_name}/users | - -以上两个接口的总调用频率(默认值)为 100 次/秒/App Key。 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :----------- | :----- | :------------------- | :------------- | -| * 获取 app/用户 token | POST | /{org_name}/{app_name}/token | 300 次/秒/App Key | -| 获取单个用户 | GET | /{org_name}/{app_name}/users/{username} | 100 次/秒/App Key | -| * 批量获取用户 | GET | /{org_name}/{app_name}/users | 100 次/秒/App Key| -| * 删除单个用户 | DELETE | /{org_name}/{app_name}/users/{username} | 100 次/秒/App Key | -| * 批量删除用户 | DELETE | /{org_name}/{app_name}/users | 30 次/秒/App Key | -| * 修改用户密码 | POST | /{org_name}/{app_name}/users/{username}/password | 100 次/秒/App Key | -| * 获取用户在线状态 | GET | /{org_name}/{app_name}/users/{username}/status | 100 次/秒/App Key | -| * 批量获取用户在线状态 | POST | /{org_name}/{app_name}/users/batch/status | 50 次/秒/App Key | -| * 获取离线消息数 | GET | /{org_name}/{app_name}/users/{owner_username}/offline_msg_count | 100 次/秒/App Key | -| * 获取离线消息的状态 | GET | /{org_name}/{app_name}/users/{username}/offline_msg_status/{msg_id} | 100 次/秒/App Key | -| * 账号封禁 | POST | /{org_name}/{app_name}/users/{username}/deactivate | 100 次/秒/App Key | -| * 账号解禁 | POST | /{org_name}/{app_name}/users/{username}/activate | 100 次/秒/App Key | -| * 强制用户下线 | GET | /{org_name}/{app_name}/users/{username}/disconnect | 100 次/秒/App Key | -| * 强制用户从单设备下线 | DELETE | /{org_name}/{app_name}/users/{username}/disconnect/{resourceId} | 100 次/秒/App Key | -| * 获取指定账号的在线登录设备列表 | GET | /{org_name}/{app_name}/users/{username}/resources | 100 次/秒/App Key | - -### 用户属性 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :---------- | :----- | :-------------------- | :---------------- | -| 设置用户属性 | PUT | /{org_name}/{app_name}/metadata/user/{username} | 100 次/秒/App Key | -| 批量获取用户属性 | POST | /{org_name}/{app_name}/metadata/user/get | 100 次/秒/App Key | -| 删除用户属性 | DELETE | /{org_name}/{app_name}/metadata/user/{username} | 100 次/秒/App Key | -| 获取指定用户的所有用户属性 | GET | /{org_name}/{app_name}/metadata/user/{username} | 100 次/秒/App Key | -| * 获取 app 下的用户属性总大小 | GET | /{org_name}/{app_name}/metadata/user/capacity | 100 次/秒/App Key | - -### 用户在线状态订阅 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :--------------- |:------ | :------------ | :----------- | -| 设置用户在线状态信息 | POST | /{org_name}/{app_name}/users/{uid}/presence/{resource}/{status} | 50 次/秒/App Key | -| 批量订阅在线状态 | POST | /{org_name}/{app_name}/users/{uid}/presence/{expiry} | 50 次/秒/App Key | -| 批量获取在线状态信息 | POST | /{org_name}/{app_name}/users/{uid}/presence | 50 次/秒/App Key | -| 查询单个群组的在线成员数量 | GET | /{org_name}/{app_name}/presence/online/{group_id}/type/{query_type} | 100 次/秒/App Key | -| 取消订阅多个用户的在线状态 | DELETE | /{org_name}/{app_name}/users/{uid}/presence | 50 次/秒/App Key | -| 查询订阅列表 | GET | /{org_name}/{app_name}/users/{uid}/presence/sublist?pageNum={pagenumber}&pageSize={pagesize} | 50 次/秒/App Key | - -### 全局禁言 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :--------------- |:------ | :------------ | :----------- | -| * 设置用户全局禁言 | POST | /{org_name}/{app_name}/mutes | 100 次/秒/App Key | -| * 查询单个用户 ID 全局禁言 | GET | /{org_name}/{appName}/mutes/username | 100 次/秒/App Key | -| * 查询 app 下的所有全局禁言的用户 | GET | /{org_name}/{app_name}/mutes | 100 次/秒/App Key | - -### 用户收藏 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :---------- | :----- | :-------------------- | :---------------- | -| 分页获取用户收藏 | GET | /{org_name}/{app_name}/users/{username}/collections | 100 次/秒/App Key | -| 添加一条收藏 | POST | /{org_name}/{app_name}/users/{username}/collections | 100 次/秒/App Key | -| 批量添加用户收藏 | POST | /{org_name}/{app_name}/collections | 100 次/秒/App Key | -| 修改用户收藏的扩展信息 | PUT | /{org_name}/{app_name}/users/{username}/collections/{collectionId} | 100 次/秒/App Key | -| 删除用户收藏 | DELETE | /{org_name}/{app_name}/users/{username}/collections | 100 次/秒/App Key | - -### 用户关系管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率 | -| :------------- | :----- | :---------------- | :-------------- | -| 添加好友 | POST | /{org_name}/{app_name}/users/{owner_username}/contacts/users/{friend_username} | 100 次/秒/App Key | -| 移除好友 | DELETE | /{org_name}/{app_name}/users/{owner_username}/contacts/users/{friend_username} | 100 次/秒/App Key | -| 设置好友备注 | PUT | /{org_name}/{app_name}/user/{owner_username}/contacts/users/{friend_username} | 100 次/秒/App Key | -| 分页获取好友列表 | GET | /{org_name}/{app_name}/user/{username}/contacts?limit={N}&cursor={cursor}&needReturnRemark={true/false} | 100 次/秒/App Key | -| 一次性获取好友列表 | GET | /{org_name}/{app_name}/users/{owner_username}/contacts/users | 100 次/秒/App Key | -| * 导入好友列表 | POST | /{org_name}/{app_name}/users/{username}/contacts/import | 100 次/秒/App Key | -| 获取黑名单列表 | GET | /{org_name}/{app_name}/users/{owner_username}/blocks/users | 50 次/秒/App Key | -| 添加用户至黑名单 | POST | /{org_name}/{app_name}/users/{owner_username}/blocks/users | 50 次/秒/App Key | -| 从黑名单移除用户 | DELETE | /{org_name}/{app_name}/users/{owner_username}/blocks/users/{blocked_username} | 50 次/秒/App Key | - -## 离线推送 - -| RESTful API 接口 | 方法 | 接口 URL | 接口最高调用频率(默认值) | -| :----------- | :--- | :------------- | :----------- | -| 设置离线推送 | PUT | /{org}/{app_name}/users/{userId}/notification/{chattype}/{key} | 100 次/秒/App Key | -| 查询离线推送设置 | GET | /{org_name}/{app_name}/users/{userId}/notification/{chattype}/{key} | 100 次/秒/App Key | -| 批量设置离线推送时显示的昵称 | PUT | /{org_name}/{app_name}/push/nickname | 100 次/秒/App Key | -| 设置推送通知的首选语言 | PUT | /{org_name}/{app_name}/users/{userId}/notification/language | 100 次/秒/App Key | -| 获取推送通知的首选语言 | GET | /{org_name}/{app_name}/users/{userId}/notification/language | 100 次/秒/App Key | -| 创建离线推送模板 | POST | /{org_name}/{app_name}/notification/template | 10 次/秒/App Key | -| 查询离线推送模板 | GET | /{org_name}/{app_name}/notification/template/{name} | 10 次/秒/App Key | -| 删除离线推送模板 | DELETE | /{org_name}/{app_name}/notification/template/{name} | 10 次/秒/App Key | -| 接收方配置模板名称 | PUT | /{org_name}/{app_name}/users/{userId}/notification/template | 100 次/秒/App Key。 | - -| RESTful API 接口 | 方法 | 接口 URL | -| :----------- | :--- | :------------- | -| 绑定和解绑推送信息 | PUT | /{org_name}/{app_name}/users/{userId}/push/binding | -| 查询当前用户的所有设备的推送绑定信息 | GET | /{org_name}/{app_name}/users/{userId}/push/binding | - -以上两个接口的总调用频率(默认值)为 100 次/秒/App Key。 - -| RESTful API 接口 | 方法 | 接口 URL | -| :----------- | :--- | :------------- | -| 设置推送消息显示昵称 | PUT | /{org_name}/{app_name}/users/{userId} | -| 设置推送消息展示方式 | PUT | /{org_name}/{app_name}/users/{userId} | - -以上两个接口的总调用频率(默认值)为 100 次/秒/App Key。 diff --git a/docs/product/message_statistics.md b/docs/product/message_statistics.md deleted file mode 100644 index b0e431c0..00000000 --- a/docs/product/message_statistics.md +++ /dev/null @@ -1,133 +0,0 @@ -# 消息量统计 - -环信即时通讯 IM 会对 app 以及 app 内的单聊、群聊和聊天室的消息数量进行统计。你可以选择目标应用后,在左侧导航栏选择**即时通讯** > **数据统计** > **消息量统计**查看 app 的所有会话、单聊、群聊以及聊天室中的消息统计。 - -要了解消息统计逻辑,需要首先明确以下概念: - -- **上行消息数**:环信服务器收到的发送方发出的消息数量。用户将一条消息发送到服务端,上行消息总数 +1。 -- **下行消息数**:环信服务器发送给接收方的消息数量,即用户在线时收到的消息 + 离线消息数。服务端尝试给用户投递一条消息,下行消息数 +1。 -- **离线消息数**:用户离线时,服务器端的离线消息数量。服务端发送一条消息时检测到接收方不在线,离线消息数+1。 -- **消息分发总数**:下行消息数 + 离线消息数 - -## app 消息统计 - -在**消息量统计**页面,选择**汇总**页签,设置数据统计时间,包括**近7天**、**当前月**或自定义时间,查看 app 的消息统计数据,包括上行消息总数、下行消息总数、 离线消息总数和消息分发总数。各项数据的含义如下: - -app 消息分发总数 = app 下行消息总数 + app 离线消息总数 - -app 下行消息总数:app 用户在线时收到的消息数量 + app 用户离线后上线时收到的消息数量 - -app 离线消息数:用户离线时,服务器端的离线消息总数量。 - -设置数据统计时间后,你还可以查看 app 总体消息趋势和上行/下行/离线消息类型趋势,或点击页面右上角的**导出**按钮导出 XLS 格式的数据统计表。 - -![img](/images/message_statistics_image/message_statistics_app_overview.png) - -### 总体消息趋势 - -在**消息趋势**区域,你可以查看 app 的上行消息、下行消息、离线消息和消息分发趋势。 - -![img](/images/message_statistics_image/message_statistics_app_overall_trend.png) - -### 上行/下行/离线消息类型趋势 - -上行/下行/离线消息趋势图展示以下类型的消息趋势: - -- 单聊 -- 群聊 -- 聊天室 -- 编辑类消息 -- 回执消息 -- 撤回消息 -- 用户进群和聊天室消息 -- 用户退群和聊天室消息 - -![img](/images/message_statistics_image/message_statistics_app_uplink.png) - -![img](/images/message_statistics_image/message_statistics_app_downlink.png) - -![img](/images/message_statistics_image/message_statistics_app_offline.png) - -## 单聊消息统计 - -在**消息量统计**页面,选择**单聊**页签,设置数据统计时间,包括**近7天**、**当前月**或自定义时间,查看单聊会话的消息统计数据,包括单聊上行消息总数、单聊下行消息总数、单聊离线消息总数和单聊消息分发总数。各项数据的含义如下: - -单聊消息分发总数 = 单聊下行消息总数 + 单聊离线消息总数 - -单聊下行消息总数:用户在线时收到的消息 + 用户离线后上线时收到的消息数量 - -单聊离线消息数:用户离线时,服务器端的单聊离线消息总数量。 - -设置数据统计时间后,你还可以查看单聊会话的总体消息趋势和单聊上行/下行/离线消息类型趋势,或点击页面右上角的**导出**按钮导出 XLS 格式的数据统计表。 - -![img](/images/message_statistics_image/message_statistics_single_overview.png) - -### 总体消息趋势 - -在**单聊消息趋势**区域,你可以查看单聊会话的上行消息、下行消息、离线消息和消息分发的总体趋势。 - -![img](/images/message_statistics_image/message_statistics_single_overall_trend.png) - -### 上行/下行/离线消息趋势 - -在**单聊上行/下行/离线消息类型趋势**区域,你可以查看以下类型的消息的趋势: - -- 文本消息 -- 图片消息 -- 视频消息 -- 语音消息 -- CMD消息 -- 地理位置消息 -- 文件消息 -- 自定义消息 -- 合并转发消息 -- 空消息 - -![img](/images/message_statistics_image/message_statistics_single_uplink.png) - -![img](/images/message_statistics_image/message_statistics_single_downlink.png) - -![img](/images/message_statistics_image/message_statistics_single_offline.png) - -## 群聊/聊天室的消息统计 - -群聊和聊天室会话的消息统计数据和消息趋势中的消息统计类型与单聊类似。 - -1. 对于群聊,各项统计数据的含义如下: - -群聊消息分发总数 = 群聊下行消息总数 + 群聊离线消息总数 - -群聊下行消息总数:群聊用户在线时收到的消息数量 + 群聊用户离线后上线时收到的消息数量 - -群聊离线消息数:用户离线时,服务器端的群聊离线消息总数量。 - -![img](/images/message_statistics_image/message_statistics_group_overview.png) - -![img](/images/message_statistics_image/message_statistics_group_overall_trend.png) - -![img](/images/message_statistics_image/message_statistics_group_uplink.png) - -![img](/images/message_statistics_image/message_statistics_group_downlink.png) - -![img](/images/message_statistics_image/message_statistics_group_offline.png) - -2. 对于聊天室,聊天室消息分发总数,即聊天室下行消息数。 - -![img](/images/message_statistics_image/message_statistics_room_overview.png) - -![img](/images/message_statistics_image/message_statistics_room_overall_trend.png) - -![img](/images/message_statistics_image/message_statistics_room_uplink.png) - -![img](/images/message_statistics_image/message_statistics_room_downlink.png) - - - - - - - - - - - diff --git a/docs/product/moderation/keyword_review.md b/docs/product/moderation/keyword_review.md deleted file mode 100644 index bf045010..00000000 --- a/docs/product/moderation/keyword_review.md +++ /dev/null @@ -1,133 +0,0 @@ -# 关键词审核 - -关键词审核是一种基础的文本审核方式,通过对文本消息内容中的关键词进行识别与过滤,可快速发现和过滤不合规的文本。关键词精准匹配可解决简单的内容过滤需求,例如不允许出现国家领导人姓名。如果应用中的违规内容较复杂,存在较多变体等情况,建议结合 AI 模型审核实现更全面、更准确的内容审核。 - -下表为关键词审核与 AI 审核的区别。 - -| 审核类型 | 应用场景 | 审核机制 | 审核范围 | 收费机制 | -| :-------------- | :----- | :------- | :------- | :------------------ | -| 关键词审核 | 简单的文本内容过滤需求。 | 1. 你需创建黑白名单,填写关键词,设置对含有关键词的消息的审核建议。
2. 在文本审核规则中选择使用关键词审核。 | 支持从客户端 SDK 发送的文本消息。 | 按月收费。 | -| AI 模型审核 | 各种场景的全消息类型的全方位内容审核。 | 基于业界先进的语义模型和海量的多语种样本库,有效识别各类场景中的风险文本内容。你需在文件审核规则中选择 AI 模型和关键词名单配合使用。 | 支持从客户端 SDK 发送的文本、图片、音频和视频消息。详见[内容审核产品介绍](moderation_overview.html)。 | 按量计费,详见[内容计费说明](moderation_billing_domestic.html)。 | - - -## 使用关键词审核 - -要使用关键词审核,需按以下步骤操作: - -1. [开通文本审核](moderation_enable.html)。 -2. 开通关键词审核。 -3. 配置关键词名单。 -4. 在文本审核规则中应用关键词名单。 - -### 第一步 [开通文本审核](moderation_enable.html) - -1. 在环信控制台首页,选择目标应用,然后选择**即时通讯** > **功能配置** > **功能配置总览**。 - -2. 在**功能配置总览**页面上,点击**内容审核**页签。点击**文本审核**对应的**操作**栏中的**开通**。 - -### 第二步 开通关键词审核 - -:::tip -关键词审核功能为增值服务,需单独购买。服务开通后立即扣费,自动续费。 -::: - -1. 在环信控制台首页,选择目标应用,然后选择**即时通讯** > **功能配置** > **功能配置总览**。 - -2. 在**功能配置总览**页面,点击**内容审核**页签。点击**关键词审核**对应的**操作**栏中的**开通**。 - -3.开通后,点击**关键词审核**对应的**操作**栏中的**配置**,进入**关键词名单**页面。 - -![img](/images/moderation/keyword_enable.png) - -![img](/images/moderation/keyword_keywordreview.png) - -### 第三步 配置关键词名单 - -1. 选择**即时通讯** > **内容审核** > **关键词审核**配置关键词名单。 - -:::tip -1. 关键词名单包含白名单和黑名单,即**审核建议**参数为**忽略**时为白名单,设置为**疑似**和**拒绝**时为黑名单。 -2. 每个应用最多可配置 10 个名单, 每个名单最多可添加 10,000 个关键词,即每个应用最多可配置 100,000 个词条。添加的关键词在 15 分钟后生效。 -::: - -2. 单击**创建黑/白名单**,填写名单信息。 - -![img](/images/moderation/keyword_create.png) - -创建黑/白名单,需配置以下参数: - -| 字段 | 描述 | -| :------------------- | :----------------------------------------------------------- | -| **名单名称** | 关键词名单的名称,不能超过 32 个字符。 | -| **审核建议** | 对关键词的审核结果,包括:
• **忽略**:表示关键词合法。
• **疑似**:表示关键词可能非法。
• **拒绝**:表示关键词非法。 | -| **生效范围** | 关键词审核规则的应用范围,包括:
• **全部**:所有会话,包含单聊、群聊和聊天室。
• **单聊**
• **群聊**
• **聊天室** | -| **关键词** | 该规则中的关键词。每个关键词的长度不能超过 128 个字符;一次最多可添加 200 个词条,每行一个词条。 | - -3. 点击**确定**保存配置。 - -名单创建成功后会显示在名单列表中,默认为开启状态。若不需要使用该名单,可以在**状态**栏中将其关闭。 - -![img](/images/moderation/keyword_creationsuccess.png) - -4. 添加关键词。 - -创建关键词名单后,你可以在名单列表上选择**更多** > **进入名单**。 - -![img](/images/moderation/keyword_creationsuccess.png) - -选择通过手动添加或文件导入方式添加关键词。 - -![img](/images/moderation/keyword_addword.png) - -- 手动添加 - -单击**添加关键词**,手动输入关键词。每次最多添加 200 个词条。 - -![img](/images/moderation/keyword_manualadd.png) - -- 文件导入 - -单击**文件导入**,然后选择文件上传。 - -:::tip -支持 .txt 格式的纯文本文件,每个文件不能超过 2 MB。
-文件上传后应确保单个名单的词条总数不超过 10,000,否则超出部分将添加失败。 -::: - -![img](/images/moderation/keyword_fileimport.png) - -5. 可根据业务实际需要,搜索名单或关键词。 - -- 名单搜索:在名单列表页面搜索名单名称,精确匹配,需输入完整的名单名称。 -- 关键词搜索:进入指定的关键词名单列表,输入关键字即可搜索出包含该关键字的所有关键词,支持模糊匹配。 - -6. 删除关键词。 - -在关键词名单列表上,点击指定的名单名称,进入该名单的关键词列表。在指定关键词的**操作**栏中点击**删除**将其删除,或选择多个关键词名称前的复选框,然后点击**批量删除**。 - -![img](/images/moderation/keyword_search_delete.png) - -### 第四步 在文本审核规则中应用关键词名单 - -文本审核开通后,默认会生成 3 条规则。本节以默认的单聊文本规则为例,介绍如何文本审核规则中应用关键词名单。 - -![img](/images/moderation/keyword_rulelist.png) - -1. 点击默认的单聊文本规则的**操作**栏中**更多** > **编辑**,进入**编辑规则**对话框。 - -![img](/images/moderation/keyword_singlechatrule.png) - -2. 配置使用关键词名单。 - -- **模型选择**:如果仅使用关键词审核,则选择**仅关键词名单,无需模型**;如果需同时使用关键词审核和 AI 模型审核,则选择**AI模型+关键词名单**。 - -- **启用规则**:文本审核规则默认为关闭状态,点击开关即可启用。开启后,规则列表中的**服务状态**一栏显示为**启用**。 -- **消息处理**:**消息处理**所列的审核结果与关键词名单中的**审核建议**的配置相对应。 - - 若**审核建议**为**拒绝**,**消息处理**默认为**拦截**,即不下发给接收方。如需将消息中的命中词条替换为 * 后再下发,则配置为**替换为*****。 - - 若**审核建议**为**疑似**,**消息处理**默认为**拦截**,即不下发给接收方。若配置为**通过**,则直接下发消息。 - -- 其他参数配置详见[规则配置说明](moderation_rule_config.html)。 - -### 使用示例 - -发送文本消息时,若消息内容中包含关键词名单中的关键词而且文本审核规则中的**消息处理**配置为**拦截**,则消息发送失败,SDK 返回错误码 508;如规则配置为`替换为***`,则关键词会被替换为`***`,再将替换后的内容发送至接收方。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_add_word.md b/docs/product/moderation/moderation_add_word.md deleted file mode 100644 index 3c23b069..00000000 --- a/docs/product/moderation/moderation_add_word.md +++ /dev/null @@ -1,10 +0,0 @@ -**如何新增自定义词?** - -1、[开通内容审核服务](moderation_enable.html)。 - -2、进入**内容审核 > 文本审核 > 规则配置**。 - -![img](/images/moderation/moderation_add_word.png) - -3、点击 **新增自定义词**。 - diff --git a/docs/product/moderation/moderation_billing_domestic.md b/docs/product/moderation/moderation_billing_domestic.md deleted file mode 100644 index fdf5ece4..00000000 --- a/docs/product/moderation/moderation_billing_domestic.md +++ /dev/null @@ -1,172 +0,0 @@ -# 内容审核计费说明 - -## 免费试用 - -**账户首次开通内容审核服务,可免费体验 7 天;体验期到期后,即开始正式计费。如账户欠费,将关停服务。** - -- 默认的并发值:文本 160 QPS、图片 100 QPS、音频文件 40 QPS、视频文件 20 QPS 、音频流检测 300 路、视频流检测 200 路; -- 如需提升并发量上限,需联系商务,费用从提升当天开始计算。 - -## 计费方式 - -内容审核目前采取如下计费方式: - -月结后付费:按自然月结算,每月 5 日扣除上一个自然月所产生的费用。 - -:::tip -当前页面仅支持数据存储在中国的数据中心,如果您是需要海外数据中心,如新加坡、美东、德国等,请参见 [海外内容审核价格说明文档](moderation_billing_overseas.html)。 -::: - -## 计费规则 - -**基础服务费用:288 元/月** - -- 月底按模型使用量计算用量费用: -- 当用量费用低于基础服务费用,则当月按基础服务费用收取; -- 当用量费用高于基础服务费用,则当月按用量费用收取,不收基础服务费用。 - -以下为举例说明: - -如月结算时,图片审核 50 万张,调用时均使用了涉政、色情、OCR 文字通用违规 3 个模型,则总消耗量为:涉政 50 万张,色情 50 万张,OCR 文字通用违规 50 万张: -1、消耗用量费用 =50*15(涉政单价)+50*15(色情单价)+50*22.5(OCR 单价)= 2625 元 -2、用量费用 2625 元高于基础服务费用 288 元/月,则当月应付费用为 2625 元; - -:::tip -假设用量费用为 100 元低于基础服务费用 288 元/月,则当月应付费用为 288 元。 -::: - -**审核模型单价如下:** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
数据类型审核模型单价单位
文本文本-通用违规(涉政&违禁&暴恐&色情&辱骂&广告&灌水&无意义)15元/万条
图片图片-涉政元/万张
图片-暴恐
图片-色情
图片-广告
图片-版权 LOGO
图片-违禁
图片-OCR 文字通用违规(涉政&违禁&暴恐&色情&辱骂&广告)22.5
音频文件音频-转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)1.5元/小时
音频-声音特征(娇喘)0.5
视频文件视频-截帧图片涉政22.5元/万张
视频-截帧图片暴恐
视频-截帧图片色情
视频-截帧图片广告
视频-截帧图片版权 LOGO
视频-截帧图片违禁
视频-截帧图片 OCR 文字通用违规(涉政&违禁&暴恐&色情&辱骂&广告)
视频-音频转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)1.5元/小时
视频-音频声音特征(娇喘)0.5
视频流视频流-截帧图片涉政22.5元/万张
视频流-截帧图片暴恐
视频流-截帧图片色情
视频流-截帧图片广告
视频流-截帧图片版权 LOGO
视频流-截帧图片违禁
视频流-截帧图片不良场景
视频流-截帧图片 OCR 文字通用违规(涉政&违禁&暴恐&色情&辱骂&广告)
视频流-音频转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)1.5元/小时
视频流-音频声音特征(娇喘)0.5
音频流音频流-转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)1.5元/小时
音频流-声音特征(娇喘)0.5
- -相关文档: - -[内容审核产品功能介绍官方文档](moderation_overview.html)。 diff --git a/docs/product/moderation/moderation_billing_overseas.md b/docs/product/moderation/moderation_billing_overseas.md deleted file mode 100644 index 2dc15a9b..00000000 --- a/docs/product/moderation/moderation_billing_overseas.md +++ /dev/null @@ -1,178 +0,0 @@ -# 内容审核计费说明(海外版) - -## 免费试用 - -**账户首次开通内容审核服务,可免费体验 7 天;体验期到期后,即开始正式计费。如账户欠费,将关停服务。** - -- 默认的并发值:文本 160 QPS、图片 100 QPS、音频文件 40 QPS、视频文件 20 QPS、音频流检测 300 路、视频流检测 200 路; -- 如需提升并发量上限,需联系商务,费用从提升当天开始计算。 - -## 计费方式 - -内容审核目前采取如下计费方式: - -月结后付费:按自然月结算,每月 5 日扣除上一个自然月所产生的费用。 - -:::tip -当前页面支持数据存储在海外的数据中心,如果您是国内数据中心,请参见[内容审核国内计费说明](moderation_billing_domestic.html)。 -::: - -## 计费规则 - -**基础服务费用:520 元/月** - -- 月底按模型使用量计算用量费用: -- 当用量费用低于基础服务费用,则当月按基础服务费用收取; -- 当用量费用高于基础服务费用,则当月按用量费用收取,不收基础服务费用。 - -以下为举例说明: - -如月结算时,图片审核 50 万张,调用时均使用了涉政、色情、OCR 文字通用违规 3 个模型,则总消耗量为:涉政 50 万张,色情 50 万张,OCR 文字通用违规 50 万张: - -1、消耗总费用=50*27(涉政单价)+50*27(色情单价)+50*40.5(OCR 单价)= 4725 元; - -2、用量费用 4725 元高于基础服务费用 520 元/月,则当月应付费用为 4725 元; - -补充说明:假设用量费用为 100 元低于基础服务费用 520 元/月,则当月应付费用为 520 元。 - -**审核模型单价如下:** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
数据类型审核模型单价单位
文本文本-通用违规(涉政&违禁&暴恐&色情&辱骂&广告&灌水&无意义)27元/万条
图片图片-涉政元/万张
图片-暴恐
图片-色情
图片-广告
图片-版权 LOGO
图片-违禁
图片-OCR 文字通用违规(涉政&违禁&暴恐&色情&辱骂&广告)40.5
音频文件音频-转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)2.7元/小时
音频-声音特征(娇喘)0.9
视频文件视频-截帧图片涉政40.5元/万张
视频-截帧图片暴恐
视频-截帧图片色情
视频-截帧图片广告
视频-截帧图片版权 LOGO
视频-截帧图片违禁
视频-截帧图片 OCR 文字通用违规(涉政&违禁&暴恐&色情&辱骂&广告)
视频-音频转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)2.7元/小时
视频-音频声音特征(娇喘)0.9
视频流视频流-截帧图片涉政40.5元/万张
视频流-截帧图片暴恐
视频流-截帧图片色情
视频流-截帧图片广告
视频流-截帧图片版权 LOGO
视频流-截帧图片违禁
视频流-截帧图片不良场景
视频流-截帧图片 OCR 文字通用违规(涉政&违禁&暴恐&色情&辱骂&广告)
视频流-音频转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)2.7元/小时
视频流-音频声音特征(娇喘)0.9
音频流音频流-转译文本通用违规(涉政&违禁&暴恐&色情&辱骂&广告)2.7元/小时
音频流-声音特征(娇喘)0.9
- -**多语言说明** - -文本审核支持 23 种语言的识别:包括中文、英文、日语、韩语、泰语、越南语、马来语、印尼语、印地语、菲律宾语、阿拉伯语、土耳其语、俄语、德语、法语、意大利语、西班牙语、葡萄牙语、瑞典语、波兰语、希腊语、挪威语、荷兰语。 - -国内数据中心默认语言为中文,海外数据中心默认语言为英文,如需使用其他语言,请咨询商务调整。 - -相关文档: - -[内容审核产品功能介绍官方文档](moderation_overview.html)。 diff --git a/docs/product/moderation/moderation_enable.md b/docs/product/moderation/moderation_enable.md deleted file mode 100644 index de950da4..00000000 --- a/docs/product/moderation/moderation_enable.md +++ /dev/null @@ -1,37 +0,0 @@ -# 开通审核 - -对于开发者来说,提供安全干净的聊天环境至关重要。环信即时通讯 IM 提供多维度服务实现消息内容的智能审核:审核服务对用户的消息内容进行审核(文本审核、敏感词过滤、图片审核和域名审核),发现违规内容后根据审核结果采取消息处理策略(下发或拦截)。 - -## 前提条件 - -- 有效的 [环信即时通讯 IM 开发者账号](https://console.easemob.com/index); -- 账户余额大于 288 元。 - -**1、登录 [环信管理后台](https://console.easemob.com/index)** - -**2、进入功能配置总览页** - -在环信控制台首页,在 **应用列表** 区域下,点击 **操作** 一栏中的 **管理**。 - -![img](/images/product/app-setting.png) - -选择 **即时通讯 > 功能配置 > 功能配置总览**。 - -![img](/images/moderation/moderation_enable_02.png) - -在 **功能配置总览** 页面上,点击 **内容审核** 页签,如下图所示: - -如果使用自定义消息审核,**需首先开通文本审核和图片审核,再联系商务开通自定义消息审核。** - -![img](/images/moderation/moderation_enable_03.png) - -**3、点击 开通** - -说明:如果遇到开通异常,请联系商务处理。 - -**4、配置审核规则** - -开通成功后,点击 **设置**,即可进入规则配置页。 - -![img](/images/moderation/moderation_enable_04.png) - diff --git a/docs/product/moderation/moderation_enable_03.png b/docs/product/moderation/moderation_enable_03.png deleted file mode 100644 index e81c2365004af6cb1bc9b6573f8f743b8ffe39b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84623 zcmeFZc~q0<_CHEb>#5d(RuNPL>VSw$f-=d}Y7u2hMIlT{WRfC73{wapq;;Y)MZyq} zsfvP(5fH+V1Qj8KFsKM9fkaFg0|_LA5HkIutv#M|zvp}Zx$CZV*Shaoz{;EFdEUME zv!6YD_I|nbv%AyQZ}xnnqN1|(?3tfDR8+o3sHl9Yw(+0JJN2iEhm?Q5i1BbbsZuwv zcTV}?tI!|aepG&i*(?p%p!~e)${C*+6%}>e4?ka=^*FesqM~?k_NN~&B!CwtHWwL% z`ph7oxO_$IFBsf70JCCQH)w_2?413gpmx^O>E|E5@72xxLG8?y=k7mk@7{Os;E`S1 z_ZbC#RXTPv{ z!VgMnKW5fH0cXz4eDT$Pu6t!|Nyg2z;hJxrD2zHWOI~gAn=m4b5AV_w^bl44V|48y z-Ni*h1%Ss@bVqX0Aik-{55IO^6mB9Ov^S9g@bQW(U7pm~?FG1d8vns$^DCJMJ*23e z@Lm8v7I}zL@Sy5ckU?m%497+B6bbxbyy2-la{#1eo#t6biYNLDx|aFkL5Pi)d|AiA z(yOj@+8}6ZX;RYNTMVDj${d@%`?=IEnt~ECV}RFr2EY@dp0sD8_nHHwgr;31mR)Ah zEsX;sUl5X?Z6gFZ4K9ow4y6;k&^%oIbT2RfG2CKdHj(Pb)B&$Pt`8?7EaDfhgiD^K zxn*k&?HHN(!Wz78<#mfolgAMPNtR~*&Buu27rN?w-fE5%6#*;1L;}-U zq4$FvnknL;L5lsVDSX5y^ajvxrmlS(&~b4_K4);LlAaecfP|alf65ykb+eo(`bnb& z6}Yn%RG&It=j|8;tl3X6@XDg^tnOLtz39wH(MH{oFtSZ{+nAL$*`B=gw^m;K@$B99 zs#GvyqVYb+Xu5q#bF!Uaz$tT zMar`m{ct8qwS^v4?J@>}$_yI&7JHQ(oa;BCVMF4nw256xno~X5@m)uv+y9fLYljgX zi}iz7nD8-&Hgt2MFu_`I*`c%#YJ|HTcIwknFx-YnBrLB)I)RhI^3TyqS0`dmhmC}K z`@!<(lDEfn)vhG`BSDIdiiO!C?OYf&w^ugsHgz?tQ|{Gc?(WLi5XGzTt$w&z*?fxO z6h5}U&^zJ~4`c8CcKPicEZktAGz!hvL%&a+uSo8d$$1JgQpSPsz%|UEaqh+d+Uud zpKZRTE|#)`P#=qF$FUwIL&wwFS8jQEw#6syU0Uc_f4xeT137M#uE?ClT2V()d6HH+ z&!?@~fm#@u?Mtw{x3{>7!K)oBXLQBqhe}Eu7Tq0Wu_AhhjLvm|tb6S8z*ZzaSeuA| zkDrqpG4f6PQ6wLB{1hMEa>VDRVPl3TxBEXd@$+4MyQ<5BOIOk+M5Xf9{R%c&KRaw*=kQz1d17gaCXCsl7J%w*c| zqD_+C@_?QAb*VX5rbD(Zh%f3PYqd;`1Q*cFbBKS6>B-eiIzzTc)>-)v*o*54)0!rr zCs@m4>vKJqo?4l;Tl779<%`o+pQ)cVqRP|97-5wjNAoIza<7HV74OAVx-fodrW`Kp z@2l;*Kyd;uf+`8EEUOI3LEfqzI^t_p?G+wvtL6B&H}5A4EYU;7uA0;Qn2y467CM;c-2I9hj|4} za9c;AD?;IAk4t$HMNOZGIPcM68@^7?3OuH_VYb2^<(UwYZFv&c%qMN3(T2R`-{^a= zu4sj8-h+cyN-oQb)S5v8KTe}F!^*Wsv>u0Rk+$$)-lbx}NuOrN=1RPDZP4sr@}66U z(GZn|9RsEEVkFhzfiIYwamF`!_l^6hpqyJjo5kngSh(1@xlzyf0R;>0=L}}8Pdq%#BI8~2KXBnzPqoXivR50|Run((Mv zNiB1|cIk4=Y_wPOyC+)QmL2Y}(WJTRfYdu`?I%jd*RI-3b`Tj8u|ta)Q;+L=|Era` zkKdzL&z8|u7i5CX1(S0k2K0vf9Kkz1k7j~iWgK2RVnnyFi3ITLG&+T= z@V$ObCKJJ+{-FKR`T^Xe2$U&wu9q&n34NQsf2h=99o6f6NoJpE3lBVGgwU9l*2_8_ zq}Py7H-or5t^X5>O81f>H&&f7acw0%kpNAKXFZO&kXmTHo{yPgS{a@O!v-12Umr5lxA zaV3*>JLvl%N?cF)ZavOUOQx@b8KW7~07~>9-?qE1;=4qMhS6s-eVI*M7nb9Q8G-fH z>{?3Xf^$U{w#Ilx%{}f~U&~yCxX!Fz4--)w{Bgf0UX`}Vc z2cp^;qmG+Dg{O}$URpZHyKIqs-UZzF?pW&MKYTp$hNw#;n1H;vd`G|EeLFlKH#ywW z=in(#d9g5^8Q)7)LFz7)%cy|y-z$FXUnKO7KhY6b4d}3@VSH@JF2EOq!j|8?x#~0S zz;l-)oCGAxf&LoyM9B;$@;es>lG|#c{|mHrDhfXA35gLgnbM6+BAYaM({Cad2<9mT zca3TmTmY)M3jEI);xA|GYzUPcGC_3V>e`~l-xnpBG#0#v)yc#VxWis9aCCD|Ja>(>ig0KE^LW$A_$gDd#sCh zEhC_cu$BWFB0cf|h2RKv+IxtZ)>50c>r-rg@u}<5LHr@s{TI1-kAFfLJBard=YA?X zv!lwjn)=x0gkm5n)Ow`Ms?qs`i{DwC`jFsWrjM5k5lsN4@oqd9aX1f6$`u;qkXhQUZ#|!7WcJ8k>36I2CGz1mN z%7C|+BrkV&OB?#m9Y!c^YSfL&55D6CYoZf9gKp&^gcakbFxHe0tP-q2C4agVIZ1V0 z+((>eap{Uqm)nonr<82!UW_X3f`?=4}V((yq)3nl~ z11?~a?BsODQ2KTny~S?-wjui6l&&yV^ZeYQySQW3f2Sy$FJ09`+(`PVamy$=4fuRg zV1n!%%DvP&>Qz_S;F@XEr#<7UUZ! z=t6(!RDg*rT=a*N?Faz<94|%Gmsnn+?b52gnDgpT6skO!B*0PTYJ;9InSb-rE>_N2{WJIFoM~RUORL zy(Gl^<7E0Go+w)LWT$^2>$k7TbKA6C6&Cn| z=>0$qqS)!UOYrUnLqq&67e!jeY{Hj-^tW zZ6soi=5S$Wx2o8(gFU)0OV|~+k|8_@m0z!3d!uI|J)U?%-*zfa{(Qme<%aOR>S?dS z9O|sq%VF~V!-)2qRME-qt^maQr2SmhrJGodKchXBUnjG%z>?R)VjTqwy>?Or!yx^G z#xL0N+3`G*nPFZ|eM`>Vlq5+G zyXVqBuCxRtVDh|dk0(EKI}Tdg80kH(zFQ+@?)gcdS#h9`mIzVucNnj7Q9OR7b1PQ^ zy{s_-ki7=9j&{g}0kb1mte1Vc4~~FUX6=J;b<6Q9)$QVGn~6xmL~c3`aX4XL`FhJV z6!|P|yc5mirTKHovI@v_iqgs}9wTR6n5>jx{faO&==5~9IK;Yv7`?`n2xo<>Zead= zMZ$yh^sf7A>4>vOhRE+R;L<*3#lhhRk%p&&mi0M9w9;mFMpxxeC8yO<&Wt4a+6f)} zjE=c0S;NeojFEhQ%dze@Di1Z7ve|CX_FquMljt@P1359{pb#%zHtnGpF;Sw)?(-zC z;5`L-m|spG_oNzFzXvkd+VRhvCQdAxBwp27T~rL3asxUf=RRnSH!>Bm5?%nF z7SN3H4$!ivdilcj?z7uKjnM8asZr)*hBq%UocSUYM{gzz3m@f#Stt2YL zC?UtYuGfqWo%EF)VhKW?hrO4YF|BlY$~ZT-RFApMt~e=o5>~|ECD8-lCpwOc5ZC|K z9u>no5}u+QeO08)xpi;glT12;i(J3_;GSnd!*o(Ij6ELMrUNpZztd+u_+72uI|pxu zG6V_sTjXV#xpsF6&z#OB@=w$O%6;sR@P-8|a=233>JLxA=!f(XAvW*pzgte26(86g z8kqvdY{AW5h3`$2HE#K26qI^@^Wr=f$kzhcciAn#?H9CH8&q3Uq;HPN9;HZUhdvMu z?|Ky7f^pqZZjgdQ%tB?wrHnxlYp|v~cWPdkUPuhKy+W&%Q%Ak8D#;vk?()ecs=wV< ztujoDDum#wO=0v{swP4I&VAcq`nNNf&XxG*LW&F<7Mx()&AJop=XB#=B2+nbG#e}W z(P51@@m)uJ$p>ROow=5)nAcwEp|pK1dxB}_S@DOH^9vMef_)Cft|kJi)J*z21epS< zYb9&HoC=i3hTFUO-F@T5kAJC)XWX>%-yhPbjHDpK6+~dcp3Ud0{rfA1S!^T;EGC=y zlo(Tm(Y0}1Cw-h5Yu~*xv#ld6+P%2NDRg>j@UL^G^5omTa<&owHdYL@!wO z@3i@E6y6`sxfsg*U9na-(zAAXcUO|C-RhUg$}?k?1kS>Gr2FxEAFVx(bTzbQJ%%xw zqmM!2?a6@mt4@iah9t3O+mL#BL!`&pye!h7u-$pqapS-3&Lv&mHSJ|@QSo3xqohs) z{X}c|D!g48hJ`N7`R*UmS$+m@=Ot3VmPQ97Mq;nK?)elgDED^D(*B2we;X8|kJ#k%{BI|(qH=NLVFdNnX9rH@ z)DKjbyhC5}S~@3^m;Pv9ytpjPv`ORf4&R)ZD2oVe|){o@)?O zRB;=4U#ec%0445Hit^9v*Tw&a-`W)TMYVQ;P{LvEX2{w<_Fa#t?in-|@3yG4giMaB zlBlgtb=!_LKpQZBE!F&yrn~Io^qhmD2{FYmdK3P5WVRv(g z*}FY&pJ~+$QX-XESOP%3f3i~~9*2#Bf~L5pG4w?O26v71H}KaxVf%!5j-R>h&sBb1 zO!*U^)@$6T3+JHg8Eb?0@Zc+Gu-e&l=el&|Aml7V}$Ag2xfp( zy$uf>(oO_SoL#h~{o@XnVE5m6x>2|DVo7rw8}&Sl(1zK2 zL_JIq>jA^dBc5E@8zmBbBl?q;d}Ou6WO_Q^HYz{(bakbR*>oEi1Xd>4fz#DMhHL$wHV$Q^EDpMEhe0ROK?$fm^DG*T8I+(<)NMwd$hpH=?ovMXeO_xZRAdi3lxw7!6)me3tOUs=na-P?svwC*PvKfxT0S z%k|CJ+j!N9-wy{(xj@>JiT;wQdcII5q4au|N-FB3Ww?$LUgY>rVbD|?J}I&$Y0jm~ zRO`T~KfK@DI+pom?H8xB&>N%0Q@D0bDDh>7ycb9gw4bo)&C4O$tF}~6SWegsKT@6` zH@GmjOJrwX=VM>q8XaRANoTT+%F8~X?s-b%xjT3o$S;2o0b20Y$u<-mFMZq;m`hwf zJ3&-)-^rP1+FoL8Jfim?$`IZOgs2m8NT_tdLHvI^I)4^xK8MKbdqJCC;G`&qiwWuV zMBFHddq78ghQpj&Y*5CrUvi5rZQ#PtG@er)F=hOKd^TRRQ7k{!WgbH#C_f%gV#n|g z;@O8pzgx~DD1Q|w|FTZQOjd?I7y#mTV*T1yj@WDptcG1cyZVrb$l{U$yGSVTJEEHD%rmvT#b@6J=%VFLihI5v0 zl8H{`c*1+H!5xor#1LzP4cyeEm1xRPdz}8>)X*Sg6_2$pTrxe!Z>IdW;>x>R6;|6~ zGyNHyMdxFIa(k$EiOq@;yth=Dgur}E4U_t!{iu=wzoK@T3%pHLV+h55MejV{K9Wsz zl&{ovOIct2dFVg-vVRu%;D}+?g$}#JQ5PCPv#SW~=$+Hm<;)K5NN`&fyT925M@-h_ z2zyRk5?Uhk5t9FrvZn@LSPbRih}1`t38(i%!~kz44Lz!;p$TJ6*gJQTiT$znI{V$k z@K06Wj~@7TK_u1YJu6d~{Ww?Nh4kJk-0igJf+d0HapFHAKECKRa0q~PfoqU?+ z_$W>ns>Fb(I|%65P}9Cv_QBA$h&-aX;Th`$ly%*aE1NSqDmCrjTW{m7BZ)7Mqj7(w@_)(utv$7U zyj%awC%zh$rt{qYTqOLqFdR*7GxeVBq+MO)3%Q&Wx9TD_uky zR&;hS;Wwm!&Y0`)Wo@FKqT1Lf1LEdmpAU2O{MdeNqgt)=xB>-53bx={P^)SQx$rRG_) zW(|9lWugO+y?;5plyBwUJG6!> z_1483`?EM!8ESY|vVUU|u_39iL5cB{Vu55_&lOTKDdTyj8u4SLuT*+t=Aa`FV>_ua zF(~B=LOoVIln+%ROsJ(Uio6A0BVd5Wv-gZc` z9185bFMU0f?raE(qwaywMD-UkSnN1Mf0kLWf06wmW6Mn3;)xk)+IaY&EnOAkSl6e= zq+KEPoud-c9?zUp$j^v!X0-iwl024rtp#sNZF*6Z4k>)vmh~ZTIa+I(ys-2~8u+c{ z=g)Ux_}EhoZaLPfRe1d2oOPtD+V+M4fYsY_)|rtFj%icmUlO-TuEHgeIXx$WeU{_) zs*hGzG-2`CkM-0^9cx6^_&G{VU(LJR57|P5WuNb5r`D0;jxc8idqGv>Kt8Rb#18b_=q0Zu=MRb65SF<^nd0EvXG)O&-2HDHJyWuCqte({$b6Bz-?N)C z7osc!E>pp0N3)4$?s9IFfBfD$hY}xhuah-p6qav{5X5yn7k;Mrc0S#k2S=4!UxG+dqrP$E=QJr+F_ zYj`fv46{&J;{raIG1duj6HAKz&~>@4>@ir5kDE zv+Htt%u17A0l}30mWR~I*rXz2CTE}DzqQH?_c_$P?X}W{g6F5}zX68l69;fXN=W7> zd`>USx4ue|tkuy))Rp zZueh@Lgiy>{mg9$r71TX(4MP*`l`*V!sXJz}*kN<*Gm5VqkW3~T(k^g68a_OZr zBLieJo~h*+A9;NrXj_X5SbPCK9zGC*^G6=tl2#WzLz>+M?@M!!!D(&0Ha&gY=E~F* zmyZGDRj=xNLwlJTlDuLIpRadnD@zN?a){KW!zl#`qSJNJ7DXV zW-M|OKcDLzGklH|g|Qh>wHa7!HQw^&C+*m!tVx;mL|mdGm&PtV^_kwIVK4@BW^hC$ zv+=!;Z2++xOSLbzX1-ejVrLRN47=dl~7}~G3IJ0%b>{d=xNa*r9qN{%+YFT8%^gBJyA}gNj;x9|xJ`At6eD3-S#`18ER7qy z+|7e9Zt4>1vG11l`n4l0W9eyYLp_#utFNn{;pi)5`xbFxh|frKI8coxY_3tKAEM(9 zF5nCY0rY5B+uaq@e?=N9DvKXkJFLs|#XO6nY~l=z-nD#wFQ&rJT2a;Ttz81i4;^O> z5-)f6N5{_$0b;|Emc5vx?$^W8#8QiH;a4dqv-ZUFLuzwq$DJ9)037CbV?OccBM#zO zzA!B_-l>UY`$7g^RID%e8Joyr)UCQEcA8T;00EEm@ z01$HC?z;&HxYswNO05V1GYAIT)vA?weMdix2%4;X<;6WcltZlZo=NMpU%P7QM;O={ z;A`jF+zQ(g-1Z3KMb&iS90?e!zaAN8&^@D%hJNDpjq3-q^0p6adE${}&iyLaMbC)! zxv8?78L+eLIR@<{wS7oSFfSMnkwaJ21zZnD-qWoF3fgwLa*A1Dw|YUT;9aAk#j^t| zouZZuDL|%PwTO3ST#I7ihcGso%QOKUR%A20%j9jN35Y6nX6%H&H|V4s=h^mylHstQ z>e2y1Zmgahz$q)G9N2KlaC^3yxykN~==clwcbU5|GWEjxD=ygt?tD>FPnzCASZ`Wr zJQB>ZpeR)+b~rXtm-l!o0&K`(VKp9kJSt=b+YBeQxejjTNv#F~bv|ipzOox~cd+^c zb_N>roG2F%vJa#Lh!qtTC z(|3RpQ0>f+vhIawB_bN^U__=~6DG09up&`4q%aKzv(``-IFb)~(UxAzKQZ^H;4giJ z&i&fX&J78xba>Ws#17Cgo;%F`5$<;Q*TUB4pjGRF`6C2%`)!Ds&45+FbcuLA=wtz+ zs@>Ij_-Aa1_%1DJA2CK44S%bdy4=x70SWFNOPlM(9#?;1imTB+9|bs!sFoF2g%#MM zl#q_$wyEXZnHy$O;`@htqemfy8m%d*aoRIpjJ9)q*8B9A?~gBJ-T(P`H{~D4)t|Sq zUjzPdzVH7UA6MhySwm1j(Z;C01-hLlu@w>Y z*hRn}4ts1&as;n{*>N3r^>qH=-Xo5W;9SGfPj?t!5tbxw&V0M_yQN zqf*PH`DLC^I5|mDEf#8-ZkGm56n0I z$Fe9M7!P0@h?zsSZr?mDGCgL;ztBL_Nbu9{bf zhWFENM?lB%hv_M2MoJBVtL^!~S6=oayWx(#qjh?Spvo#2hW9^cOT>hX`kOBM47zHPOmw*w_8^=etR=JN z)X2`XcS*{KIxYK#G6?;>i)|V;7#HAum&CT~E*3M^E8ncWj_~1khs|S7+9wFxY!=^S zb2?sXroJdEiM!A=@FmZ#-XC|zvJT<^8oz)eQb?#y5PCwW_4W!>0tnDLO+^lKYh1S> z<_C(ol_rlV#W-AO728gnBxFCz6#$G0A-z~&uM23T*%3!X%xP@?8RULQ7w?;?0N93qXIJ(By78_QOfr%-|cg!D(;{z^i9c;w&S^x`e52RE4~Xc)g-5rlwDA`9W&Ld zE|HYOV)Eq%tw>78e$F@aX==0j&@8J!&{bce_s1vjO(o*SEf=sdYbDwt`(fMl6Gcq# zJSRTMJR{ee(F;Tv-I#xVS+z-SDqdDeL zEU2i3Ru{v4$LwxcJ`P8SDR9y%cGMlr=f2h3a7BtFI>whQ7-yXg{BC{z*hB%|xVg(j za@%I9)q5Afi=Vl(jGe(g8?0D?!3^I!0eDFv^~I{!H?=)fCM8qIcTj*)+9YrRHhMi^ z0DZj4wf!A{@BDOEZ|9m?P00W*uWPC5^_Cm=4F@$am$gnLBk%Vak^$cgxRQ+>YWskO z?e`#*#aw&?3Fh!qzA@UY^~lLi+x>Mk9h2P-fi^qDs~aL|w=RfIW3og^aC*V+?`xyHu%&|s#x0;bH}#vFd}YwPgx4Z!_t1AA)b}p zE?y5=3(=AMON1i=DFr#$Fgvk=6}|XTasRSM?7Erok9M}_q%hn# zMhL00n>9wd?NU}*fa4|A984g2Ve3?E7_~a)z72Q9F6uyhQ~gG})z|X}N{2AXQ6>mH zf`{NXgsbME>7&)7@VR%Mk-lUhw?U(O{i&}Pc zI{8#MLSeR|-qn(M<5u%6+m$h^GVD#Xj-bqSnPzG#0|Q!`D7obRaV6Fv53Vpiu7skF z7zR-dSXCiCYuXzgg5$5L6&TT80Pd}uJ@&q7oF?#JtAAg8#5<04?KByr-Goh+I07`ar&k36QfwWycjum4huhiULSHvt{m*$e;t36tvsxzQ2};b!Vzt zy<%uXgxnWLsb7iQk>*zbkw-zv_WS6Dol4wr<^w9FXyFM~YuZK0?+zR@O0;ZblNN@Z zZkm}6y2Gc@elborM)eetpyda#C(neO%1+B}yV11R^ zdqd7jcqeV@UQTxXyA@riDL%PjR3okHC}|t*zAm&W(k$bMX-JDPT4*u9_`Bq8MP;5o zU52|n(U2J^zq~u3osC4-46i$7%?TEJnAyZLnVrI zhl~-*-Vfk}iGzY56FG=C4=zIvo4H=hepGI4W(<0 zz&qa8$&(H9VeeKd-!)?i#w7sR4~F+SktgPJLoG_SxW|;+n5s3Nr6MP^;YE;}Qq;Rd ztu}wMd_KIlBBhgQV$Z*B4rk26rW#6w7C>3k!k4(#p_6wP6ky)d@bMBL*RW!9Wge1a zKDmiS8>c_3U!{a@i>pm?4(`17y5OT@=bHyw+0p@o5VW&qDi z>YUZC=w%dmBaI(Y$kZkf@-4Y3wyo8p#cEZ&^Q@CpPU*^4fgY#+W>c23^XVC__IpW~ z{f55~Kb0p%ZvOldA#+dwSn_2Z1SAi*jDPLGhbd$mc*&(EJbqZsEY|ZIZ?U8eR%Gny zq(oInTe4vuv-6YKv!(1|+9M^blj#m#>Yl8h&Bc6y?m3{H-FGa?qLFR4LN$l;>*C<8 z@_g3Ub#RWSxMc`eo>E612W@wz2tfvN=*vS7?)$t`KLr%V!tMl(BS!OBoC+{J4?yU~ zil|POC6A3tzj1eAlzExJzrOz!IUbPUyn0yFJeccJ;;8g-ey27iFK8?7M;Rh8CuC-D zl*dV(D>&YXwjwWi@^ajA@Y zQASTvYebt*y-S-RKUhkS+sXYDD)rHy>*8}_lE3I~nIW^MxaEaV*kHm_nlyZ$4!sBv zs*A>YX;doxzb@Y0K1o?2=^jl)+%MosI!fLpOL8j?ZGfh$HK@ve(}8Z$u`KlATa1$? z8SxRa*twVO7QOsY>8`1t`x4vOBt~tAZ|d8!Mzgg<0!0A=9k3aU#nDm|ll^1(Uo~Vx z20Xd8kS(Je9S-YG&{Lx12z)7fru96=u3^1pJ_9tDP4LR(Qx=rQ-5e07$MqGVp=(tF zOm(v^H5)jN0BT1tOY;+wJ~5`!+^Y1$w{BOMPMrmb{fO9@fsP(k^pt++T9}+!mfVS2 z6+j~T=<1*bXP-S(k;fms*`#IYsuC9ssddHAy*EFk{%E<$Q1Qfw(40qX(B8*My#e*V zY5UYrFhxtJ-BkkE`iZrZjlFq!#2cqZxiCF$PKEO*NTw0O={V+>m-&H8a#ixWB@$~X z+cmpmLU(cw?6X=q=%U!RG*D4Gt1QeyE%Jy|W|vVefOk{x25NV)%x+RoXU1LfYXr;? zQQ=yT-fHPT?M@r@3#mZP8w|t%C$!3k8#+ixw!l4JnSPJ|_Vu&1_O!@kPmnXG=P^`r zUtZYrw+!f`uXTA82Voe5>-@xm^kO8cv{3vb=7h4 z*Y|tye7LLH*i(1?mOr9c188 zo47)vg?F9efA>rakiEX_C_R`mkJ)RlmevQ}mMidaoSV2TroVVvZ35RE)tz`2XPJB7gl@5$Dk|RFfxws5qDuF`$>u_6KHhIerFM2 z=ybD_y}EDer2>0n=2%IKt)13eso}rc`&3l=I{RF}C)M|T4(=ZLv%2!hCaYY0_#t!r z`=u-um0$1PW9we~w~n<`EN;u+uZ$>(-u3_OMdp80UFSMkoxG|3{}S5jqwLPe6b>qQIbL z(IC&K#xi69!vNc1AaFWaN7=9NhMpA~f;Vhctk_7Kud^;qT{kD>nHWShMs#R1?kv~| zo>^FA`j8egg8bjS*(rh@%dj%371b>><`<1c^-SyI-AMgq0cTOm6dkviUdi#*uft1| z_DF~kdsAT4wi-d*jRgSbgfJdQ@k}PKi3XDfuO^@#YX$ktJ65d(vq1w1x<3%$>hw!8Cm*4$wkG$+0{x; z=#^Y)QDMJ0pX_88D^KcYV6tA)Cz^EZu5dSK#MCu6YKuufyL+GwUmM7>@sZr@IcXxN2M^$xAJ+NHygfW9seR#Y(Bhb_REY-0XC0hr%P3Aot@7%}wkhQI=_f90 zQH7?r0*k3qD$-N2r5+=(n(;s^RLKh7g@RB~O{FIGms_W750smDXkS|^QF{hEih+_B z`D5PY0~cnT`6X)n(HqTzKkP51G8s~mavy%F!>2{KG@Bd{FY;RAZ!lM31A}7==#d8w zmal^JIlnLmE^Dn@>CVuD|7v!N_=q%0^$@j%;6=-4?3+d8mtLei&47%;o+f_z>@Hn= zoAqdJqThlhGGkT~{&wpnMboZkvH|*@p;=U_rsZyWlnO3Atw4j#_ZWfk;u-H>Xzb(?P|Qw@cF*6EK2X zafKvp?vj_k{$vst!k?FM&d|l9E*-)g%J-!fHo#zoFT=?JEwrc4#IpyFHF3{{A<R?;M zS}!9GyV~`9~uSE0wX1tm~w?1r*ec{kN>$~R22MMZ$l!vyeL*b$S$Y3#T zRq3nxq;1Y-HP(yyGi73M-2KH}7e>9%V%|vk6=Pre-G*HboSJ|K^TcgcqtSikb`>9e z(66^XSa?5Qemvt$1VdW8-}1>G%V*E}X#j%Jv5uGJQSo~$hieL}=C*p8qYI^%VE!pO z7JQx`^k9tXGG`Sa)+sjv5R(8FXnAKfLT4~Ne zCIcz^C(5sj8_&2w(gDp55vRm474}}?5}6c$LVZDh(nD)S9?f*fbwXtw!@~oCEjn;&oHR=4Y`gr&*WU$_U4t~+;c(M z-n>%Iq?MOMm+~_&$SS@8{Wg&!aC#^{fpIi-qbJ1J^)LR}29mApD81Hq(w17te9gCf z(h!!zzZr@+fM5KlkNA2(64tV&5f)S{>-I?$47_4>(_1Xh$;^cPXM?o5&Dse~NE=R} ztZR7_Et6&dO{$7ra6w&Tyh_3ci_0*uR)0IlfnkdW5+7qE2~oFG+Uy*5d;CnXoM>43 z19s{-!ITL^EGkaNvhw%PU&eUH)jYG%N_+KUG}FR zp;}{$E6hrDphPI*nIwN(HoE36xY}F79n8A2FydF@-B`C7O%5Ifnnx_4RC(vkjj@v> zh(i+o(}g1an;JvT`?7hbT4j(Wn(v_K!Lq=>Mk8%mxYCfBklEAxmO|6U8I5*C6?S|( zaIITHHwWnXK$?q4U1Yt^z?$&-aS?z0NNGf5iQA3t<-SbEXxq&J>-@xF%0qvM-2;1# zXXIe|#p3LHNs3`?aGSORXTB5|fQnqEe^NHWM>OIZBMPzvfy9O>0sFg%eZU zsDu1eqEmy`yfiDMfR57{G99E`L9Hz=-Ds~TnYksGcsW3JhUWtp0Ly~cxb;Yi=d?MY z^-NPAza@vZk@B$K9+m7gWx7WZ3K|b8aPYg7>?&Q=q*yMEI@8hgn_(Z%>=X7!ul7h6 znh-hRy-3v8oX*AkP*>{y4aaq)jPiiSb03dqoi5smih0R=cdY#7*{IXqky}h|z)rOg zUmkvtT2HJ~qrAViTwc2ux6lob4zjKz4BF4Gv5L7){$wFz{kqJ6VhOGB!Unx0XR?!) z>7}Kc1Bn8UOgHjGt!4RUaePm>1BxCWY{`)vgp@R8#5JH6jrNA>Z`?DJD$|aIIvoR1 z>fJz(LM6jiP7PDE<*IH2qt0qktp``&Tc0eG9~yQ4zEgU97#SP^-RA)ODTX9`bW22f zA!c~bgd|Ksss*klN=S!n(vNb%8L;{z>pdbNiHzLz#SHw^8o@Z+Yo2v}nMd($1I;Ja zQk(N6=arp_qzijG8-vcJ12W6bF_ zW#lj3AdVn1%_TjfRF*xra{GNV)5Uy+7%3G|VSZ0PKyC34!_pI)NBsXnsfCx=1n=5@w3@M3_ z%i_T&J&A+WL5FF022@zmV;~e%afn%AY@VN z$(ob{);IfEFYElB)=PT%je@!{d~_nIR%p7b3A7p~O;>Kwq)@hE7NU#+pmSm^6U@jvxO5pr-Prm`MNMSlM}u}1V33T#s~8z0AjS0q`*8pF*Y z^hJ@)gzDQ&>CEZq#XFQEpi9x*8*#WUu+<@|WIJ>8=zxDRa7-aj(2Y2iylswY898&i zq#W#SYdo^5wrS`-@2s`0HiR^uqiHAzwZ68o6Y6y49h0==>paK{;{+>1E4^^1lIaTE;EJYY9PSK9|}|G9m{@bfA3Cq30o9{KB*w-N(B# zp8q7;3P5K!!)kg9Ge)*fthLoc3u2QJ1&!liF_L;&939ahJ3^RXkdGKy#%Bj@&qPWk z^@-l7*WETIf{Hg)vRo0xq)c)Nnwa!BnTJSrHK1BF7yB6rR$s|Wj=O+mV{h=!A1Jnz6F?%NeFiwlmYOC4_!#`XE@Hn0Qi4bur3nE-4J`>OQbH&yBoP8+APESeNJ0pq zg!98PTj$;HJNumL`>u1YbAA5dU;4{a*R$5W?sYGeT8!qg5NGL?LmV(#5(mL4yCnHz zbzt8$C&kf6aqw%Q#(B5Tk!_5@#B#6F%z+0gsn_KrQYpKz~@KmM_D zrRxJhKoiTd)e^&GM!P|y_goyl%-8w`Bkc`O&a7e|*z7=!by~lw?|d`!noxJSw)6yW zpQpZi>S|v<`u1&N@=!&fc!uLc>?-}a8&o`Kk)-L+epLEs`_mDev$m=V@Yy$}_sHb- zN!rFGe?-$UQa5K@NTUgfiEkGdp!t1;?fFs7$(e-|&DLPUWcVcQw^H!5vF!!c3Ozig zGc<_R7huJNrqSPIX=VXc2lDhbU;Sp6DJE9By%D>hZOm@u1~1nVzZpqhJ>WAe(4?xF z&;VPzfb`C}am%-UFjw1LX0DzvLvw!>o@DH&=c=@4Hj;Mj2$RQ_#5#?4#{~W$C6N>d zDaZv?Dki|2mIYKt5AvnF`{`vQ-Tpz-o6h^N6&dEFdyz?t(Em`M~w*i z11sZ6MI$-KT@eX4kr-)_%ZgH8BBF~Tr1-u-^$JcvYO||Walwua>lEB=#5+H=wFc{| z+XEAh0{vyb{zpcx_M-$$Ybe+thBH%Dht1aS5qaNQ?H;d)mYS$*b;S;o16B`6+jvB; zNB6fEA%vvf$JR*y>RkGvY2yR3MSW_5*HB|mmBWRO=q|aD_MWwh!YwTrw`jRoztV8* zenYGrZBZXi8~!Kl8bbdj?Zr+qu0?K7Mo;q{U+1^PDeq{qhNLSbRKK&vg(u-DEp+q zY(J1a8ipZAkNCdB!A&v2o$LLLFgxxNyBMp_sMWjG#t8|Tt=Og#b zGU+&Vf-7!heZi~ZLShl}MwRDqO_~Rcv1CV9q;i6+r`!&QmPYa`+w=k4WMmtfiJo&> zCQi`xvqckdTdrOEF}!BrQF3KzqR;O^?+ZB>dgm6`;wG+INcIZVyKk<67=6=vzHov9 zd)d>8$Mb;CeV-!0*pJO)d-$S=>|D_h220BSp#mt1m!zjyHrc`QLQEbGo%`Tg;~WsxABNQc&;eEDM%1j=XNaNQKMvC8O|D z9w&WIudcQRchxz-+C6gR7`RZ!-aOz)zkknrEXWsa9b985(Is&7icHTp*=k7#Ke%rd0rX`1^m3p|j7(>Y#<@xr z7NxzgGvF(4E>-n}6PE~GF`b;Ar$8AUz=m&Ah(Y{jj?;G%9s&Q_`bW^C(8E&ieqx(N znruD4s{1hrhw9SDnU4xCb+?<4lv>N8oU2kR)SIKy&e{`AujR)4=J0Gv=!rj1On-rc zkdzr_p7kT;+IjmOT zcsIQK^?$M;WlGlVMw;5^v{710)uCIR^^!n>d;@JtjCplbnp-eFwWg|PNoPmOOtNsH z#%>w?+LQPduQ(tRn5F4hO07Dq(_Z)pd^mbFL|@m4dJr<%xmu;`7m;Cvh3u{~ZkzP+ zU~Pe!jM;FamhzjNt@%fFdml_Y&@3$6@h_EmujI>5Tv{ z=4*cUi!}W5mSJc~Te4PSin^_S;Xp*JeJ}Qo**$5q5f4}d9-y0d>Q?0}$qx7bZp`4TK5BG_gh_%A@(98tT`rkp?f0jWk3px z$*Qg0?#cTiZSw15$9mwOzJb02%A4>bDA8uo3jSRJvoyq3vQc;(`NZCoU2o~&1tR0=%{N#0pVN=`5B!R+EoRScdvj8vq4GFDb9YWlwk=G#ZX0VSrFyTx&)E`$VlF|) z+Mul)$^~N~W18>Y1>Aobzbf>}{ZYexurF_tzx(`;Tvb%sKt# zJDyKBpe-Od^_L28Dc}F|`GfzTTpWL2fU|B1XqcV>6kY1}e7(&-zL8=m%i#NFvm?Cd zsd!`kwSn0|uS7peeiPeI_rfgr2CfD%A}YV*mFs74@RlW%;klX01+aOHN5OU zm4dHh%=W7N`Q6`lu3y4ZPV>9Y>XZETHo5@cF0H&m!Ft?N=1om{0QFnQGTEGag(o2s|4i@ zAguw%idWAcPG|dxw89bj4^gz7IB9q}UVoltv&yBdkMCaB01ATGr5Z``)l|1MyeD3F zsy+IJTywjw$a}aB#b`cRlyT&Xv@rCN8Bk?Pvwkr?80%o-OiXREp6;w^WKlR&X4?aU zUFMI3kL6HVE4RFLX?imQ&9gactLa@e?+X4T`)zvm#PJbO+~W&y!w|(v401)3EK&us zE*g*?xujR7+-Ld(&!Rj)m<&j#Yt4pRD@foWOAW3e3|_}Nc_w_wQqVOabE5i5`WMx zck-mdmx8o}^@WJ{*C2Ux;Uy`t< z9H^JeQb6N%NlkiR|K|<`BqF~wL9V*=4!N(f^5P6Ig>-z?whUvSc-I-mZ9}p!Hx-a| z#$TBJil^VXaK|C<$05^g?pkQPbyuhHiS}UY#&O6<+iu*9$q4jEzudK<31j`|nJMr| zcuM#7FT_kFD1YR# zKxxuJqpt>f47o+^s|f>@NO!-KH~|5qfwS@d+lKPnLHgWCb>q|sPh&#!TJD(T0Abhd z&-F7EdcX?<%sNan>Nni7Y@GoB4_`*dAI_V^Iw zR)(&kfa``{WIOl_k3h0d=YBiyHy4a)3*H;z&t2oSD+k{3PpRAq?@?LAAK{%8U;yZ9 z-VYx{jabkm>$8|nZ0=X-l=+lC5R`_DCJg6A1bhFn5itS z7R$pAy`g)xDOr}CtykPjZ3H9*3fr>IQ$5p-=eEo5Sh(a=xXL>e%TBA zht@Sv)O`A@B9_VosoW2_etJaf(?EaL+St}@Pgvct6de`$KjI(WviAFiV)ZmbG44sU ze2^nZScMHI_@;F{?mtPc#%GCBkH3!S;&qMd-A9#(;n3e!@ZNG}?qbOT)(`~Vngwc~ ztKKF@SWDo74ZKDl(%Tg*8Xz7y%5J&ztvw0DZOA|Nawbc9$u`? zIy!3>Jk%d~bmd9!y$IL7fMe;81x0#Q<}sjZfhGDiqGtuUs$ar9I0vchsz>FaKkvik zM}R&Gt0eU1HWe};(!jQG=}K*N&Z|gCE-ZM85i2+gqMt49y8w`YOU+Aa_8@-SYlc~L z599}_cDG5f9qfK3jy4m|STGcPkQzFA}Q_rI)6w3wMo z&yHy7oS9A3r={>-W9x>J8lhc+rtslNgT{W25}Tvg5t)J|=f+Jmh8oWlbxHQnL)PE0 zIiXMVzw1t}ZERkuo3pICwEM%R@tR zow%>PP^Buth~y*@$_;+u(BObaC;4fnQyyKJed;mBun8TUcHWP`dtK4(YbIcN_!ZM$ zCK)-oDK?zlA_CcT1joB@V#L6pRLxZ=YE|U;olkte&2&Vfo0M98SSzJ<9wlHdF&-k#o% z#+&b0<15z^?5At%GGmMy$&?bxj<5I~aIG%2Xbn|*&`ql!j}4YCoA`xbVf)SL zG1SwzKX$d}$BxW}W1p$QTzs(6+djPL0mmD#J`!vt4=Exmf9!Iksp| z?(Bi9SW3eNJ%tgXRRl8UEnTM8|3*XeB(bxKNu;!!f*~kI#OeYbHyf%~(%W}4#vp#} z^J^5pG57~;Wu&cx>N63j1S`l)$xV|-+&jeS4ZgfAnh*OCVibEZ! z4hX=9sT1F}#ei@oJMHHPS?8irqK8jeD(Hv!@4M$u84xOS#v>K0Jf8H^ z;>H-*<3M0a=|ZN>h7wpw#kwS?19K4$RfJK!ha~=|^RtP3>%##89x}$$7iCIOolmf8 z&S~&1d7xxOQA;deV|?aV|M@Cs7q3>~SVaY)saHiT-;?0xZ1%Vxgz?N!kxr(9!bI`fn=qToI^RZ|HeIf#KBB+n!Zb$mDt7P%Xz3NluD*tK>QcoT ziI}+p6`|Y=vg3Es50iQAy>m_e-VI=OG^`}?jJE5Gs07wr%sIleV`G;U+lQH#PY99f zW=f103VCFO`#-!9fT&${=TnmZ zbPsw@C$2PP3WzSQNg3LJ7Tncr(-7TfOF*4=!#R3vTKNkV#s1Z6VFyy6cDK^cO8N}9 zrjM*wYqJIj02wfU8}` zp4PLEy5{QWZ&rPTKXJY)UOQ+$I_Br}PU;D-U0WlN|)|rd+KBK z>)^yoyf#i**vKE$kzcaDSD~Q|w3cC?@5(0NfiAtsb?2oPiU1S~Gt?UjO?yQ!aD&4)z<~E?Sam3*0 zS*l_mo4n8ZFOF(8^j4q~5FV9mOS)AQEo0Ufm7_geFCQegY%-$HdpF5k1Q_WmE1dzW zFKJ|jcz7lgr*iJE-*^{dn-dXmxbFfeSchSV?%*S1g0BNAIV=tGWdIgBSlH!A;6-e!5L6xpvLLw05(3Z<4?;QAoK?^weBOv4{-?U8Y zr>2cLtb|*|=Q|eEv9|ebY(!eAdUPrdDPJ{RzdhhJr&o}f{8gm)Te6lJ2!1PSp)x8z zL=<+}Lvf?nd!m?7i>TS z`fKn>1#fs1j5_slzA8}h3NuQ0?E!V2us>qt4=1fNg-u#G$hK@ol|^x?D*ZZJ?YtCo2wRwIdLs;1J9U{ zh(`cI_BZ!(BZ#XFm>wLZF5Z$HBx=-o(2T;>962GNJTw8|A5TL=N#YT*2GMt%1|olt zB5YEPNe?x!_B>!#5yCjXQNK9!x#ahWKnwe|G&CRZ^DIz4R4Io50g9 zq}$kr?Y3_L^$$?fKFQd(ZMy0v-Xu({w#yHly1}PxCvnDP z)n`$UUxff#2?WmA?uaQs?W1JYHO$ZUp54A`R@zvXbJF?32R==0^7O-U*-eHJJ5$oi z(FxU^;9IFxNS|ft){_azbq|etjMr)cKpt>M7cNfkK_-tQyrPEErg@At^5A@xtcfyS z)DOkE&uZHzD$PdTtC788ee?tL5U}%|!$u@JO#HLcaeVv7@OyAWl^US6nfocj5kg;( z0%}Y>6*X|uQFsz-)sN^pVQ)n8TO&BTaP1)D5`Bikb_Mc+x&{AIU=K7%6?~OPBZ$i9 zhWh6oBYXCauK)_rJO9B#M7k-Ho#@`;UAhCG8y!9T$EP2RFd#{9b#Z;Rm%&N4i?@+* zk`Ias2!J>ptcS-}*>0s9djY8cOzR8#HepdXJ(m8yf9|PxwY|F)2p(b!;yg`8Vp7>Y z;SVa?yQ^6$u4KFrnV!r1yro@xK0*-zYn={?UDP4REI=SNVgxr=rmpJh?Z_=`b+%n* zlONEW_~!vuhN+dbfxAObEwpi5KIi~rX`h!vPF4}}8)bQ{EV|78h#bM$d_C0HDVg6< z)sJ@)KIkSzJ`%^Yz8_l)LSx$cYE&jcNNG7j78<{t6+aQ~A&blwZ~b#H-+dg+Ue`+l z@)_AxAWY}L#a}J#xSHg;8dgBLL3y=vqIhWQ`?A#zXItE|f;VE9bPh2sq)rJLss8}O z6nmS)YptS6*0t&)?@g206@)|U58rj8B}YL=OyoGJ97I_dD&YEW5r!X!rK~6;*|bwL8H$f!MgT* zo9aJLq95{dP-0IzT_Q=}8V!iH+*=9LCn%-oP2C%EAL=z}aO%o4gGpi2D=C|?cjqR5 zBXDe=JEm1HlLkssftosGv1Kt_u!w^Z`(dWKs7b~eq46IG3ONZ?h7y$nw>4mEVf#{37=~w(T_1SU!Ro6 z1_#;!D@=rJ{A|M6flT1l6g}w4EY=O0x(<^p4T*lqJ5Cf(kVS}8d_#z^&ESXo@TX5s zIT&lVXHE=Ah?t)@(0@NI4!u+Q8@2B&q`{W2;pYtjp*B8RW2J$GHe> z64&&biS|1*Hz|s)VcT$d#^f<1e^2#cGrBp`WW+f)1dw?99u26Qhbpdp|LqIOPG8X~K54?!mRrIrJ&>M_NnR~>|F{*KHhBT^ zw*Nl>`#wJ^n<@Yg=-=axU7d&R@9g?K?+Ty3Ax&tf#&ukjE4nH6N}eh$r`r(O_`3^NKTtx9ta%3LI0UD`DHy9FnkQq z`T>_#jaXd z57T#(U6h&r%07Ui=I2G-1i-*pQ`qmOqe^hBtb|8ez4ec|3*Q$l3t1-g@)xy18!F@? zf(ufHmJKloJZLfa*I^ynTr9c(zb9U#7W~jW1)_k3KZ4@*H}VT&V@qLI6x5S+ ztq!DX_(}nSd0zqh8$S-X@sNp5dqpSsL)`)lnGSv5DOjF#Bn?bVTNWm~?n7)(Vaa1_ zRgo${mA3bnndT2Gx|Uj+TC^O*ZNpmEv^CR|A56MWDv{#sg%LfcM<~aV;PqXSaZK$} z2nmxr)D372X8r}gF1fHv`QGNzCcNP}_w9GMB98f~CnRx{l z(F(VlsAkLm#ov`I<`Tq2ll2V`|T#yo8l$VTyZ^{P>UI^NPbm7tjKHYHntIgT5( za^zi}qFU5w>o)%=pe$EU>y~83nlv~JBdvAEUZq?V7x8Fp#YUf-!CkqXIUK1SqFzzAfbR{=U4hPmEB9|N9ADEDB7zBffC%Z1)7Xs=~;a2sP`@FkD4fo}y zO!B$QP!+URkFLG*rLIt*Rohuy%cH`85mxwK1_NrIC$Lu-5R5?y+H#-Ywr8my%u0T; zmIT&%5G@~69o{YGhz!{K96=p2dZ_6OMrsW?szJhjb3*r4gOFr(imD?Jw8z@yUDgOC zHMt;ufD_F`FR~-=skxx5YSLzw<5)`$^y>KsLNp$Ap+TttZaX#QZWG&c{O!)>V^Oa6 zg+RwArp`(};*?%21qYleOq~Bgd8}(re3CqNaN-z4V6}20aP%|I_bbqB@?}R=8lGLx zU8(v5P}BCBbdy&Ao+p) z`cv>?Fz)RqClo_G8XTfBCG(NNPJ6S1PwDM8qm*BV#&J@yRPNwzTAskI-=Q1?sRsTU^|k^K5S)a?Fh;vcpJC8^Exwd+J6@XaV} zV#%Dr!D)}2G7DeHoCB_RYYG3Kfro8Lm`-QK>t#OYruYfM;BM=8` zdsH0&iTy>Y+!Us#+5=wMB~U~Uix5l1InB==^Di6DdqrD&%daE+wTVASQ)| z15 zr7PVAB8T2RW|UxRCb{l#Oj(`DOB5EZ(ry~yp^%|@0P|o?0-Lm2q7 z`zZhd$!FOb&R$bOp6+}NEuXqDFD3RGzpu8_&UKr2%YNSG%J*r(BE=DZVyx8@$9s_J zSm;HwfvNPe!nhWVYF797Js({a|J3KU88YrOADQvM{s(**+mZrO(Aj=CY;Vnj)JAGw zQ$|UJE%~ytUrUYfeaOlSv0X*ddHvl9_FSrG6jyL19zY*uJj$8(Eg;*x zWn>DInp095KQHeCIu9Seo?5J~E0I-s6==w%O`NasbGC;)>b%Br8vvSxcpW6WsuZRx zgz*%@*BY5s{UKdINTtfSMv%2Y)8GCn4R-VcAbT(kPdv80*q|I}ueQQEp%O?D}Bl*ZF1F~S!W!DC{S9NuK|;#S3oIN{0l^H|mJIOLdUX(oxBj7mmG z^i6R!6+ zZu#hU8Kd{aS|bC{8IO+zq_(()XHuf1d6VZJV2X-!DpU&70_Gt+30Fczw(S{d7$=}) zJc(?_Szx}z37I1c({T^y1_QmAZ0q#cnYrD5?NyR;E zxxJs4@FVUZWkkY=4MR(*EuAl}c9%(gpqHwVx%~m6uxnz#N@5cZQ6=l$oVf0FR)aWH z>eZp~d7wXuRa@in86~808{=(2Pf8lzn%G&>TCuc?>|;d--D-W3inor!q4ACV+r}LM zBS|qQc16+S`Q!A#@L0|A6RO5&D|~tEFM7^snLDkMv2$>dXNFsr?fcla=+6uH>O%ng zofWt3TZ&|9WzBZToCG!{>Ee!Cn?V>UCVb(J9&-FX#vcS#<~jh_N~Z=_jb#Zck7^hRSdfu9B2DUvX+sVfHMMLk5>pvETr>bj#v| zVI7DwGwN4mK2Ux<3DU0rIlOuGAqmhD{sj_s?n7qgYgq7qXWsum2nGJu7x_Vc?(w-h zLqI!N<_=k1DD2%|S!aERWD*uMcz@8`_?CJ=lZ@{&08It%4d(mNmRaJ;?BSbT+9AV^ zEnB13Z>{>yKl z=1u?BHB#*Toefuid>)W9i&{K28&7c&@i)R0g+!-ezJy>%QkLUNrqOaL9lND@04=@` ze2zHIyy__f))VDV)s`CHCWZ9sdxrt!Re+}0$Y0oyL#|6V-%z%_U|&z{sJa=N{b#!u z&*dvg@P-q;vK`X^sp|?Lr1im>W|Jw1=UgY?Nvh=-a9=PE%i>kOY%dH+2(Yi2CHKT zO4ka^6E>HfzfICsjN#+e8pYA?&O&49R+}qTZ@`DGe{||=WkHs9Xc#OVPD1Ql|4lA% z+xkS(vQ~my%1t01ezUh6Tm>3+R`_$3GxUc%9A>+!zgLee%8@b$ZiT<7#@`%Jn74!t zIacPdfR#x>{RU!sJfPRgDp%f2gnR=w%l|`3F6tz_lL*4nXt#=@M4$ZSpk`GX<}fL>I0%Of<9Lv-b?vYchc5ng79& zx+sqoEqScf1j_2EqH%V+4(tKc#D$(h>$h$0Vg2nI_rCSLuclvfzB0x~-|Lq8noLQBm2Z**zHmL2G^mfPqZ6s6f6oa|1Dta8XfZ6Y?n= zcJJ?w%_V@R=LZVn3y@>licY`{s#|wzsJxi~p-my-5iZXxZMdCyA!8|lL_2r%KRNV( zTHV(ErONioj_#t@%&`Sjr-RG0&Zx?_2?bZ2Jn`mWMtd_8Lpw7L#JPWaGmir(tdf>Q zEs`W{aL6GY8=RG2R!V_TJAw3(vkMjY?EBg$bsm=vfjq=OSH_ zpTh@3*Y*S{^%$R0K)pa7o5d9G|#U|_-ugtHk zc5RGFs#a=K^sbJmQAv||v!cc`;O1Y)LIyhz86?b`9lKXbcihpO)iLhnSB|YZ&g&z^ zWVNn8HQV}=AIu|T)L<)WmuAVcG#_J&bKhl7_VA~(woh1TfGj0@jP-J}GMQ^F*){J1 zx^l63{PjPcGCW#2ZMdVn1k=XSw%W_nVUDp{N!dB71FHWT`PD)~d-8~J$K0u!?PSq! z$jWW9se_L`S;3FI>!5gB?b`H!F%b@AG6^#I)1 za%b)m23D79sZIni3HX$sHE}0z1=;0CGUXZUC%spnX^@ zj-YZ3yUq1tfYub^8{6$>f#LM^v!tw~`%>^eEEYE(lBl)y_i&32E|XS~^RP{003G7s zO_(el*DyjK>dWE4rKHw(8m=1bk(uxyH_XNucW5I<9vN1gM{7-G1vzUia`(f1E3>E! z`|JmtiUwEs6vHh7MG>g9Z#+JqmVZD$V>#M=ZUw2dEHc(;4#wW^();v!e`K~xd#pa| z4T@jM?44;A?<_(lWYSx~sodh{$FcKfos!QY000eKbOF&qa5Qo_a^)XcUCMDGD3Zn{ ziOU0sUFcD4rB*hZ7K(O;L_7j@kCos9$(*}>z78j58fN1<}R`{r&C^tSr z-=!WsfmCxIx9Usli^A!z!?T*b;$xQb%&7h@Y7yB1#kkge>G{j3y;z3(+VWueA)1{d zx6RMmdL~R0t9s*4C#Y&^V_w(hni^w%YDr!hA3%K<135Dr_j0sN&qQ7Dm%}yx4}<1` zQrLu6kvwzgCOUIMbUS>hpkD_Y?}~J&UM-1!UF>$V>!4FGDvf3wf#OF#c?C^szTF>@ z{Br$bJk4D%2$|rtdB2ozp&pH_ZY`O?C1lz7KAf+1k}S8aRHEH@WC=Mj(i_uo^o?Kf zX`#mPLzLRR0*%r>{P;rUy>{gl{q=_X7RH~Qj{B{>{enGfD4mA6E9le8BSCisrm?~E zvL<{5akw)c^0UZCG|Szy-$ufvby6}H;ihs+akX2;z1 z*gA1DV$CmCbw@GHTNn-7&K8pGoLwpW{6hYEaA9HbcrjXebMopP$Htthr=9Ce70b-+ zz3HwN#-y5U8H>)?&W>>6GOtKi4wI~DFvqWdPjJ1R73Zs?mjE+DM$^@>kC$|MpU&GQ zqlyK!P0(`eDVGsDhF1CWt2+O>?a{!!u^#5U7aW+145b`zkb5xf{a&zx)kmp{+&cbW zH^-d!eRPP8%acHT`)2=3s}}F33d8D2*=z0(;Nv{@Yb|b{t0fy;J08LPHtzlaT)7;~ z(V6eF>wCHW%*?Eyy1avCLnLauN**)Yr<;FBSPaZZMLC?hZ{fXRr&Y$3~oo9+nR^DTq z;uzwy=Pn6ed&I9C^_>0WDt>%!M)nB-UA|*vi_6IDw4y0V!-*7pwA3Ux3A(k}-%wmgM{^G9}24E5Jp{5l<80`&zy4iUwv*%TrS<^^%adOM) z*$k!$N|(a6MxDlZJh}a^sRaX5dl?QnLoA8>-fL`a4@!;@ zi-KJ5()!9SU;;0BxP{2DX!dy3H|tP62Gk56_wvO+YkE?Fz`@I$cnvg-Gk|cu?a$>* z39gHV?*lR(jp;7VtGU_lQPKMLwEMD!Cw!w0H@-~kUoTSB-8Neu(t4!?56Tf z{$(7x0ppOeqA;p|V`$H|mNnE%R?aWGc>0Y*g)^GUUvE+hy3g3Lryyd zMhk@0HofmNZm(?3{J$A-ey+y)n;_xi?*6SS{n7XMU+h`_T|@@BvK!r3{?70HUmU9c zpM?WnsQ)Jz$A7qR+X}x>1(3ott#VQz$ZW`gx<-x)An~qCZAN3UdLFfpw8l*!$U@iK zQQhsW9qPT!e>{QR;{ah&6D(rYWV}W#SXSNT?@vd@b3GsjF?DJ#JRR&?08OJcvTC<7 zh9_KqktkPF*S7@A`{y3g%muo1)AxumbW!ORM&8GO80xc~{CGbH2D@&!;x@|6eg~SW z>u0Rgc&|s;PMh9SGW5$b`V4y@6^H8X24q^M<5N^K<9jXw7##08{}%jt!$*CK<9a}N zUiT>mxdDjiA4^jR_i!soNiWt>_kW{+EGX?RO4uBjWqGKjz#lzx7wAQXjW=K;yf2ZD z_5u0fpC!w|Ah90A2R!Z9$zTBI>HY+f09hjIC#DWchQ+DHjpw`fkfDk}3aDgz^yA#E zRLJDil-yq)+^0`EZ9-Bu ztkFeeVb5)K1zNBHWpw|;5S&TUarXCAt$6Q}!!S9l?!1YEe>3Qf0KG(4UfH#&^O9cR zAfQF>!wlhHt^9!Qtl8i5zmWsBl=}}pgURjeHtW}|jF-`Byqf?II8a3P&~pJL7yPOZ ztlrWnwI<@jY5C^r=<6MtOx$C#w$Q742WAqHlk*f~ zbu-eV^k?b>@fvGcfr>jIos3$}%Y{Ew&1Np3&=y8OCis6?5@3RczOd5qzIVaF%d2y< zZLES)aRSCK$fR?ioOP>ga}OltrEE#ekN?s?M%Zi7d`X@U@RAOAg8W1l|Fv|6A?>B*<5{ zIAY}Mp&z^7{SpB{Zh>FDnqt3;(InBECq8yOezvdy0Dk2b{B`d9hW3#4J-HXEwzYm- z)=$Ry+jlR%yaxn*0kkwZbl`;e|M+vuLmri;J@DR(UwQX`ofs!H34WJ7e&lxefxjD@ z`pb~e-RE?7{N1lgxi_4;cTo1uS8&0{)p8#UMS0LZG$;1l@wqp0facKP7EXCq$x?K? z<9u_*8Yd8*zW-6P1hwKj2honY!{m1X2Oh(RrJJtR1BrA)%s&FxZZ1x;_Knl&Io!AM z?I^}0HJ9x12=>0(<|563J4-~8z=h{D7ffD(y(6qsPW4-k>aWO@D5hZCLepIE4kI2Jab7{_k!CHo(yhZ!yryKhbO z_jL#)CCFWX;N_^$&uu%IbTSEqQ#7gUk!}g!I4AG^$F+=`?By?7zfwh#t@~7~xc%hr z^fZa5-O0zn-;Y<}dS`=OnEz{nyScB*k5QQT1ux+7>^O@HTa557QZI=^=L{_cBcL3nlXLM#D znaaMP=oCK(f;pMO4$|+ZzpNTg@&`1plW8DFrzf;DklEt7wCV&8$;E0%yN7nvZ2uVC zf&XAe8Ce`_Ybi+8qSD2b>t>SS$Vz!E0%>P1JzgEFLzrD&kwW8%UDcf=+)dOxgi59V z#HlN)i=#vtIGJ^_>Sd2n4|BGYHN^~@E-b(Uu?qP!0u_dSWMsma=4GNmTMdQS*~nqq zx5IFk^`iTZjd%=tvm4_s9h*8~WO4^hn)Rvp5 z zzv-i`dpOZB;`saWlRhN^_oSKeXq<8Aa^pSK-oWUwjYuq0p#ioF<|+)$wP`(d|h>d`JM@%;{Z!QYaznHLXmuK4#cVbeu`{8gZY{9K3N=mEy8Pg_A!-(3M%mJzig zy>g^is78gozc$qeM+djX`H1=ibGaJJ^ zRZ*kqSiSzn&GR~=9U^V~&KByuIltCYin{pE%bscI07EYgUBzvgh5@xQA*E#j5cdGr zVDqM}qWev^)Q zr0c2%?KLg|Rg+elhJTh~U1Ozx8#Pd5@NEMr;(CKU$!|I|oD@CYIbu-}^_TxUXW97AGP(xV$vY zXmmtp+fGW|PT1pmZ7~b1=og3N?jA@dmuyR$yy~EHjYJP^TDW!+C?BC0C&Fv>HA;g^ zs}VK&n>P~rzbFDv{QvNbwt|2v-Lu{MRa>Iw!_LlYAY<+QB#_OXsDSQ8Te4+|$HwtF5!cFG) znYOV=Z!Va=iu=f{<|=qd_i?xGcGDxb0`0FFr~OS} zFYVYqYO3W1(U)rSYgq}r?*iCC#C4(ZxiFyFNbnmGVhHE&5S=}6e02RYGkolC&k3@P$n2(xMUhv(-5kk#zvTVU% zdHKsV#ppT;ol3MIUa+OVsW&~)hoEXZf)e9Js|g6v~0Ya-Mi9wnKyA2_U)ajiuhm)DVoVz((yLMvzbPs z9bH>5fJ>W0^_wAnvrz*Ks`VRaGw8Hs?zFd)-4L?L$&|&aZ%gelg#HRWW3N@aH+=e-S8jH+Qb7h%dv z()L}LG)48`Z#9a(3zEU)XHP3mKi*S%xca}|XBhlT5gsrXQ> zuWli=yJeTKnj)(eXUi(YA#c>{QM!BGiQz4pga_g1cIX}ON zvf_(Yi}NDZCa>WnVb4HaW6P$U_I>`QBTrZ4&R-!s)5J2YHZIYoP2~JuJv23hC(SO} z>99FKq-YE<)*`C1+}~>FPS@;pOlr~m6oY>?KgFIJw(0Cml)?6Qb%xbs8PBt zaz3kB)+OhgzKmAB#vIUs6VZZrR0bbJTwJy}E%rNK+u!4>KnOEnXhYjWWHW@yW_eIhttEpO^evSGUSE77NAzm} z1N}AU&PqM(0+nM+ZqAr%3))vNhu#BUWiMOHV>MiWQ19(H|Mb=mbNwY_p`rbaW8m$O z#TW0x5E~uF0-4%EX?)|7OxltlLh=kJ_-)%)@tW5E#ol{|HJz4MVR zh;)<)NQXoOL<|Ax1PF`;RH}rgQleC;krrA2MIk^aN(&GOY61~Lh$KKHA@KgxnK@_1 z^UZnw`mXoAu7`gqVVC>fd#`(~b&GCIj<{)?TDNypjkowLeDZXt^-k+9lytZ0^fkxf zpw!6ZS_?r*V&}la$0&Oz2xshN&j-Mo9+@r)S1kW&)RvTJB^#Y=`(t(R&J0I7pQK^@ z{Cdv<(CBM zcfWP^eBvAjG+ral$3NcPzZc#eWgm85D-MmZL1g-gy4z0=g}mU8+D+TB*OTUooodlCDraEW`?ptYsu)Eo9-jc86{8 zQmE+@HLzEC*L@L7GVm#<1Zrg6e7D~4X?T8z+_bZ2)^7(7gA$kkyK^ zVd65lW-gK(94z5=0Ts8Vu2$4coeaU%>gW>tsxYN0+dpU;#10W*@GYQ$MQC>o2 z1g4gUP5;PY11|L8>C#!H2d$#5sV|$x4eK>LW*9A@8A$pU-R-5Wmsu?y+%)eYWSdL?n`c(w$N4INRI&o%?w6M}BYyF^@tNWZP#xv0JZkk^r+Ki?%N|Q0;xhk-y}> zA0UomqyL2T31Uo#p5+dqTg=3x#W_+^yD~th%jr-VCDqzzrudprNJ)R+v77LP;byvL z9CF2`YN`*Ek5BR@t} zii`W4vPWlvX0bl9Egqd2@>N>xGHn6FT(JS>z3=*$i{(HzJ(ZS`%=gLn_xL*d8Oc^m zT(|!dN*44nD3}231LrALU;^Ja$Jv4JDxhzopQLXXU+(>^iUxe&H+Nan=vsqe&0Y+0 z8BmyfhpT{*YRkPd9e#Py@`JL~kt-&*Zz$9PePoiWol0tp#`iS_&;l=(dan8^O`kQp z@T3JUh@HsU^R%^>U6&?=gQ`s89A(DDyEv_PO*J&rhw{tnUc<^1$U?gsp& z08LViz0{4e1&xZg+B5sjm!e>fAEgJr+3v0e08}MW+7MuP22PV|t2+G7SDhJ%)O%X} z2W}ZVnnkmLkJ{LnZp`0Rl*Yu!TD;k7IQZ;G7*U z8a`BM!}PN;wUKfnAHrH8Xz!lG}-vQ-+S%(0+kGI)KB&%n>2x{F!rDvQ7AZEIP4lu4+Z1JWmaEsyrud_*-6 z>&{!QM!qC{6^fq0v)(;zHul9b>89+$lyZVb#J4>9oBU5t;wP^GQu7N3azMaFnWSq& zoCnwWsK~cW&oH><7man zIXiRvUBgp16`B$~>tUYnUtnr0F3mo!k=2Exc$KAO+ZLlWYh@7e3sNu^7-*|TGYsdn z7c@K>gm}xo9LelQ7jdPX_ zyFmPf)Xst|3`Lrn$hBiYtvOGK!$B9T1MG)=D-INn(z3cU_KL23}*DisjU_>2nb;FopKIh))Bt3QtAq%iZ z;+CYLAXAk*>cOxTCiulydvx*q*E1k(teZ%5h57y?7 zHK)Pe*;iQT!whfH+tInGjPQCyc^GbV@{vvVU`$ z>!X&!A*Mt5{-!xU4ktX3{1j*IiC|PgziX`CIsP1sXMi@1#WtQ}M`$KvU)e##u8(#* z%!*2Oj|1)sqGV#biDA4X`Ojz^&7|2ZNQ{|Y;TP%>%Y9qCUS9Up79=@|^F7h#g1#ds zBjK(?GkLF~)HGLn_@=MAuN}~7Oh;upDE{3@ftT)TgCmYG1t}WO#vlf{7N)f=Rzb2> zD?z6#n>v?Y1a>Jcg-sV;N*|Ct>+T#1_nq*aq}g%B@wA$j^PC8yN_p4FGXKjjco&Bm zi8Bo?&8sRU{<8D_>PrJS}+jLc7GP#*=eo6b|8YU{m)Nx&|A5-D5DQBgF+^|0YAv zVVk^~Jp_<~%B~@K`;GkgdS;3IN*BWX{t~%XQWrBE@fo&YaO3n=M61S|TabOxjFKEs zBJ^}^OVhbM#q5rQX-Sgi3asLf4Zq1wCaakXx4i6b*Ql!OXJla0W@u~-fMW=d3e*wx z&eIhsunJP+HLi^VI@hToa*9K9VTR&%LcM#WL*Mvf*b3S@-}BJ|a83UkoU_dq(CAA? zd9GF9EGr#^qsH0f6xWS12Ib1YV{Zw{KWY6b;W()M&kEB(7R~+15cmOq{`=;dhSjbZ zZOy_)YpIeL242JrjSkQ1OHPB%oC|uWz7Znm5M}3tQZ!$#wS7p?JAv-y8OOZ6yhcxj zvtZJ-OV;R{qa-K0$jbT4`*8H*g@Re8c0NQ-|Fyb~2jpyXU5;I~IiuF>NOwJ@Nopq2 z?ZfV|oAq+Qo6nDbs3LudK!r2c?y*Z(w{L6vx~k?z_|RScz0I?o-p?_6ejPAKCN1+E zYpZ}I20SRGyrPi7L4U;Jzp7$C|LW^>Eb^NXvVwQMacbqzQ=I}3;G|sTTi-C4ss|4w zIIaSHd48IwKPz!R7p(RaQ--#B5tAD&3rrVerb<$Z8(y49#dZwg{($$y;N|EdE249IQciYeI7|FJRutUiCMy8T0?;LoZk_@{{f3(R$^{D*MnBKoHb z*zXUVzZI7W|BP+_!@T@pr~HQ^ z(#J||-_>t&t8saIa~*}z@&7?$?A8OUevv@`<$U^VdF@x=d@yIVS~r`Xho+V*T6WF4 zf9_DT&n`v78p5-bCd?9brJfi9y}7*+fJxb3DJDNB)9b`EtZ(K;;oYQKEbm0~y;PS_ z2PxOa?02aPp({)Tc(Ln@Gao+G96rI{JUBF^Anwz$`XNzkSbKGQM4jR)N_TehT=XSC zsPkXb?5GMLF>UkIkw03>JkVpw=~`u4?{Z#|9tEDnWuR%(QaxLdH_VR>-SGpLnF+#D zA&KFfstJ(JOsC0vu4p16hxv>E5DeG&1$%7_6>t4?BXR(%{c zw+o)S(#F;tj#=-Sg9OVo4!&Ehc^R$T!3?fDVQ=V@OMgYGNkjOIChp5k7-}yM*WCZj zaKKf89DIeA;tPPM)e`CvL)^2Wr$!&EO)bLZ<;1fk@%CEW2MPri;F^-m(MKK;tB`e!zZgbO?SCi$1xMjzvc+K2KhttFMvE7E9GsWe~LkcoU4 zWK}7KK7RqjZuPl$Y};rgRG6%#1YR~+wr?ijyCA!vcIEWCDaJRj`sB~CL|ir@VT?PE zn|i%8nDp7=SIv)j$36123RkezUJcl;J3r(4n>j>I9={3|7>3X zQ2b82X*X!^zOEnwfaPFMdR`-ZG<`vp5mRH_VR++ zB#~LuH2z2^|Ed6Vbc*{9(OnEnas4G$GqRiPw-}Mnunr#UgR{b|7#Y-BmpC>eqpL4T zKd|XyG0-GwN)l&Jx1=5^-RAD7SZqcdx~$R#h_|TVE!zhtlS-tPItNDckn9Bd<^M=@a!#$iixir_=7{8SknzvJsIvng)x@ zKfq57I)oIuLvb;THkP>AF)r48zgllBFTYwsJK)W@X7o!T=1y0Lb@YAUwBeDFR6mKZ|< zMNG2_`@+}QXo(PUWAFyMJG9*it=7X0N1UT2ZaZ`&KYfN|+uYjgPWH`qs(|&O%}j;| zapKu=ARfH(Ob-(4_}NIOc7VI>_AxHTMupCunECiFy-_mpKH9gpRcn8sR%m8-%_P+? z;fR#3Pzi6Ls{pYVAwZgBMI`+?eeE+V#}3+>f#PKLkolgFB%$!z?aGi|^jQcvBc6&d zoINqE-V#k-oo#p-mhUt0v@@ZK*6BRp*wOAuaCzN^wB?)DA2XYNmAEX*uxd6>7!X6+XgRe35S(wl|(OoqMeH+%Xlq^0=F;tmws6 zkGD!tZMCgn+CW6VlOH|^I?Puro>r}WN7kB~x$VRld`vZDb^-LiWWVK^QS82?2GT%d zx`dAviZT=-0`KeVi~Q_bs1UxeAEbbwSlJ%J9u!m9Ap3f0tC34z4cN5!LB~F$w3LOd zsj0^BYHi~3szz67m!j<{<5LhnX^aovbp@ZizU4)?nbenJ)`|8e5pJA*a;Uy}Jj7^p z>9S55xAWb!Sfv-xQneS6s^p582~zjYEOCPzc2QDgg}7lk5#fl=Ls+RGdE0j8x=kKx z*Xuk`0ckH(Ckq{Qh59;M6jc##F;}=rNn0glAjnPDDq|V@*3U|t>?D!nFKUT)CYlj0 zb+jRC?_`oqC#a@i?v~kWIdO-dJ3bh3$zZ#AJxI;jJhU85pR`?3f3{@Z_Od!-XTMV@ z=7EKbhdbmwnor7#);M2HCP%0<3>>k1Oeetlwaj_urdJ1@Ah!<7JJ1ZB9{$E3 zWg+2M+08sNoMfDA&*|yzzm!$*foPA8VdAqC5`RtL9$F!Yp8oT34!>N{5g^t1Av!`9A82R!#jNwD1tc zAC=Jf`ELGauDY?KtME8YK|NTCr0mo^VA`T@H%$4c$>`0o6uS-%LS~4ZyI*NzUcS>r zN(O10xN|C3AG2j+ChSm}SXn&XNZupLX$ziIsy$a>vK@5?L<`xBE3&xq6#3#|qtnZb2gEfv5*pRyy1fIhY{qMERy+ z?_>=Y?08boa;M9~!RHo9B~xOR&UmDUz#qHz<8f$HiiKzmT}0Qk$jT%|#4>$XvQ4LB zv%I?n$p}6v2H#vXD4myZpfC-4>ACa+E%oWa`fl0J2TKEr7l%Ab8KiT|_Hn6Ch^fAb zu7mIr;b6vlb|s=$y>nUuH4tQ~uAb0&ES`M40^#TrMtcgP^>EL<3?b#McEJB3f!x?Hs!CHSR1-mW-reHiM`Wh z$8{^l_D$s-sW3ZeCI0z}PrDex;Ojm}laijiw&U9yC6v94o)A{Ef^XzqO3y!px+$|O zA_-s{0_1J=)87=856uY7e#K9nU%~tm4Hh}A9b_?;^qORRRA?lqmjC-%+ zxqhe{vcvd5ky%tHGT{BP7m-D?)GJ%|Js^rz`lxo@OU5VHtLm^v@=50O=^YiTe5tn< z%JN0V4$h=>=shV6msPa9ep*1M0e-V3laN%Ms5D;@*?`b8*O4CSH9Cb$$x9@Nq42kJ z%HVMhM4!u5UFtm_;T%Ub;AHfqCOlUmCZ)r&@w@lRmBXQvIT4|7DE@*xXCVkQxYp$ep=&ABU{;o1( zl1aJEmLid*vF4#`Z8uKAFGZ#lwTwRAa-?6+#-vgO71HWwD6nmSugnX0?KGjO z>7${U_qDYj(Xx*F`y*}Jim<&v(UuV>-Lk-FV1m$W_`8jToRKL8oukYSl8*xSIS40#|h{4QelIfI&%Y+hushTB;(E= zvcvd@KKU&0_+Ao$dU65 z8k6oi_>dCw%1z}DhtAlEM4is;v(QLT9N_Fi2vfBpIU}0Acx*4rUxV!;@GcuZ)MBm^UG5*V;V3Z_-on`^)}Mv;aGx zv60|1Bd!X*X-kO>JpJV5IyF@iCib=WA^*v1ygdqR*z(hy}2| zE*GZP9m>|<#Osf1k)c5sB2}<T==G*5c zzg)|g)$oyJEht4=GPG3d17gMedNDq@43Bwoc=n=QShnj4Wp&kuZ}-@KezM|t9_LNl zM`U8+>;$RGLdOnGH$6%pRo8&_P#If29N!lJ6g8Vp&f%RnG1h5V&lHl^S#M0$D3dI6 zeXFT@q26tehPelJvpeMMxbnxP{DkV~lSatqu5g8#6Jzfo*hdx9ykLyMYt4smzmk$4 zNV`rRuuu;_azKVy`go7xrh#3ZPSRy!QpANf@WJ)3KfLO#hxx?oz~^w{>bJliaE)suSBX zGajDp?Wv<&9|>_)Xi?NC#3reJnxx>Ryx$tkk~hEbUsw`{PC8TJiv_H)r6h4D+vPDk z_2$rt*7x=8eaMr}pB$U0o$*#4o%(t$)iq6gLW{JY`m&V|HRH&z*nXY4&f6kNMcvy>#ZCRW* z0p?2*8jq(-kmI@1lW)eAk4^`A&IJ}zCm-}&i{H!D6V98+L)E~2r&Wa^)>p1Cxx>7* z87|}SFc&(9mr;&8HM5Fi9bt>J4imywv`^8jZUl!wvhD^<91Fp9V!{)S@ey91iN-6<*eM;k)N0;jm=lcp$Y>SIbvGJTEolsFb9o-SQA6PX?aPiwc2B z)ij4}Nzxd!T{Po7yJMZ_rE+Z91S|u0PiVEHJRTuTU=8)@i1fC z%MTOx*qFT()$;pG5gz5lC4seD0p%6L6R2aGnTY!FY}1p$2t$4`E{;JXD>5}oJwXpH zEvXYy{Ij}S?)i51ZTEL>*Jy(CvE9jg5GpW9#PJ+mmRnc|Y+7!7uQ|DKFi~Y)P>_zgb{NoI|)4%mbm8U z1hI$noAHhhko(li?=0fVJ0H%3R=;JD&alZNBr`X~!rU`^n7bWm3^kA*^_tsCUH3f>MkRHK%yoILT{7b*QRN7XgnQ%5~WOHZy8IRIV z!Tn-%wW;p}pnJeM0rj(5*DhOMW549i(Pq+xwj(3c@hyoybCVTNV9hH3ea+6c_9*%f zD7Ksudg9aCCUB#(M?Q?D*z|gOvb4IR$3$JF|e0EBW2`xpBwG<;z9FI zC2wXWzBEg!4BR=yR1B-XY&MBHmAG+Rxi5k)2bU}oK#%4%QOKr*t%`!_O%aBFcuxsF z1Sa0Po_}hNT_p);#8OfbPrjCEPti2L*Drnjad?PNgDp;|@J2pKysYHoLpSF3G^~ zcq-q@xs(=m45Aey@?6CfEQ33WqMQJm*-M>0ap+$8%7g1$6f!%3kF)7)tZSAW`!-BV zqba-JZvVW{o`Ag2%9u2#4PuhE{rlRgUby!t^;ah8NRtIq2Objo^#bpO{Q={t_1ET**U#F2Z~R?k)=5*5{S zHRYb`j;>XQMrD!ebjPrhDgkqUZ+4qj9LQau_x7igbKQ2r1x`H*Kkedf)BH)HHH@h8`5 zdv%EdEt7+|v`?w5#1re6ki97N{k{BQ)8g57&w#}$IgYl&IKIxt5*HAImmV-hKhs}euwN*RVce=v)d$W^W%6a|@ zbo!EZUujE7`9uw}46+^udCD68US55*0sxLhT|N1d@cU@S9&YJZgvaR?&K4gb(P)(N zPXWE*Rbf`x&#y}+9-Uq^;kOkJ{&{^F%RQy4}%i)~2v zOvd&%t2XRlK0 zM3S~dG?g)_oH?!KI~LV)2}9ksA}Hn__tM`glQ_GjQZn!Rf1$ofH3#}gsk80yF>&U3 z?_29^2t$MBm->}Uw~8<3uG)0bGFQb!Hs&0atn`4=kDQEY-%{5(f}QuQD<6ccA!SUk<7<4tbSw9| zwoaH17-3{pVVe&4I7SmmnZEMv>Q6CLsQ=h8E`Pc1KzSB!garQ~-o2^`#87BThT~^n zp??pW-!adRp@64E!FoXQq;a(VZ{1UeOb&ImwJ@5$T)A;tx8}VN%;Rv*irVl9bdIG~ zcH>Euk=UWg+j;Xzt94g&ruM)}KF1>74N~g_ZBLEO`CfPuo>^0`Fw1`$bE#6<8#FC` zB&1DnHiX>BukP)s9f#B2x1?P<_>mkhbxIe#5=Iq7MGYULJ)!2Q9BX~L<4C2_N9>+J zk53H`Fj724I*4@zXk1o7D-^F`jVh^}A2Y)rq52)aU{4JIEZ5JboS-FfR-3u??9XAn z?8L9_AC?EQ2EGQ3pumzb-RE@@dsT{b7Zrz}RHvt*xGG+?&{Osqw0kQ()3}W9eBIx) z|9MLsD_fe`77^B-K{pgD9aKzDXBWw;XXq8D#NBx&aeEI4Hs^|xczqxrcTvJUCCAC8 z@6{^U&5X3xCAep)uwPuj)~it>V|am6jl}kxJeK9BSbxrsJKIf;Tl5uVol6H8xzXv# zD3mYvmi&0dxzYjg#n1-`A>2t&(KP+-l{|M7%+X9}Zx#(`z?MCauUHVpFoYhjWKP?N zfAE9MLeX?5F_ZQ)DE5IuVHa7yh&->L>;Uu38WBVxw+~c`oVcdavUTTcGY)&EyEStww8|Ouv%E7a$!=%FE5#ic9 z-`?_4CtdDMxOA&MeRp;}={a5hnu(?>gy~8_s2R@oaVi$Ye4P6S57J^NykD@e)@to1 zht4vX-p3nV4*JJrCRYoeozZcG@Ifmu{mW63RHYVw4b?$TSByJEbHZ4OGH}08lHW}OMv5CT69~D z5jj(u9I#iv5^CR-;(v@d5InFtj4`Tgh*f_8%@r#PeoK^itdYEYlv7HRPZOpZL~MLL z2yr@gHUqu$`*nHuPoVDK)5~=Gsy_MBy8gcWC*Fg{lte0TRwcloGL;8Ea#C)Ur`Y0i)3ur$jw6Ogo+$8`8o3l#TqGv5vdZs=o6AYZjq_agjE<}Aq~BNXk4UE}GShN^;QO4^b*57l+rTzhj6X^Xl}hBNz59=2x-<}CKIp>{ zSok=;7Vl(R^o{fQSTK4Ks(u?93 z1@mYGp^U7Oyo3i;mu9P6g{joAHs!gV#K<1mGu5baljoRrH!s_-*&b-39jW~G8Pv)u zXpl1;>izw)D4+XxnD0CjDS!7*w6u8`moeM?b-|m1#~d?fgOdc7vVVDTrt@}4)mrE2 z=y@UjQ_t*7t`>RKf=0dbmC$^)xBC`JQQ#Z3y zk)Pn5Vy359)qUTlO+2eMpJlPDBt$1Vq7J00@a)qW-Sir|`T+Kd6tz&J_7Dl4wAQ_J zZ*5dbDcz%dlCo;-yigJzSCycddEd6#pOYXrc`vgsHSoYo#CzXfeyX_lesVmz2hQJ@ zs=MraqHM`|*2`XXNim;i-M=7)*g-X8=OfVZlFpK@6STvBk_gUqN}j^@hzO6StP-Z*%(#ljg zD?oP_vQaYk>SLnW)Wi1FgY(U1A;(>X6H#p!1IHW^kdQ9Bn^}8uDod zXH-X@*z8w>O9ACs2d?=C4ob{qKLAN(n& z|I_r0XHs}fJUW{c%AFAN3FkHzqFaJ=u@S7Y+BabcUi~Dmf2IV&HB>7P!p5hh`Z29* zO|<o*V**aXpx53DqjXju zf>7Yb^^?Zd2e6gS;K|4@a_pKT=*mmWok5OhW2Y5qhV>q(Hq&ADQP2|K!^PLToZ*az zSK|j=h~j+`fAB9hL4VlaY}oL@@9(knIAgW$dJu?L5OIe@ER~$^FkP%M zB|6O&SEsW5N_T)|ZaIpf=Lb~sbS)E8+m6H0pe;oD+dfd!dfPza+S|Uv#K={IuB{jG zPoBbm8zWb-OGPBi9c65r^opaAUZ%nsEMo_h!HlL#O~H+z*>??Yjo7q?yizQI02X+g zxPz3qHs%3pS^StNnZxEOGzV}}6C*j&ImiB}oL(*a{;mX$Cnxj2%hvnn+t)RPj)uS4}4N*m)Ulenb)86ihs(VA+lltw4y=;FH@U78V~) zel0UujQPM@nq18qhy@rKi=w*A1M`a1E&rp>28xzji;b<06fN&`K!nyVYoI~dudGL* zK#LBi@te&{?X}4WrbhZ}8!@x$zC58LO{mpwDhN0?7?4X}Odnx?oT*!ff0z^j)W)fw z4qsJqxItaa_>uF{2d%f1c?~3*9!-+IW8FMPuwjORM#nxMss+ry5s*lFgvbpj(rye% zrhE+-_WTE;$v-ckPA9aj6r0}iMnTI3w>6Q6vp8wllpzj%5@>cH?Nip_oQyl} zso)bUOZABSc)=Dh-~Jy(z$H`gfqWEa&gVXw19qb^5GzwBuNh#vB91iLFk|wTC?)YJ z7AqwJ) zAb{F|??E{k+%yr2dsO%*f#Dx#1Nc*nr<5Vd@chg&P(lwN9b z%_R$81K3?}2JCKz@LDInOvVZ8XibD&#Y{7{`Z(SmTyLF;lBFS>p7$@4w<~1MXTMdo zCTVJi=Y!3s&oF$n$>ZXzHA=6PYN40y^os~{gxj7_5@o4>fuvrZ$-X_k0D`_q$OO7` zNYbc1g>^!1YpiCV#;UD}Fs=$WU*kZs%_GlH1m`Dp8IKt)nu4smUkln_PL>SNCn0-@ z(Hc^_bODJz}NK_<~E>l*VvT>kzUAWBCsH5^_P zXPj0>B&B+ktDto58voY@Z z^t^R@?Qf6D4IBP`8TwJi`vV1(hB}L-vc#atzh2ssek7!R1mKcpf9I0Er~B;M(%wce8o68^hDNq}N zWkKQ9c#89(O6iMG(0k0{Xj%oJGS?ekG<&oV#ZyYJe^Ep1{+-CQq4b{-g=Ht2_3h*O zg_2FolzxjHpWe&q###WRPKPZnyvO(=eAm6x8`HbOm=%GJtub*zT#Mvfc=w9h1;0LC z2Ch-!*QLjS7RSjkG~b9>YOo;t)2j0U{#fGh(awy{HWP>ArHh$vpD!D3DLIlY?V1mG zFJZb5KF^9&P7$7cdC->FOS^fb*IS*x(bH9GC47rb!hX65e-?x_mO4BN|Gq50x&HH; z;TwZ;IK~)yz)z(9;HdZ=XsG32a&{$5N5!iMus0~OjRKR>pI)iK?I8Q^%~7co%Pf@L z(cvak;78JOn-XnP5rw>2&LdqpIy>?vyeqkRW%8l(!T97CM@v(>yZGnE3s~6+w#ze* z`~B{mRW*Q!28FQ{j@}p}ym~umh*(`&*-ha=GQwm|iMCl4YzD3fH}+ckoi2Q!UxPD- zOXcDYtI?+^da98=+#|0c-!=2x~uPe$xb#0>hZq}jtI za~^WJ$xm@$q)E?edtWRy%{;Pd?`_#w|Yux9z)>IXR_7y+-w% zTAf*)<|(vS$;0oS?7_hMtu8M}aa#w9lr2{7o>sTLhQegMrC(-<*}()~&+1fYet-qj zO55U~$k$52a!5j2B0A~2v(tu`hX0tJzp)Mt#=o-;OZCOBZ|ZwsD6^I(R)O&#W<%2N z+^R{GIk%H`@z+pT7iR3xvlvM^sEGeq_Kr7}gXX+P^~;>>x3tMKg=Tt|MB&+%Fr~hA zH846}QKO*7&#F>=AAMR$O|leyzwrKr{wm*{qhI$b9c4Hju~f~Dg~!X9fs+!M0VTUG zAIYt!4DpstMt&QVv^7=sw=kA7WZSAUhbk86vUZj29F&wO-kXHvOm?Nh@cO<`SXJUZfe?`i-y@}fQ9?ck74L_ikm70@6#_h|I*;+ z|ICCbvB|f*MI}hxhFbE%ahBU<`>8IPe70VL9N(7UlJewZxEj(%sx2s%;`|hM-~{Q~Rf#k)x6<@lT519LX#V#6C9~GNpaP;#WIIaxWA%hu4RQtzchE{hkTb^j+nT+J2RWvpXEC=;bg* zGRi->t&1hi3wHN-b)bQS3GbEme{oMGmIrnet*K|f_bnvc`OsT1EW-`V0vGPZ7bvI zQ{VIKhmoHic0W+n&3?HmIwqA*qcaL;dL}e3O<^-KHkZLRICZrV(w!tpHCOb-J5IZ= zDw*H8_0sa%)Yq*aH{zy`>*gA&E0-(FRE#xy;5EPywDe~8Z-lf>Ju&8^wlUQq2(=t} zhAWtT+^Qulhs+;==|PmRJy%z>*e*q&pgGYBl5Mna*=qb`N{GB-f#-Bp$Bmc@LSTl7(yPX!ZduejZ;2`=3BExH z(i5o1;mg@x8~N(n9nu4*5q;i=?(}lbwTLN3w4e+e?FLr*PS)=$;ABF(>dmJit!hU1 z(o&GhZ@5qRi4ZOMxS9DynVL!%Vma5D_^(VGHcHXO`oFas<0J{%* zGD3JDG}gBV7v~CDTf4!1$zdeEyH2bZq7ALQ2xpX8DlkmIqZpM)|7%UVfx4X3qx8;v zShS?tA&0zzBy4Ez>q9k_3R>@F0&TiNkg8f1C1inb#$zweW$Ty6IdV=AyHH~0-VfAR zqD!MeUMu=Hex#9)KpLr(P+b~`p{#3T*Qp2Qbhr*{D3d>Y$3(;!^M9f9Y^?vt@AI-i z6?&;Peg;PrM~B_5%buC0-pU-draN|jy5#p;{9NEffzx^Bz7Az2=k2;Fv{c&WF}TK` z$kQ_)0C_6y?2$tTbJ~XTPr`#eepFVzfooqRbr7NSwYvk`BUfzSaM1t~Rai@kAoK`K zu6dvKNla%V$HE$&X>b5>13@BIhAyMZAfntwwHX4cdCjmgejNM=yBT2RoC96qzkN7+ z&0;0sImJ0-Q|CebAqWL@qGywAS&KY&L-}jva-x27!#9c-zU7zKOPh4UcyWJp8dN(7 zTtAEbSm<_;FmuZ{_p%yE_-4z#m-I|fQ0UPs)Q{@dfB&a}?qwpE4HiSW%<%c(mcwFY zk{-|`jsYO)Ny4y&!)35X;TdMGGxv`)Fi9m=qJb}-N%YAZlWyz1iqVhJJDpUQK)FP* zkW((ImM`&h$!vk7du&Meji&|q0FLAnAqWY&IDySk-i~wsk2EaaoC)bmp_dy(A_58m zNRvfb0?+=%0h_)KIJl>mlyw6Aq$i1VDAJbw&^V0^xUY}d<`BNwH>6KaPq+G z4UYBgfsLzfWfJ9xdZ7v4(w67Ya@^GNBkYGNLf`4{i40)oiGI8CN~`8(A|%(GC-j)d zeM`6$pDzvzjYoN5O|`!U3T3G8rc%998wm*ji?{9DE%+P%;z|k6N8+Zt~z}I=RBao_(Ou*TcDF6S! z`TB2EGgV3W68Vw8r?j4R6o5%pfQa%2UB>q6hO>@g$l9Y)$?H6@7z6&_QAADPe=u-o z$QBBr7JPe-?3_xgv3P&Peehka{`|gs5#o1(FFo7nMLkZSH&Duwoc(Xdyyy`_M{E}1aaYzTA(#DBJG`452P=46VpaH6a|Fi4U6j$(tx;9jjBwUnkq^%=%s zDIczKv(cB)o@KF`u7tt?Ip>XDAf8poH^v{ zC*f=`r=zg^o9d8sJEk-Xwe1{;V2%tr+`3|g5#4>zbgQ58sL^mSWiPImTacIn$S0$; zfqhJrh7b6Wm2HG<>zgSW<))yaepkV;khX5c4{RGJ4>eT6=m5>y&44ni!&QY(m2^4E_~nCY zBoQ!dVu}QQWfb!Do%L4qmQKxE?R&=-3$D?xdrlb!`sS)BNUBNz0;k7`P3x}>~d_ecJSDB1$)7Gfx2qa8I=Hy4ZANK$!S9_C`l-QV5!@GDEI zKElmW1db2gUEgqaMp=g~HDmO3Wvb`(#YYuo{jg#mPj7PHyqN!J0pk)BNf1>xsx?+u zC23V77}-VTnm+rWENOp$Q#aKrnW3Kt>TGF=W^#OeoB+g9Ll^ z+hx$&JEm@F3;mHEbM5NLns>PNt7L5L>)!zaQRiG8jY8^!4kfre$KF-)B3y;>$9hZu3Rnx-;NA&*M1TR8Pw%znj{Vc@~K?P3rz42_c=|?l9a;# zpo?wTKm^WmfD>y5a4{j1{LA(W+}_I(OFKzghI@3O#jG!azZ2*I-$hLL;mTcC0UcWC zj1)K?@if?kIcwEuDdA(A1e7THMV`wc36zgI1qLu^wlg6USsYt9FJ~ajVPDOkQ83 zhsI2yrfYuGbKZ&m9TxglBRi1KT<8=5YbVVb7?kn8PHU|gDU`hH5oZ+YaETvF#Evyt z+OXj~=9hm%F%hG* zp+0P{Rx2Xth{bTbg{j&W`JbW1;fhx=(xdhH!AQ=I2bY(OZCr>eG&o7MG%wq-jLsN1 z%J|hpeexW4TuM{_w1Q|-SY2l4m9|ToX-1UG5qXJzpO_KI35_WRI|EN zUJd**DF;OV{hDRGbg>~|YX74fR^Lyhyn2-RTFR#?qEF7>hCf#7P2xpY3Qa5#wfFG@ z(L#85hCepibr78G^hdtv=56BQg>-xPvML>OG_?kEEvbw$+s88nsUUVEwE zYAfjZDDKQ6jNVSa5x(WRDpq|^5 z(kPs=*VxG&x2@pB9b8(igCzY)MAz}u?add)9QxU7GvP5hboLDY3>JR-$ok&(;>*LT`8DTGJvrBTc&$fGzYa4q zA>3FuXTtZDl#)lvB9ggxk}>A1rT=#D%2_Bkx=pu;YBD=keSG}FhaP$fJM3@cl% zsz+$(q>g;3Qu*#`>wkzVI7}sigGw`*ZVo%lW#CqC)aKmN&Km|3v_j8Xv&`|z`_ZnM z%_j`Ct9`4~%5nqX%wegHf=aKoC2fN*x4>&{7L{XglLIeUOpZfNV8Rjj(2cN+a8Y7Z zI(jLbI`^Z)cnu=x>Aa@1Fi-97RC-5Hf=Xn0dj_n+sb8Ml{XDQyqm2xJ+(rx#bC{C6 z>4DXubyDfCZ_eidRZp)$p|AqCdw2=@6~~Ml8%HgZ*B*RlDARq*TmS<|nNE^bT&ug} zg>PBmt8Zy`U{e>7Qp#1@9hn!MAM&ggU8asK;%?Oa^m7X9T3A~`x7Lo4JqZAaP3;b< z*^x1+uyLyOj&B+-FWjJPoIJeWCjI(Srs;xJ=@tjJZ3Ki~i_TO(voPR6`hX_;?z>~( z4lMwKEX$B{T{4m(HL@hgy13{kv$YdR;tuM7z5YWy|$>m5Ibl7L%3ZN0LpZq}?A@ zx=(du0;XYDKf`d7k@(zkha^nqT!`1Xqa$bgx4;&UIy&F)ybwQex0w+bF}iS$=p}V@ zMxN{aQC)Er_U#Z25Q{&Y>{ui90F)M!bFq$1fGY;d?PTM>_4+ zdkCWnPPOEWj@niXZfKdye5a)zS=RBO{jBw^GJL4CHi~?&tptiTOBLmgcI3^!P!Br8 zpRq#cWL^n#`Rd^LCOE4(t>Xh!45+}>|Le>8SyJbTcS)jRk=*mWm*%NH zsm|%WOlEs`c#>7)l$l!}tBK7~C~!1xeZLL%9hcykO$q#@P%1y-F8H8?abTt4XpHMl@(NN$vNJf4QCMrkY`fPXCC_|};5 zVF0?X0-0ZMta#F)UkefJM%4St&^RNCy+|M0+=gISFLn_s(kF)?ZLjq&uHJ_a4gK?r z=|8B~gkmN&e+3OMup5>b6YbR$Q;hZ!Gcw6LbU9w-jJL?16s+}of(^P@4>et~-c5qe z`D$?JV?F=3daR}ohc7C(aVs8tNQadba{UEC&bnO$8=*RLJ=Ac@h$V}_RcTlroVB7< z{{)~|bY>&wNm`+cd0Qei1ncRMb9vq9u%&Jr!TNuuT}#G_Iq70zGlgCiby@2a8rVsT zyI29A!@0T)PdiZP=*VxQMLGodHoJrrpwzRTvi$|za_@F+I`^r3w$|JpoN^3A5R2nw z;9wzhd5M`3)aHnO&9TgX)?cQK*u7S#WSn(tW1kB7El!Fq&q;W=XKZkeNfo?QDO&u5^sYu!vyP#Yk&26Rt=leHOubx|xmEI1mobAxE#KVYWc9b&G#4aB z2Pn3O8S0#}{2VC-M9g%PV}G$K@VZ&lAbhHbs|`bOVsmr_hPLH5VyqA>J-RX(!BH#kU5l=N~+cAF>|D@OntL>E$1mvxxD&&lKBN`;}HK4+Q2EP zu+{|9idm9&g!5-R`MO)t2z2;Jm0<&c1QZ$vqQU^hV5^acP@{c*a+!9NWuJ2z`xnO(T>P{aypOJyal2qH3gn6=0 z=gPh9m1ZK(pb$Sp0b`%lkJfMNpyiyW0;Jy=Q_MUU#Xy~oz7QLkbH;{uTYsOk#SOeb z1RW625uc%k+o8pkbZ3$U*iIwS2h7uH3OM(L*k)d?+M6( zX8p?~=_ML_2u&jzW-Cd1XEVl6>En33{jlvbWED&_HynqRw`TfTOS&tf>6>TxR3ZK$B$s@nt~bUWQ>qxEywBGZo!U(Lrzq?y5JBn$u_T0 z33Zj48;;RhS^W&l;@_SrwUCNS^Ui{Q-;J+3JHl%q|-A*0fHIa{CSI7IBs!O%EW0?!r|(k#+a)|>qx zm%^sHPGN2ciDYZ4-jEcJBKRcBss>ckXxR+q>E zQPkVW%44<@YWSD;;{>ch8dgn4b|5%3UGlU#-}A6`&w0sGOcv?2Oy;1!VqkZZIfElm zyjQdzsdxf6Rs|}lV6OH{^MA-nR}$lkg_4M3R2_fGa^p3m`P@fRn(pKYq&)-tS>myQx?TZmI`O$w%1AQ zmNJvIl}=Al>a8&u*W8Dm?pDYfUE|>s+n_hi8goAKvJ(AkOhNqOdnQx3g^N4Rwmz*F zn}2p)F;(c*?p*3QQ^6R|#3Y8fUZV8n{&xILA0CBeK}JS90xM&vN*C+0w^*D>reDUMDjK>=BdgWD#{f;~Kj<_7^OGj#lZ&Z0jPraDTzRe7ijj(DCt*vUSU7&K zHZRT>a1*>?ZE$P3%h|&;b=y?dq9iSJ)a79r7+}({(=YBF$D=Ev<3MeVM@fD@-Eh&S zOJfEsr!$Pw>A0b`e{SyDzNq7~U@Nu@j9A5>A zeUjAATAySWW6-uHTQJ^wN!HK>+KJJ`$*q0sDQa_Z8!`Rre19^uO6sH#*q*2}R;ej? zEALU(;z1Zt@f<_Koi|Opk&DspiDbKF^Zl@pJ+4>IdW}AGgYE5acfV|E>%0ZLB`Vir zWLx>%9=9Wu8kt-l4PoYPyHu>0=;(yC&~Gw&Fnkf0hJ5^e0XX-foVG5bADYl}R%iMg zuVKQtE1}0dp{hAc94^a}h8z^}C6aU)1Y6L0TAyqCKh&K85~l5T7au`|?MJgx!T~52 z!sa>Y@SNqv{uL2A@?YOHP5n82nfu<63 zo~&n24{cQ2i^oWfpAbcLSGy#%tD#+*wy&9gvf!TykL~r7lvqw1iBiyh>~*lHyXD0! zwOFW3%z~a+4nt)7k=53hSIj-pA#QG_Zc}S<7eAAinUd#WOlgYfi`W5Xcxtyhn$pst zFC0CfmZ)nV>VmGGS&;&Kqe`!g=ykfCEJwcfKGgmFJ&hM$(z+1omNCWbcRhi{7k?&~ zAFtQSzFr9>`?;=hQ`=0Asy%RJbnGOOYO-e7F%mlMU)*71R^7u+K|lA~)a>CO(6s0F zzQ)5!jhxF8CFZfTo%p(AiQ*@k1f`ujXvZsQstsYXZqj2m&uijdZ0D7O$Bdu5Cdc8C zd9emBgW{=H!>rvLWSK4;q%Ce8M-jeM$T%j(h3;c$(P1WIJIQ(4=0h)|u%f9h13z+l zA4#b zn^qDjDFJvcC8zEHeYz7AT8y#7$OfdE%gPH+2Do{~R}O8C0n}=D@NF-%2dxFO?`JZZ zeZG-9;?9SfJMXyDxHkb&w&Ol#AKa-2+UY>Fk=E|aBXqn!elFW)0tZt6G2!I`W)xHa?28C}LLXuSWN41z@HF!C2v$9JDcVbG#NvIT&T z=5cc*j`N9*vcidt(%gBnY(l=7SG z2nk79Q~G9bVDH5fJKt<@3=5BOyNtfA5t0>W-XuRFA+Qc4X`SG_b^m4W(zyz^WQ!5| zifu)-P)za2!orE=Vi6**mvZD~@w?>kJcHY$DDg>#)>r`Aj4yKWPi2gBv}Jcxo>pI3 z;`0z^k*3$P%&$*{4K5Kl*Jr@*x(71GiO(SvOfGF2;9)af)QGQ~L{_#5I?u32) ze(d!lyenZNy#!?|*X-L%yC%|{!P99@?2g|28sFsGfMG7~4%SrK_r=5RQg&sDQ0d#d z#Xf3>(rO@F-NDU@O<{XqDD+1iR1`Jj_TAm^O7pjC{Us#n)sG&aRCB+viBG?CLc2Kb z@jc&e{t%OgYcb*7F6zA7uc6WTnV{p>3+t67D8W4$__sfK4yX)1c7*$1(DS)aIuIN& zYz(Ov?2o7r`eje3Q?<0%k65o$M7W#*7W$*u57PlEj!{8l{UU3Vr5wJ~1LhC+Ecj3b z`NnS*TJ4?rbKK=4{m<@oL=tuERGVrZW=^^BI6(;lveJ@Xx7Za57+kR9uI|AJSrK0= zqZ2gaL3=F`57`wEQiWI&68<`Fw23Zzub*A!$H)FO%vLC=-bD&)Q)P|P6ERzOIFX<4 zw_{+M#3H5{hvJY20aAP;xct;{U(@2CQ*wt?)-n`pD%)q*c$~i7a|~hQdo1{YHS4BS zNM47L2$*q8$}=GB3_~h#ZAufeCB@Ge=jyO(%;yo2t3^(bMF~JZyk@EzK-8Q_eHdY% zw1kUd^EIvwdN{Z8l_vO12~>y#-}wf0Fl#jvyBZDkn$txF!63eeLb(GOoS99-ArCW9 zjehnvA>uWkt7F~;h`fJ$u0!Bh=@#3OiT?@*GynleK$25!K$#G>NxSx!^Ji?!mXOZ& zm$``m!9m~+H3V;_y63l3Zl&d{T-s?c@Wci&NWRoh4idiR`aH|?tYafD^Xt})3{l%rZ#FGwO%6}!^d@>aI)`en zV2R|xjAu1p5ikhWm^Bfal^lM}Fs5X3H*#-OEq7k~;u#IZu4(K?&BXm?6_bllF|ZXZ zM^g9cnjeH~!ZUSrZIaE-;I`GM9|(B(r`m(GqV|9Ui3^#vBC(ebeyLTe5c98>g2Qs- zHk?;6pyWSW&4aIo;^L#J0XOd$idlQas4vSxQqJlf7eWLTo@sGUf#35x94gf;i3r+J zJ7Ezc0O?Hwp0Na>QUh7TPLuy{f{BI+60IW>G0zSJN}abd5)Y3(8u zhS_7j8bE$I6aYOHSuq}tQq%ThM`RvYm%c5ehVPo(Kx!Kf*sOoyOTkk%pbwFQD@i-9 z!E-G?>O)p#k%EG!kQYlN;2Uh*OH)k5P-Ffh5#rEJIKsvZU-am3_M`~;$PLA(DNmXf zULS(H%T6tdu0_kc?ZfXW9SUt+uu}i&m#kJ|h-1Yf(?!-VtKX}U$1oLPRvcU!zE;Y7 z4{OF>X;)sp2Ke#;a*vTt^^CdQCXv#fCjq&KUY1vA{QHVf8rS$PxnQurrZ5iozAx() zgC2EvfqvcLl2hb(I~}VvHC3D%n%EFTR2adzPVcrAL1rVpdGzd_L=dk;qFFA>;lrHs zUGFMgY=_^}`u>AAsms4VULJfOa#afMd;Qa?W{;uIy-Wzce%%^-rrMD zHmjc<+UFCg_w!Jv=&lLs64o#h!dckqAK=mDOufrZo)-@jogMq-(9#iTijPIOF>K0_ z|IoXiz5$SOxGoIs=)C9egN0wbCweAe5Dv4=ut`_13qLH(3)6L5+V9)Jo~KLD&`TMQ zmV(meWs|Vymvdov#xu)S)A~=(0$($Q1CAkxp!bU%k2_5 zw<>ezq!QWbyeeztycl~Leurn>5%Z!X^rkXCV|^3VQIcD(h78FE7~*J`@l&17VXnc4 zfEd6f8zRz=^3`2pn2?cz)r{G_m_I~LMyY(-i?mT0(%nI^liS`{segN`HMLVu7P=2 z_6}b~)ae}wkrPI3A&5kNmBhIJCQu+#O@R)RK2e{h7{Oo49XB{UCXVn;W2Pslm5iI? z_jI7=6@0+`XeZG|R;m=-D{g9_BT-v;^&NQm9~$;ziEnB_O8(}ow$ah>y666LxeiTv zfSmeJ-<~M9y~Z*E;gxYh_iqtYbG6x&CDUH^(dfpy?kvGuNDa$VPmYNibC08fZf8Y# zXPWbSFv%I6p{m*m2Bx}2J>%_VJytAGQsIxB(1JQEM#7X7)K$&T`$9urIIdU%Q#5`w zRg`q!CZgr2GaT177ne&5VSbG08UKxD`wtRE$%18Ad@y;9P)?(8)9*?RKRg2|hbeaXL?6V+iiNRjUz_(*LCG9nR*_F<9TJw7e z#B-1)Z!|KgoUX)CT}{ipQT%pjX@R&n(wzkw*XY}MGua3t6l@yS=We?#yS#HhGNsC9SUVad@mu7@sLeK7a4}?Ss}j%cNgW#H#~fmbU2(2!c>~f5){FB2MWg ztG%~mz7?=QWR#pwR6+x-XJ|r8RFdjXD~L>K_<&1!Tl)Q(y!r#86(f~fUcA4RgG>zE zOdVH9!-ljyTU4Zy^CB;anon~uPnxa94ru3Fgr`h35;ap%q`Dc*Khs zTI7#~=5HLoJxoTuG&e}v%*4DSxDOxhpQ-oHKAW}HWrrD9hgE;MHk4{manGO#0F}t^ zJRJ~o_GDq^9-KX1B|&YFsP_)6RZUU#cD^PMZ+=t)BT~IiZI?6nLFWu;7uPxMR?@^? z`12Eti*Plfcl8hc8d9~L9nQrS7nP7H=e-#aLgzT<5X_70l|0%UQ3I0>pX(TWi3@!_ zby#ZOP%jT_Lcz@v1}8eU*ZXBJ&*d>ccFFh`Rd^c02zIMHE(B1Y{}|-#)v#FQdn1^8 ztm{_gC=E&D%$Y}&n10H##t`+>t%O|?j)nNEw4%>Wb2wuY4K0Ol7Y>(uhmLTU?pl`S zxrfEn{CZ%s=D~+FHLe@hWE=WgI{Jm5gqQ*Wr|<7g$uC1YbBywEYGup0w8K$V&f_hw zZb#FI{l+h5@1(%Nt>{kOs<3xyf^BN}8j&)b+txKSOJB)I|Hxw3d!d&iA>(*X%((Z` z+Uw^dwYKyr2Ukt4KHrxWGg6#}Q_Jb5O#!=473p_nW zUMO(9bY{vD4?>R?Z8%T6jU}D9f{XV)!vNq!qVHdHOGS)SA9@A4#wJBFgG}Wc=99V; zmwLf<&6)pq$b z$-v!1DPVIwUAmMulhf^?#pizN3i3@n0l-s$Z?KjqHn12x)MZI6FtBtu9_eqb>kX~b zw0==MctKp0>y2uu3TW}G`B{&V{WVqf*TDjxdzxfK0J`J?jXcn>rCX5!*&1j#nnGZm z9%cLiQBQ}7pe|%ng=(fW{mxGQmoE7q&;(>8~B>QH% z?x7@_Fu0P&K47v?uXB^u)vQeJ!JxLQLCC2M!CiKkDgCqK+?MW*|LAP1nEje;o!5^p z3l&V#(rl%@QG_b8!vlof;z*U$g3+>lL;;vO@sEfNOvf-srGw-DsA)c1J-^k4|LYEX zDEwE8KXPJ928EZCOM>@aKUY1TwR`26Z%KV!xZyH7mNfBIQ02E?!_U6F|2^=V%G7_G z=l|p8dD~URd;fcVccW;NiU?h^HmH{UuKs;#(@6IqXbaf2;O)Z3pvFk0i1)Ks=)d;e z!wF-dYt8u^^M%Wc*?u>T$cds@;EQkDkR=@8Y@~#!r8i=63vsZtHZD>ZCV`}sqDRHviRUKHzLewBuiyXk+GO{zhm!2^m*pXuSbEw;ZB>A@+^e*5qqa@%7LX&4JvJbq@y*3w5fg!26Cu@-x$NBTrqXY+}Ai z%TmhbGL{^VN2&3aoKD^)-&7tm9D2<|$1nr%pl6j^lT$3G1f|udop%7@eUO2uzu}Q( z9zOQnf&?054=RI72H;iWGG)i)5@3a()D#So=drN54f^6E?=$dXQE@<$We2j@#!-fj zZze+5gA_xi^-U7S6vjt>#%r>D_tWov_u7@Hdnpc7+RQ0H4fze+W(MiH9r1AhBEN@( zr7m51+yz72KO-VoY#m$}mr`!c=vOqp5y*ReF5*$6kt0+cU1X(NH|jS1Fg}mU6tq>- zs+4lS64CBuWA8D(x~We1o9x^lk*kX(d+b1BCAuv!R3o=Efzk;>GjIq2!|8pT#|XNb z2N4Q^JA0bH-Y*{4tQ_6ng1DSre&7HSewP4e-bqQ^L5>UCL`H^K*gbOH!juLtjzvlZ z8Xhx!VE@=$5#;e0meCP<0@9c7YSg;EV_-*kd@rpXXZzbF=O4FQ>{*x_AD6$wj)cyX z+=$x&PTy>c2R%?Wz~9dl+Xh^4G%s$y#hc0uiVycxLf|@eMpVHOS-NhH=l9>LNdVe} zd(>1(zns1s5wtMyoZ}=1lMBqY?m%_;Qur8mtfyMt=Mu^E z8hRM`xcjk(EwmG^u zd}SXxHUEG?G=dbgf{I?bMx#(6{M-4W%P}Zv4F5ehqO=$DU(S)r#1OHKo2qE1i?9{t zVCO_IBli7n$?Od#2Mo0uK4RM)+&+qr@*l9cUjCJ2&9MUyX@ z*j&7PNWq(IFct2r8YSMxqB@R`z!t6B%GAcK+JdiL-Cqq!Py!38m)^+b`!5|GTNfzn z7O=Z!S2lpCwsxCbHVZWEQu0xkIu&?)e_Bib+q;fp>uS8+9wk?l&wJy^z4GM5VM7Ql zKfSd;v!dkgRB`;I#mf(4F zCPt>Z@}|i{ve`R{QW4BV&kn9BA^OeoJ9Ic}-dL0uEEY1vA2!Z+=Dg2Givbw9k0C~{ z;)Q$Xn3z_~0Uku8;ShMv-YCgtLwQY{)QPHnpxup_ViR=Y_yH(6aA4Q>b_tEF`*H$K zHEJ&<;M;#yB{}b@+grr6>XBUt9|ie2HqNCxX3aIZG#@3jUDn!bSd{Eir^}FQABj%z z(;=k6>NY{u6XcyY+Qo8&{N!BcZs4YooNaTvBwZP91!CLgoy6fOPwMq}Zr)}TLT9v4 z4qNwLp+SoUjce1&M^lOIyeTe=;q5+q7N1)~Ymh`rt zX?;+kw;}}hYxc8b(Y3C<**(H*sYj!7+>Yozg6czr1IWzO1uH@)te{+}VN>$B)gqnH zaaH_EJ(QDaHFj=2bSJkSqvr{u=Zu)5*Z!UbK66o@dk#pBIOI5DW2sf;6$r=Yri?4S z`Lrp0UE@N8O=5fx)mMwRlyg5#0v(olB^VvvI=KOQfqY}O`Zlu$M)hFn#=S4y;XTC=Q3%$6YcBG!c#)g!&oYSD=CE|DG9|7%!*ZV&Y*w0wES3eQdxp`;JET$^~#Z%?M=%Q@0-d}yb7B%ggFXb^0@3?`MQ~`GB9lDu&@(8 zH1Z%k%bXHxlJ7*nh*y!KzRYdJuYYZIuJs zV*iI1I>8u-Ki?au#O=+{k2tS9^pKAmUye-5SQ55DDOACOvp*WpsK~=dFZGdzf|>If zIOdB3W>&Rh2%AwKxd`1_g5P2?+9!>)sL)y4j%@AE?h)ro;@G2UNU30V)V$dgVd~(* z(o&RG;Nml3{_K30zE*(pidU%&>q5c6-6OsNtR_o3y1!d0fbC2dF0C zFnp29X|gZo2X9yO)bSU%v92leIn1VLfybo5%llTDCLMm?C3zJG*m+Rc-dv{ZA>qGb zP3|4u*sS`|^Qw%&ym-^R{6ety9#`(|=9>zGSro*abzW}w{~6Zg4L{@et^MBWB-i>A zqAB!xtI1JKygDz`6V4lZ9wJP2@wYf2k2EI#48DA*(!fL28j`hXNXuVf`0 z)Mx{`ohO&nVm)hgMcb~kllLsDRAvP(urzjm;Fn|1@B_)EhLojSg`rAA^`{&=uP|Y% z9hixf*GDK4>v~%tBq%{hf_@c}_N(aT(YTW%i&vFDxL17`NZ-B7_~4=iyG_lC@C%Us zA!*(eim)LVg?=EUD)!&P zVnkmZp-YBnzynV)cI!O<>3*FV!#aD%25#QWO{qIa?$6*_rtYn^l}Va zO$9!&8I$_QTW!>=*@ooBV+sJs;TqLSN3mcDNF6d>BlUw4$I6Xl++aj^tB5dOgj4qS zj!l3OQoSTyB4A`8tuk%t+Kc}#@8lr}UpHUY&Wdq}F`y6uBu71vvck*6()5j5Bk1eh zR^r(E3?*MJBC&E7eSlx)T>vq6srVftWSF%s@r;u$rz!vX_Za`zQ(g*wG!*C67y|IY zs;V8>j}Q)HEsCsWeF0Xp1hAl6j$TNvpg+eIIT%31eF9KRn;@VF(t}7ed*`E$Mp)ab z0s~$ufi|#Cs*>@6ro&Lw1#>SOS4nis5O&M%KB-X#jXJRwuO8bwyQ5UVLQr?h{tg65 zW9>Ub%H?7$gm{V~GY255O0E=L+2v%M0#cV;&PeRjEva7cIrE z3A084FDal}yHxlfAo;+fGoou65UgN?@b0g$TgD728aJu!6adW&{mjQoTr7H9y2P`9 z9fdWImb->HRoyCo=v9Oof9%o=MqHNu6BY8T8#@Qw?ewZ^S4Qd{^zV!(v5$n(9a69i z!Rfi(pj?HgEnf<){@zAQJchatb;s&_vH^r?`Q|XJ#M>xw4|~rg5VTSY5Uo(HEO&qx z;-EWEi@Y%cUR6&dwmdapxfADRhHzH-(cfuvGo@(%kB>Xty);YhIJ|*vOqdRO6Sq~} zy{+>nCd?r6r{LzZB*$*~U54c-ZI7coY=sEgOvJ*UCZ+8K%LG&_mucw8$n`MwDhG9& zlsRGTIwcoT`*L3RWl+f!9m~lgd4y-Z_6PixJ5F3!3W{_35#$PNj@$Wz$VI;wxD;w{ z9&B~@^IZl|6u;ug=A(H^J@*b)dlv?`$9c=_7cCw#(pPsrbMOF;E9IU(H--(mZtG)9 z^vP5ic)5R3iIUutkqY7X4MnIVzHM=&Eh>`EDW7^4r+B|1yLD=8?mA~T$Q_9+bh{=F z`9OP%b<#kDAWV326N0T?9j?fPW~A1rReU(E(xmhsXU;Gn% zlK$1Ltk@}k7TACCuWsdE-3s8G_^)o|U)_qCkI(&P_-9(nKZeD>x|RO{x|PrTr~ntu zoVLP^3i`V>YcfV{4zZR13mj*+*Rvrz>@f9n;SpzLNL`8z&j(I!jmqBI&B_c{q#TN| z`Mr%athy~}*XWSA+Hrb!F9{u%*EN*c8_^Y*+}MwXQQzr45A>qtxdgWmu=%5;@dx%= z^Q{77nbd)}US~ytYk`H;2<;keqC$Ipr8b&LU3v~X&b#*eV{KH_^lohb!fIIj^2xu3 z!9FWv{EJh;XM%$NzaMB@W7stRnI`+IHT1Wo)Dp8HUwPU7;`lKqG5)H1-!6%g;vIC!B#s%~aRV%(=fr9K7A%TK1VI z@9Grt=~G=!9PRzIGUY2OlPAso-k(BUKf>TY%@7Z`svTc#ma&JDbRf}?xnk8bYgG*x zhkVpKZQ(J{huopLOEx&xrXc72()kOm#`8WWv{IzQIPud7zm{tw3t5?>AA#&2 zPc|UqWCTg7k#QIu$ST0)Pc73+4vmqKS@6V*t#b;1xqWNT#YL z)m2G(>JCp14O*QqZf^A|02BI1jMqkE_LUkn0D1P4vwe5D=!z74bizrn(E4dVZ4okx z)>0?}zYW=Dm4mPmUzqBCws_1(F4jFmV}U!w2lJUd*#%lhLCvZnc>$5(Yg#?BcFvUGJ=#8v33A} zwNUccPH@HmlJuKc05jhWnqDt~-YZ3;;JDUZq9FKay#Pe*xNtqg9@7_i%q#p58BqRx za`CGUqgw%H|mq)t~#v68%M9`@ILts$QVFQui!mC`P&=oQ;coHE8?n8e$^WgX z%o;^9(c$!-4=W_tim~nV=f^O1tZwa$KmYUTkoKWP2R?C~>5ciFKs$bl{y8l$p}eXj z`24R2b4jafz+bL$2l6+U*n~*CBJzLn$pN(@yD@S+$kZ3RFf&mS#N#BZ4DmejJHzL2 z8sQ65eAPa=(Oj$zc)yzU1G@HmP~`X({({Px`dV7mI^P?L&O9{#)dZMN;%g?q3NLqJ zO@&@!FYsx6gM>7wzoQpwWeWSEGhj*7<)@LefS9piF(3$~M+hc+;dKjA%B*`lYlgV; zyo}k`1ZNOTnPm$Yb-AO2>KG6=bZS~OwOtp@Ql_iGF<&`rg&iXnySy%vp?$WDOs&$( zEegl&Ov(jtqlJ&G3S@xQtjfNr$wwIOHN_`p_)5{47rA0r0S@+Dc{>R7iUAjG$wVy% z0Ty^U{0{k@fJxjQQeS!s23g;4TS^Oz&i7r(ZUaU z^(0D&Aaq`_Pz79+=)%<{ieF>r@F(b~hzae*cAfbK{t%x!VH2^u@dH8VFYiQ`ms|vb z1duhYD7Vk0kbwVGQ+ES2rBV*yrH4(Ex>6#5fwMdL!}BxReB3iHu3!5-`;6Rd_VP1* zFzWq4+N#tSH_JAa=S88^mRoSk^qLP^-!C4<28oq{jaKOpT0*&1l48D{%TF$FJX^ig zKoBNd2JXD9KlC%0XG8=%+43V6M(#mFA>Izp6Jsf0o<}5mK7FVz=tI`$%We+97t!gS&fDH_u?01!v@yy#S9hyL`B44R1$*3G3*JhwH8)n%&-b5b%J#$ql{N-H& zF-$9F^)1CTU_C7ra}GcWRROecNbB)Fscj^mG<5mk{_1(Zc7|J7C9vA`m4f$ssnwy1 z$36J0{1536$QNxK$jQJm?8Szebe;|WXxMA0ml?dM{8(DWqJ68=lrO^vD9)Qimf-^j zeTR@9fFt4;cO`60;V->LTS?O8Bc>}(g%APb~^M zs&$eq_pShXqwI9A(Yw3@*HBPkJ=^-(&E%3CC4hzRHLzBF{>%pG)q+jQzx)sNt4xZt y&rfq>ez%1DgyL78bd}!sf9=WB`Sf}Ij}vBsYcvAA6jv5iLtRsy($l|O`+opHurCGx diff --git a/docs/product/moderation/moderation_history.md b/docs/product/moderation/moderation_history.md deleted file mode 100644 index 7ede326a..00000000 --- a/docs/product/moderation/moderation_history.md +++ /dev/null @@ -1,49 +0,0 @@ -# 历史记录 - -## 前提条件 - -[开通内容审核服务](moderation_enable.html)。 - -## 应用场景 - -**发现某条消息经过审核后的下发结果不符合业务预期,怎么办?** - -本文以文本审核服务为例,介绍如何通过查看**历史记录**页面定位问题和解决问题。 - -**1、进入 历史记录页** - -![img](/images/moderation/moderation_history_01.png) - -历史记录中的字段详细介绍如下: - -| 字段 | 描述 | -| :----------- | :----------------------------------------------------------- | -| 发送方ID | 表示内容发送方的环信用户 ID。规则测试页发起的审核,发送方的用户ID默认为 **test**。 | -| 接收方ID | 表示内容接收方的环信用户 ID | -| 会话类型 | 表示消息内容的会话类型,包括:单聊、群聊、聊天室。 | -| 消息内容 | 表示审核的内容。对于文本消息,显示具体文本内容;对于图片和音视频消息,显示文件链接,点击链接即可查看具体内容。 | -| 消息发送时间 | 表示内容的发送时间。如果是一条消息,则表示消息的发送时间;如果是规则测试页内容,则表示点击立即审核的时间。 | -| 规则名称 | 表示按该条规则配置的策略进行审核处理。 | -| 消息处置结果 | 表示消息内容的下发处理结果,存在通过/拦截/替换*** 3 种情况。 | -| 审核结果 | 表示消息内容的审核结果;如果成功返回结果,存在通过/拒绝/疑似3种情况;如果指定时间内未返回结果,则记为异常。 | -| 风险类型 | 当审核结果为“拒绝”时,表示发现违规内容,同时会返回违规原因(即风险类型)。 | - -**2、查看审核结果** - -![img](/images/moderation/moderation_history_02.png) - -判断审核结果是否符合业务预期? - -- 若不符合,会存在以下两种情况: - - 实际显示:通过,但预期:拒绝,则可新增自定义词来调整; - - 实际显示:拒绝,但预期:通过,则需联系商务,由专门运营人员支持调整; -- 若符合,则继续看第3步 - -**3、查看消息处置结果** - -![img](/images/moderation/moderation_history_03.png) - -判断消息处置结果是否符合业务预期? - -- 若不符合,修改对应的规则配置,详见[规则配置](moderation_rule_config.html); -- 若符合,说明审核服务的逻辑符合预期,但实际 IM 消息表现效果不一致,则请在IM的支持群中发出问题进行排查解决。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_manual_review.md b/docs/product/moderation/moderation_manual_review.md deleted file mode 100644 index 3509620b..00000000 --- a/docs/product/moderation/moderation_manual_review.md +++ /dev/null @@ -1,25 +0,0 @@ -# 人工审核 - -环信即时通讯 IM 支持对群组和聊天室消息进行人工实时审核。 - -## 前提条件 - -- 有效的 [环信即时通讯 IM 开发者账号](https://console.easemob.com/index); -- 在 Console 中开通内容审核服务:选择 **即时通讯** > 应用 **管理** > **功能配置总览**,进入 **试用功能** > **人工审核** 页面,点击 **申请开通**。如下图所示: - -![img](/images/moderation/moderation_manual_review_01.png) - -## 消息人工审核 - -下面以群组消息人工审核为例说明 console 操作步骤。 - -1. 在 Console 中点击具体应用的 **管理** 按钮,然后依次点击左侧导航栏的 **即时通讯** > **运营服务** > **群组管理**,进入群组管理页面; -2. 搜索指定的群组 ID,在群组列表中,点击需进行实时审核的 **群组 ID**,可以对群组消息进行实时管理操作; - -![img](/images/moderation/moderation_manual_review_02.png) - -1. 如下图,可以修改群组名称、公告,进行群组管理如设置全员禁言,作为系统管理员撤回群组消息,发送管理员通知信息,以及设置当前群组内本管理员的通知消息是否发送离线通知等: - -![img](/images/moderation/moderation_manual_review_03.png) - -聊天室消息人工审核同上流程。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_mechanism.md b/docs/product/moderation/moderation_mechanism.md deleted file mode 100644 index 7399e66f..00000000 --- a/docs/product/moderation/moderation_mechanism.md +++ /dev/null @@ -1,117 +0,0 @@ -# 消息审核机制 - -消息审核时,内容审核服务只对具体的消息内容进行审核,即消息的 bodies 中指定字段的内容。不同类型的消息,该字段的名称和内容不同,你需确保该字段只能传待审核的消息内容,否则会影响审核效果。本节介绍各类型消息的 bodies 中的消息内容字段。 - -消息示例如下所示: - -```json -{ - "msg_id": "5I02W-XX-8278a", - "timestamp": 1403099033211, - "direction":"outgoing", - "to": "XXXX", - "from": "XXXX", - "chat_type": "chat", - "payload": - { - "bodies": [ { - } - ], - "ext": - { - "key1": "value1", ...}, - "from":"XXXX", - "to":"XXXX" - } -} -``` - -## 文本消息 - -对于文本消息,内容审核服务仅对消息 bodies 中的 `msg` 字段的内容进行审核。 - -| 参数 | 类型 | 描述 | -| :----- | :----- | :------------------------------- | -| `msg` | String | 消息内容。 | - -示例: - -```json -"bodies": [{"msg":"welcome to easemob!", "type":"txt"}] -``` - -## 图片/语音/视频消息 - -对于图片、语音和视频消息,内容审核服务从文件的 URL 地址中下载文件进行审核。因此,审核服务会关注这些消息的 bodies 中的 `url` 字段。 - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------------------- | -| `url` | String | 图片、语音或视频消息的 URL 地址。 | - -1. 图片消息 bodies 示例: - -```json -"bodies": [ { "file_length":128827, "filename":"test1.jpg", "secret":"DRGM8OZrEeO1vaXXXXXXXXHBeKlIhDp0GCnFu54xOF3M6KLr", "size":{"height":1325,"width":746}, "type":"img", "url":"https://XXXX/XXXX/chatdemoui/chatfiles/65e54a4a-XXXX-XXXX-b821-ebde7b50cc4b", }] -``` - -2. 语音消息 bodies 示例: - -```json -"bodies": - [ - { - "file_length":6630, - "filename":"test1.amr", - "length":10, - "secret":"DRGM8OZrEeO1vafuJSo2IjHBeKlIhDp0GCnFu54xOF3M6KLr", - "type":"audio", - "url":"https://XXXX/XXXX/chatdemoui/chatfiles/0637e55a-f606-XXXX-XXXX-51f25fd1215b" - } - ] -``` -3. 视频消息 bodies 示例: - -```json -"bodies": [ { - "file_length": 58103, - "filename": "14XXXX.mp4", - "length": 10, - "secret": "VfEpSmSvEeS7yU8dwa9rAQc-DIL2HhmpujTNfSTsrDt6eNb_", - "size":{"height":480,"width":360}, - "thumb": "https://XXXX/XXXX/chatdemoui/chatfiles/67279b20-XXXX-XXXX-8eee-21d3334b3a97", - "thumb_secret": "ZyebKn9pEeSSfY03ROk7ND24zUf74s7HpPN1oMV-1JxN2O2I", - "type": "video", - "url": "https://XXXX/XXXX/chatdemoui/chatfiles/671dfe30-XXXX-XXXX-ba67-8fef0d502f46"}] -``` - -## 自定义消息 - -如果使用自定义消息审核,**需首先在[环信控制台](https://console.easemob.com/)[开通文本审核](moderation_enable.html)和[图片审核](moderation_enable.html),再联系商务开通自定义消息审核。** - -对于提交审核的自定义消息,消息中的 `customExts` 参数必须包含 `moderation` 节点,示例如下: - -```json -{ - "customExts": - { - "moderation": "{\"enable\": true,\"contents\":[{\"type\": \"text\",\"data\": \"你好\"}]}" - } -} -``` - -`moderation` 节点中的参数描述如下表所示: - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------- | -| `enable` | Boolean | 是否进行审核。
- 若需审核,必须设置为 `true`。
- 若不审核,设置为 `false`。| -| `contents` | Array | 消息内容。 | -| `type` | String | 消息类型。目前,审核服务只支持文本消息和图片消息,即该字段只能设置为 `text` 或 `img`。 | -| `data` | String | 要审核的消息内容。
- 对于文本消息,该字段为具体的消息内容;
- 对于图片消息,该字段为图片 URL。 | - - - - - - - - diff --git a/docs/product/moderation/moderation_overview.md b/docs/product/moderation/moderation_overview.md deleted file mode 100644 index 063ae28e..00000000 --- a/docs/product/moderation/moderation_overview.md +++ /dev/null @@ -1,54 +0,0 @@ -# 内容审核产品概述 - -## 产品简介 - -在使用环信 IM 服务时,您可以使用 IM 内容审核服务对消息内容进行多样化场景检测,帮助您对应用消息内容进行管控,规避内容违规风险。 - -### 产品功能描述 - -内容审核提供多种功能帮助客户定义消息审核规则: - -- 多消息类型审核:文本、图片、音频和视频消息类型均支持审核; -- 多维度细分消息:支持按单聊、群聊、聊天室维度细分消息,满足业务不同消息场景下设置不同审核规则的需求; -- 自定义消息处置规则:针对消息审核结果,支持客户定义消息下发或拦截的策略,保障消息下发结果满足业务需求; -- 消息审核结果可回调:支持将消息审核结果回调至客户服务器,便于用户同步审核结果数据、满足业务侧后续处理需求; -- 一站式内容审核后台:提供可视化的内容审核后台,支持查询审核记录、审核数据统计、自定义名单服务等功能,帮助客户一站式管理消息审核业务。 - -满足业务多场景的审核模型检测需求: - -- 智能文本识别:可识别涉政文本、违禁文本、暴恐文本、色情文本、辱骂文本、广告文本和垃圾内容,提供自定义词库检测; -- 智能图片识别:可识别涉政图片、违禁图片、暴恐图片、色情图片、广告图片和图片中违规文字,提供自定义图片检测; -- 智能音频文件识别:可识别涉政语音、违禁语音、暴恐语音、色情语音、辱骂语音、广告语音和娇喘语音; -- 智能视频文件识别:可识别涉政视频、违禁视频、暴恐视频、色情视频、辱骂视频、广告视频和 LOGO 水印。 - -## 产品特性 - -### 7 天免费试用 - -- 首次开通服务提供 7 天免费试用期,帮助客户充分测试并了解内容审核产品效果。 - -### 零集成成本,开通即用 - -- 针对支持的消息类型审核,无需客户集成,开通服务即可使用,节省大量的开发和维护成本。 - -### 个性化设置消息审核策略 - -- 支持客户设置个性化消息审核规则,更有一对一人员支持客户调整审核模型的效果,保障消息审核结果满足业务需求。 - -### 全面的内容审核方案 - -- 深入不同行业审核场景,提供高效、精细、全面的个性化内容审核方案。 - -## 应用场景 - -### 社交平台 - -- 识别单聊、群聊中文本消息、图片消息、音频消息、视频消息中的涉政、色情、辱骂、暴恐、广告导流等风险内容,净化应用内聊天环境。 - -### 直播聊天室 - -- 识别聊天室消息或直播弹幕中的涉政、涉黄、暴恐、广告导流等风险内容,支持实时识别,降低聊天室运营成本。 - -### 游戏互动 - -- 实时识别游戏公屏聊天消息中涉政、涉黄、暴恐、广告导流等风险内容,对风险内容进行有效管理,避免用户损失。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_record_callback.md b/docs/product/moderation/moderation_record_callback.md deleted file mode 100644 index 78558776..00000000 --- a/docs/product/moderation/moderation_record_callback.md +++ /dev/null @@ -1,63 +0,0 @@ -# 审核回调通知 - -## 配置审核回调通知 - -审核记录支持回调,具体操作步骤如下: - -1. 登录环信后台,进入**即时通讯 > 功能配置 > 消息回调**。 - -![img](/images/moderation/moderation_callback_01.png) - -2. 点击添加回调地址,选择**发送后回调**。 - -![img](/images/moderation/moderation_callback_02.png) - -3. 勾选 **内容审核**,其他字段的设置详见[配置回调规则](/product/enable_and_configure_IM.html#配置回调规则)。 - -![img](/images/moderation/moderation_callback_03.png) - - -## 审核回调内容 - -完成消息审核后,环信 IM 服务器将审核结果以 POST 方式发送到你设置的 HTTP 回调通知地址。 - -审核结果回调的示例代码如下所示: - -```json - { - "callId": "100220419126072#demo_54ae7e93-xxxx-xxxx-92f5-323e33187243", - "moderationResult": "PASS", - "providerResult": "PASS", - "security": "1f4857f120b2789b7d0abcd372c4f9e8", - "messageType": "txt", - "messageId": "1F4MX6iSdI7VFnN7Hm0vrcr3Uwr", - "targetType": "chat", - "appkey": "100220419126072#lydemo", - "source": { - - }, - "eventType": "moderation", - "from": "qa2", - "to": "qa1", - "url": "", - "msg": "你好", - "timestamp": 1668766253245 -} -``` - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------- | -| callId | String| 回调的标识。格式为 {appkey}_{uuid},其中 UUID 为随机生成,作为每条回调的唯一标识。| -| moderationResult | String | 消息处理结果:
- `PASS`:通过,直接下发消息;
- `REJECT`:拒绝下发;
- `EXCHANGE`:替换消息中的违规内容;
- `RECALL`:撤回发送的音频和视频。 | -| providerResult | String | 审核结果:
- `PASS`:消息中不包含违规内容;
- `REVIEWED`:消息中疑似包含违规内容;
- `REJECT`:消息存在违规内容。| -| security | String | 签名,格式如下: MD5(callId+Secret+timestamp),其中 Secret 详见[环信 IM 管理后台](https://console.easemob.com/user/login)的回调规则。 | -| messageType | String | 消息类型:
- `txt`:文本消息;
- `img`:图片消息;
- `audio`:语音消息;
- `video`:视频消息;
- `custom`:自定义消息。 | -| messageId | String | 消息 ID。 | -| targetType | String | 会话类型。
- `chat`:单聊;
- `groupchat`:群聊;
- `chatroom`:聊天室。 | -| appkey | String | 你的 App Key。 | -| eventType | String | 事件类型,审核服务为 `moderation`。| -| from | String | 消息发送方。 | -| to | String | 消息接收方:
- 单聊为对端用户 ID;
- 群聊时为群组 ID;
- 聊天室聊天为聊天室 ID。 | -| msg | String | 文本消息的内容。该参数仅在 `messageType` 为 `txt` 时存在。| -| url | String | 音频消息、视频消息、图片消息中附件 URL。该参数仅在 `messageType` 为 `img`、`audio` 或 `video` 时存在。 | -| timestamp | Long | 环信 IM 服务器接收到此消息的 Unix 时间戳,单位为毫秒。 | \ No newline at end of file diff --git a/docs/product/moderation/moderation_replace_refuse.md b/docs/product/moderation/moderation_replace_refuse.md deleted file mode 100644 index d01571da..00000000 --- a/docs/product/moderation/moderation_replace_refuse.md +++ /dev/null @@ -1,3 +0,0 @@ -**为什么处置方式选择了 `替换***`,但实际被拦截了没有发出来?** - -`替换***`在审核服务返回了识别的敏感词时生效。智能 AI 模型按语义识别出的违规内容时无法定位敏感词,因此会拦截消息。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_rule_config.md b/docs/product/moderation/moderation_rule_config.md deleted file mode 100644 index 615f6de5..00000000 --- a/docs/product/moderation/moderation_rule_config.md +++ /dev/null @@ -1,77 +0,0 @@ -# 规则配置 - -## 前提条件 - -[开通内容审核服务](moderation_enable.html)。 - -## 设置审核规则 - -本文以文本审核服务为例,介绍如何设置规则。 - -**1、进入文本审核-规则配置页** - -开通内容审核-文本审核功能后,规则配置页面中会有默认规则,各类会话场景下均提供了默认规则。 - -![img](/images/moderation/moderation_rule_config_01.png) - -**2、点击操作-更多-编辑,进入编辑规则窗口** - -如果需要审核单聊里的文本消息,则可编辑单聊文本规则,群聊、聊天室均同理。 - -![img](/images/moderation/moderation_rule_config_02.png) - -以单聊文本为例,编辑规则窗口如下: - -![img](/images/moderation/moderation_rule_config_03.png) - -规则中的字段详细介绍如下: - -| 字段 | 描述 | -| :------------------- | :----------------------------------------------------------- | -| 规则名称 | 审核规则的名称,为审核规则的唯一标识,不能超过 32 个字符。 | -| 会话类型 | 会话类型指审核规则生效的范围,包括:单聊会话、单个、多个或所有群聊会话和聊天室会话;例如,选择单聊,则表示是应用下单聊的所有文本消息会按照规则审核和处置。 | -| 启用规则(规则开关) | 是否启用审核规则。打开后规则生效,关闭则规则不生效。 | -| 消息处理 |
• 审核结果为拒绝时消息处理策略,包括:拦截、替换为 ***、通过;
• 审核结果为疑似时消息处理策略,包括:拦截、通过;
• 审核服务调用失败时消息处理策略,包括:拦截、通过;
• 消息拦截后客户端是否报错,包括:报错、不报错。 | -| 审核模型 | 内容审核支持多场景模型,可按需选择;文本审核仅有1个通用违规内容审核模型,包含策略:涉政&违禁&暴恐&色情&辱骂&广告&灌水&无意义;详见 内容审核模型策略。 | -| 用户处理策略 | 默认不处理。开启后,可以设置时间间隔、触发次数和用户自动处理的策略,触发后将对用户进行自动处理,详见 应用内用户管理章节。 | - -**3、检查【消息处理】的设置,按需调整** - -内容经过审核后,审核结果会出现 4 种情况(通过、拒绝、疑似,调用失败),支持按业务需求设置每种情况下的消息处置策略: - -- **审核结果为拒绝**:表示发现违规内容,建议拦截。 - - 支持 3 种处置策略:拦截、替换为 ***、通过。 - - 拦截:即不会下发消息。 - - 替换为`***`:表示会把敏感词替换为`***` 后再下发消息。说明:如果是智能语义识别出违规,不会返回违规敏感词,因此这种情况无法实现替换***时,会按拦截处理。 - - 通过:即下发消息。如果处于测试阶段,模型还没有调整至完全符合业务预期时,可选择该设置,即审核结果不会对消息产生影响;如果审核效果测试符合预期后,建议选择 **拦截** 或`替换为***`,即可对违规消息进行合理处置。 -- **审核结果为疑似**:表示可能存在违规内容,通常这部分内容如果有人工审核,建议人工再次审核。 - - 支持2种处置策略:拦截(即不会下发消息)和通过(即下发消息)。 -- **审核服务调用失败**:表示审核服务没有在一定时间内返回审核结果,即认为调用失败;例如文本审核接口超时时间为 200 毫秒,若该时间内未返回审核结果,则视为异常。通常认定为异常会有3种原因,一是没有调用权限,二是返回时间超时,三是服务出现异常。 - - 支持2种处置策略:拦截(即不会下发消息)和通过(即下发消息)。 -- **审核结果为通过**:表示未发现违规内容,默认下发消息,无需设置。 - -:::tip - 当消息被处置为**拦截**后,客户端会返回错误码:508,应用可根据错误码展示提示信息。 -::: - -**消息拦截后客户端是否报错**:表示消息被拦截后,发送方是否要感知到消息发送失败: - - **是(报错)**:即发送方会感知到消息发送失败(如下图示例); - - **否(不报错)**:即发送方不会感知到消息发送失败(即不会出现感叹号提示);如果应用内违规内容较多,建议选择**否**,以避免违规用户感知到被拦截后频繁尝试变体违规内容。 - -![img](/images/moderation/moderation_rule_config_04.png) - -**4、点击启用规则** - -规则状态默认是不启用。点击启用规则后,规则立即生效,表示文本消息会按该规则配置进行内容审核。 - -![img](/images/moderation/moderation_rule_config_05.png) - -**5、点击确定** - -![img](/images/moderation/moderation_rule_config_06.png) - -点击**确定**后,即规则修改保存成功。 - -![img](/images/moderation/moderation_rule_config_07.png) - -所有经过审核的内容可在 [历史记录](moderation_history.html) 页面查看。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_rule_test.md b/docs/product/moderation/moderation_rule_test.md deleted file mode 100644 index 339f918d..00000000 --- a/docs/product/moderation/moderation_rule_test.md +++ /dev/null @@ -1,36 +0,0 @@ -# 规则测试 - -## 前提条件 - -[开通内容审核服务](moderation_enable.html)。 - -## 测试审核效果 - -本文以文本审核服务为例,介绍如何使用后台**规则测试**页面快捷测试审核效果。 - -**1、进入规则测试页** - -选择**内容审核 > 文本审核 > 规则测试**,打开**规则测试**页面。 - -![img](/images/moderation/moderation_rule_test_01.png) - -**2、选择规则名称** - -**规则名称**可显示当前已创建的所有规则,选择后即会按对应规则审核,此处以单聊文本为例演示。 - -![img](/images/moderation/moderation_rule_test_02.png) - -**3、输入要审核的文本内容** - -![img](/images/moderation/moderation_rule_test_03.png) - -**4、点击立即审核,查看结果** - -![img](/images/moderation/moderation_rule_test_04.png) - -审核结果:表示智能模型审核返回的结果。如果该结果不符合预期,可通过新增自定义调整,如有疑问可联系商务。 - -- 调用成功时,会返回 通过/拒绝/疑似; -- 调用异常,会出现 无权限/调用失败(即超时未返回结果)2 类情况。 - -消息处理结果:表示消息的下发结果,根据规则里配置得出;存在通过/拦截/替换*** 3 种情况。如果该结果不符合预期,可通过修改规则配置调整,详见[规则配置](moderation_rule_config.html)。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_use_console.md b/docs/product/moderation/moderation_use_console.md deleted file mode 100644 index 7739eda5..00000000 --- a/docs/product/moderation/moderation_use_console.md +++ /dev/null @@ -1,12 +0,0 @@ -**如何开始使用内容审核服务?** - -1、[开通内容审核服务](moderation_enable.html)。 - -2、检查[规则配置](moderation_rule_config.html)。 - -3、测试审核效果: - -- 通过[规则测试](moderation_rule_test.html)页面测试; -- 如果您的应用已经实现了 IM 功能,则可直接用客户端发送消息测试审核效果。 - -4、关于消息拦截相关问题,如未成功拦截违规消息或拦截了正常消息,可查看[历史记录](moderation_history)页面定位和解决问题。 \ No newline at end of file diff --git a/docs/product/moderation/moderation_usermgmt.md b/docs/product/moderation/moderation_usermgmt.md deleted file mode 100644 index f8c53e4c..00000000 --- a/docs/product/moderation/moderation_usermgmt.md +++ /dev/null @@ -1,93 +0,0 @@ -# 用户管理 - -对于开发者来说,提供一个安全、干净的聊天环境至关重要。环信即时通讯 IM 提供了多维度服务可智能审核消息内容,发现用户不当行为后对用户和违规内容进行处理,具体包括: - -- 消息管理:消息内容举报,消息内容审核(文本审核,根据敏感词名单过滤、图片审核、域名审核),根据消息内容审核结果配置不同策略(下发或拦截); -- 用户管理:app 内用户管理、群组成员管理、聊天室成员管理。 - -## 前提条件 - -- 有效的 [环信即时通讯 IM 开发者账号](https://console.easemob.com/index); -- 账户余额大于 288 元; -- 消息举报功能需同时在客户端集成相应 API。 - -## 应用内用户管理 - -发现违规行为后,对于违规用户可以进行多种限制操作,包括:用户应用级别的控制、群组成员管理、聊天室成员管理。具体限制如下: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
分类功能描述
用户管理用户封禁禁用一个用户账户。禁用后,该用户会立即下线,且无法登录直到解除封禁。
强制用户下线强制用户下线,进入离线状态。被强制下线的用户需要重新登录才能正常使用 IM 服务。
删除用户该用户账号信息将被删除。如果被删除的用户是群组或者聊天室的所有者,该用户所管理的群组和聊天室也会相应被删除。
群组管理群组用户禁言群组禁言是指禁止指定群组用户在群组中发送消息。被禁言用户直到禁言状态被解除,才能发送消息。
群组全局禁言全局禁言是指禁止群组全部用户在群组中发送消息。被禁言的群组直到禁言状态被解除,群中成员才能发送消息。
群组黑名单被加入到群组黑名单的用户将被移出群,并且不能再次加入。
删除群成员删除群成员是指把用户从群成员列表中删除,被删除的用户需要重新加入群才能收到群消息。
聊天室管理聊天室用户禁言聊天室禁言是指禁止指定成员在聊天室中发送消息。被禁言用户直到禁言状态被解除,才能发送消息。
聊天室全局禁言全局禁言是指禁止聊天室全部用户在聊天室中发送消息。被禁言的聊天室直到禁言状态被解除,聊天室中成员才能发送消息。
聊天室黑名单被加入到聊天室黑名单列表的用户将被移出聊天室,并且不能再次加入。
删除聊天室成员删除聊天室成员是指把用户从聊天室成员列表中删除,被删除的用户需要重新加入聊天室才能收到聊天室消息。
- -## 用户管理 - -1. 在 Console 中点击具体应用的 **管理** 按钮,然后依次点击左侧导航栏的 **即时通讯** > **运营服务** > **用户管理**,进入用户管理页面; -2. 搜索指定的用户 ID,在用户列表中,点击操作的 ** -更多** 按钮,可以对用户进行封禁、强制下线、删除操作。 - -![img](/images/moderation/moderation_usermgmt_01.png) - -### 群组成员管理 - -1. 在 Console 中点击具体应用的 **管理** 按钮,然后依次点击左侧导航栏的 **即时通讯** > **运营服务** > **群组管理**,进入群组管理页面; -2. 搜索指定的群组 ID,在群组列表中,点击操作的 **更多** 按钮,可以对群成员进行删除、加入黑名单操作; - -![img](/images/moderation/moderation_usermgmt_02.png) - -### 聊天室成员管理 - -1. 在 Console 中点击具体应用的 **管理** 按钮,然后依次点击左侧导航栏的 **即时通讯** > **运营服务** > **聊天室管理**,进入聊天室管理页面; -2. 搜索指定的聊天室 ID,在聊天室列表中,点击操作的 **更多** 按钮,可以对聊天室成员进行删除、加入黑名单操作; - -![img](/images/moderation/moderation_usermgmt_03.png) \ No newline at end of file diff --git a/docs/product/pricing.md b/docs/product/pricing.md deleted file mode 100644 index 2114f0d9..00000000 --- a/docs/product/pricing.md +++ /dev/null @@ -1,241 +0,0 @@ -# 计费说明 - - - -当你在应用中使用环信 IM 服务,环信会收取费用,按月发布账单,进行扣款。 - -- 如果你使用中国数据中心,请参考本文的计费说明。 -- 如果你使用境外数据中心,请咨询环信商务。 - -## 计费方式 - -即时通讯 IM 目前采用如下计费方式: -- 预付费:按周期购买,提交订单时一次性预付。 -- 后付费:按自然月结算,每月 1 日扣除上一个自然月所产生的费用。 - -## 计费组成 - -即时通讯 IM 的费用由**基础服务费用**和**增值服务费用**组成。 - -### 基础服务费用 - -基础服务费用包含:**套餐包费用**和**套餐包外超量费用**。 -- **套餐包费用**:IM 套餐包分为免费版、专业版和旗舰版。创建应用后默认为免费版,你可以根据业务需求进行选择。各版本包含的功能与限制,详见[套餐包功能详情](#套餐包功能详情)。 -- **套餐包外超量费用**:超出套餐包免费额度以外的 DAU 和群组和聊天室总数上限所需支付的费用。 - -:::tip -每个套餐包仅对单个 App Key 生效。 -::: - -具体计费和价格如下表所示: - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

计费项

-
-

计费方式

-
-

专业版

-
-

旗舰版

-
-

套餐包费用

-
-

预付费

-
-

1299 元/月

-
-

2999 元/月

-
-

套餐外超量费用

-
-

峰值日活 DAU(按月)

-
-

后付费

-
-

1000元/1万个,不足1万的部分按1万计算。

-
-

峰值群组和聊天室总数(按月)

-
-

100 元/1万个,不足1万的部分按1万计算。

-
- -以下为计费示例: - -某用户订阅的即时通讯的套餐包为专业版,应用的当月最高 DAU 为 15,000,峰值群组和聊天室数为 110,000 个(免费额度为 100,000), 当月即时通讯服务费用为 1299 + 1000 + 100 = 2399 元。 - -## 增值服务费用 - -每一项增值服务都有独立的计费规则,使用下列增值服务产生的费用即为增值服务费用。 - -仅专业版和旗舰版支持订阅增值服务。 - -| 增值服务项 | 说明 | 计费方式 | 专业版 | 旗舰版 | -| :------------ | :----- | :------- | :------------ | :------------ | -| 消息云存储 | 包含历史消息记录文件和漫游消息 | 预付费 | 每延长 30 天,500 元/月 | 每延长 30 天,500元/月 | -| 扩展单个群成员数上限 | 对单个 App Key 内的所有群组生效 | 预付费 | 3000 人/群,500 元/月 | 8000 人/群,500 元/月 | -| 扩展单个用户可加入群组数上限 | 对单个 App Key 内的所有用户生效 | 预付费 | 2000 群/人:1000 元/月 | 5000 群/人:1000 元/月 | -| 群聊消息已读回执 | 功能介绍详见[群聊消息已读回执](/document/android/message_receipt.html#群聊)。 | 预付费 | 1000 元/月 | — | -| 全局禁言 | 功能介绍详见[全局禁言](/document/server-side/user_global_mute.html)。 | 预付费 | 500 元/月 | — | -| 回调 | 功能介绍详见[回调](/document/server-side/callback_overview.html)。 | 预付费 | 1000 元/月 | — | -| 用户在线状态(Presence)订阅 | 功能介绍详见[用户在线状态订阅](/document/server-side/presence.html)。 | 预付费 | 1000 元/月 | — | -| 消息表情回复 Reaction | 功能介绍详见[消息表情回复](/document/server-side/reaction.html)。 | 预付费 | 600 元/月 | — | -| 子区 Thread | 功能介绍详见[管理子区](/document/server-side/group_thread.html#管理子区)。 | 预付费 | 600 元/月 | — | -| 消息举报 | 功能介绍详见[消息举报](/document/android/moderation.html)。 | 预付费 | 500 元/月 | — | -| 回调异常缓存 | 功能介绍详见[补发回调存储信息接口描述](/document/server-side/callback_postsending.html#补发回调存储信息)。 | 预付费 | 2000 元/月 | 2000 元/月 | -| 消息人工审核 | 功能介绍详见[消息人工审核](https://docs-im.easemob.com/ccim/moderation/censor)。 | 预付费 |1000 元/月 | 1000 元/月 | -| 质量监控 | 功能介绍详见[请求质量](request_quality_overview.html)。 | 预付费 | 2000 元/月 | 2000 元/月 | - -:::tip -1. 翻译功能的价格请咨询环信商务。 -2. 内容审核功能的价格详见[内容审核计费说明](https://docs-im.easemob.com/ccim/moderation/price_domestic)。 -::: - -## 管理套餐包 - -### 订阅套餐包 - -使用即时通讯服务前,你可以在环信控制台订阅即时通讯套餐包。成功订阅的当天开始计费。 - -你可以参考如下步骤订阅即时通讯套餐包: - -1. 登录[环信控制台](https://console.easemob.com/user/login),在 **应用列表** 区域,选择你的应用,点击 **操作** 栏中的 **管理** 链接。 -2. 在左侧导航栏,选择 **即时通讯** > **功能配置** > **版本开通**。 -3. 选择套餐包,点击 **立即开通**。 -4. 进入 **即时通讯IM 服务版本** 页面,查看套餐包的功能详情,选择 **我已阅读并同意《环信云服务购买协议》**,然后点击 **提交订单** 完成支付。 - -### 订阅增值服务 - -你可以通过以下两种方法订阅增值服务: - -**方法一** - -[订阅套餐包](#订阅套餐包)时,你可以在 **即时通讯IM 服务版本** 页面下的相应套餐标签页的 **可选增值服务** 区域选择所需增值服务进行订阅。 - -**方法二** - -参考以下步骤订阅增值服务: - -1. 选择 **即时通讯** > **功能配置** > **功能配置总览**,选择要开通的服务,点击 **操作栏** 中的 **增值服务** 链接。 - -2. 进入 **即时通讯IM 服务版本**页面下的 **单独购买增值服务** 标签页,选择增值服务对应的 **付费开通** 按钮或所需服务项目,确定购买时长,然后选择 **我已阅读并同意《环信云服务购买协议》**。 - -3. 点击 **提交订单**,完成支付。 - -### 升级套餐包 - -你可以在环信控制台升级套餐包。升级成功后的当天开始按新版本计费,自动为你退还原套餐的剩余费用。 - -你可以通过以下两种方式升级套餐包: - -**方法一** - -1. 登录[环信控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,点击 **服务版本** 区域的 **当前版本** 对应的 **升级版本**,进入**即时通讯IM 服务版本** 页面。 - -2. 查看各套餐包的功能详情,根据业务需要选择套餐包,选择 **我已阅读并同意《环信云服务购买协议》**,点击 **提交订单**,完成支付。 - -**方法二** - -1. 在[环信控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **功能配置** > **功能配置总览**。 -2. 点击对应功能的 **操作** 一栏的 **升级**,进入**即时通讯IM 服务版本** 页面。 -3. 查看各套餐包的功能详情,根据业务需要选择套餐包,选择 **我已阅读并同意《环信云服务购买协议》**,点击 **提交订单**,完成支付。 - -:::tip -1. 原版本下订阅的所有增值服务会同时取消订阅并退还剩余费用。若你仍需要增值服务,请重新订阅。 -2. 如果需降级或取消套餐包服务,请联系环信商务。 -3. 套餐包降级时,目标版本不包含的功能会关闭。某些功能,例如回调,在关闭后会导致数据清除,无法恢复。 -::: - -### 续费套餐包 - -所有版本的即时通讯套餐包均默认自动续订。套餐包到期时,你也可以在环信控制台重新下单[订阅同版本或其他版本套餐](#订阅套餐包)。环信控制台暂不支持多笔订单订阅时长叠加。若你在套餐包未到期时创建了新订单,系统将自动为你关闭旧服务订单并退还剩余费用。 - -## 套餐包功能详情 - -各版本的套餐包支持的功能和使用限制见下表。 - -:::tip -1. `✓` 为各版本支持的功能。订阅了相应套餐包后,即可使用这些功能。 -2. `*` 为增值服务。若使用这些服务,可在环信控制台付费开通。 -::: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
模块功能免费版专业版旗舰版
用户免费日活跃用户数(DAU)1001000010000
注册用户总数上限100无限制无限制
单个用户的好友数上限10030003000
用户属性(提供用户头像、昵称、邮箱等数据存储服务)
消息消息云存储(提供消息的存储服务,包含历史消息记录和漫游消息)3 天7 天(可调*)90 天(可调*)
全消息类型(包括:文本、表情、语音、视频、图片、位置、透传、自定义等消息)
离线消息(支持单聊/群聊离线消息,上线后可拉取离线消息)
单聊消息已读回执
群聊消息已读回执*
消息撤回(支持客户端/REST 消息撤回)
消息推送
消息免打扰(在设置的免打扰时间内不收推送消息)
本地消息搜索(Android、iOS)
消息扩展
全平台离线推送(支持苹果、谷歌、华为、小米、OPPO、VIVO、魅族,自定义铃声和扩展)
群组免费峰值群组和聊天室数100个/月100000个/月100000个/月
群组总数上限(解散后不计数)100无限制无限制
单个群成员数上限100人/群300人/群(可调*)3000人/群(可调*)
单个用户可加入群组数上限100个群/人600个群/人(可调*)3000个群/人(可调*)
群组管理
聊天室聊天室总数上限(支持大型直播场景)无限制无限制
聊天室消息优先级
聊天室用户白名单
聊天室黑名单
聊天室新成员查看加入前消息
高级功能全局禁言(支持单聊、群聊、聊天室全局范围禁言)*
回调(提供全量消息路由转发,支持消息、用户状态和多种事件类型)*
用户在线状态订阅(客户端)*
多端多设备在线(支持不同设备同时在线,消息同步接收)
回调异常缓存(高保障回调)**
消息表情回复 Reaction*
子区 Thread*
REST API 调用频率可调*可调*
质量监控**
实时消息人工审核**
消息举报*
敏感词服务(基础词库)
说明:仅包含涉政词库,不支持配置自定义词
服务端会话列表
IM UIKit 和 CallKit(提供 IM 和 RTC UI 组件)
网络全球加速网络(SD-GMN,全球5大数据中心、200+ 边缘加速节点)
海外代理服务
特色功能翻译联系商务联系商务联系商务
内容审核(支持文本、图片、语音、视频消息的智能审核)联系商务联系商务联系商务
SDK支持Flutter 端
微信、支付宝、百度、字节、QQ 小程序
Uniapp(支持编译到 Android、iOS、各平台小程序)
Android 端
iOS 端
Web 端
APICloud 插件
Linux
MacOS(支持 Electron 版本)
Windows(支持 C#、Electron 版本)
Server SDK(Java 版本)
diff --git a/docs/product/product_chatroom_overview.md b/docs/product/product_chatroom_overview.md deleted file mode 100644 index f99ab3fd..00000000 --- a/docs/product/product_chatroom_overview.md +++ /dev/null @@ -1,70 +0,0 @@ -# 聊天室概述 - - - -## 聊天室基本介绍 - -聊天室是支持多人加入的类似 Twitch 的组织,可以应用于直播、消息广播等。聊天室中的成员没有固定关系,一旦离线后,不会收到聊天室中的任何消息,(除了聊天室白名单中的成员)超过 2 分钟会自动退出聊天室。若需调整该时间,需联系环信商务。 - -### 聊天室成员角色 - -| 聊天室成员角色
| 描述
| 管理权限 | -| :------ | :-------------- | :------------ | -| 普通成员 | 不具备管理权限的普通成员。 | 普通成员可以:
- 在聊天室内发送和接收消息;
- 获取聊天室详情;
- 退出聊天室;
- 获取聊天室公告;
- 获取聊天室成员列表;
- 设置和删除自定义属性(key-value);
- 获取聊天室自定义属性。| -| 聊天室管理员 | 由聊天室所有者指定,协助聊天室所有者进行管理,拥有一定的管理权限。 | 除了普通成员的权限,管理员还具备以下权限:
- 修改聊天室名称和聊天室描述;
- 更新聊天室公告;
- 将成员被移出聊天室;
- 管理聊天室白名单;
- 管理聊天室黑名单;
- 管理聊天室禁言列表;
- 开启和关闭聊天室全员禁言。 | -| 聊天室所有者 | 聊天室的创建者默认成为聊天室所有者,在聊天室中拥有最高权限。 | 除了管理员权限,聊天室所有者还具备以下权限:
- 添加和移除管理员;
- 解散聊天室;
- 变更聊天室所有者。 | - -:::tip -仅聊天室超级管理员具有在客户端创建聊天室的权限。环信即时通讯 IM 提供多个管理超级管理员的 REST 接口,包括获取、添加、撤销等操作。 -::: - -### 群组与聊天室的区别 - -群组和聊天室均为支持多人沟通的即时通讯系统。两者的区别在于,群组中的成员会有固定的强的关系,成员加入后会长时间的在群组中。聊天室中的成员没有固定关系,类似与一个开放的空间,用户可以自由加入,离开即退出聊天室。 - -详见[群组概述](group_overview.html)。 - -## 功能列表 - -### 创建和管理聊天室 - -| 功能 | 描述 | -| :------------- | :----------------------------------------------------------- | -| 创建聊天室 | 只有被赋予 [超级管理员](/document/server-side/chatroom_superadmin.html) 权限的用户有权限创建聊天室。建议[调用 REST 接口创建聊天室](/document/server-side/chatroom_manage.html#创建聊天室),设置聊天室名称、聊天室描述、聊天室成员最大人数(包括管理员)、聊天室管理员和普通成员以及聊天室扩展信息。 | -| 加入聊天室 | 没有被加入黑名单的所有 app 用户可自由加入聊天室。 | -| 离开聊天室 | 所有聊天室成员都可以自由退出聊天室;也可能被动离开聊天室,原因分为:被管理员移出聊天室、聊天室解散和用户账号离线。
与群主无法退出群组不同,聊天室所有者可以离开聊天室,重新进入聊天室仍是该聊天室的所有者。除了 Web 端,其他端在初始化时可以设置是否允许聊天室所有者离开聊天室。
由于网络等原因,聊天室中的成员离线超过 2 分钟会自动退出聊天室,若需调整该时间,需联系环信商务。不过,聊天室白名单中的成员(聊天室所有者和管理员默认加入白名单)和[调用 RESTful API 创建聊天室](/document/server-side/chatroom_manage.html#创建聊天室)时拉入的用户若从未登录过,不会退出。
退出聊天室时,SDK 默认删除该聊天室所有本地消息。若要保留这些消息,可在 SDK 初始化时进行设置。 | -| 解散聊天室 | 需要聊天室所有者权限。 | -| 获取聊天室详情 | 所有聊天室成员有权限获取聊天室详情,包括聊天室 ID、聊天室名称,聊天室描述、最大成员数、聊天室所有者、是否全员禁言以及聊天室角色类型。聊天室公告、管理员列表、成员列表、黑名单列表、禁言列表需单独调用接口获取。 | -| 实时更新聊天室成员人数 | 如果聊天室短时间内有成员频繁加入或退出时,可以实现实时更新聊天室成员人数。| - -### 聊天室成员管理 - -| 功能 | 描述 | -| :----------------- | :----------------------------------------------------------- | -| 获取聊天室成员列表 | 所有聊天室成员均可获取当前聊天室成员列表。 | -| 变更聊天室所有者 | 聊天室所有者可以将聊天室的所有权转让给指定的聊天室成员。所有权转移后,聊天室所有者成为聊天室的普通成员。 | -| 聊天室禁言列表 | 需要聊天室所有者或管理员权限,可以对单个聊天室成员进行禁言。 | -| 聊天室全员禁言 | 需要聊天室所有者或管理员权限。全员禁言时,默认聊天室所有者和管理员不禁言。 | -| 聊天室白名单 | 需要聊天室所有者或管理员权限。全员禁言时,白名单的成员可以发消息。 | -| 聊天室黑名单 | 需要聊天室所有者或管理员权限,被加入黑名单的成员会被移出聊天室。黑名单中的成员需要聊天室所有者主动从黑名单移除后才能再次加入聊天室。 | -| 管理聊天室管理员 | 仅聊天室所有者可以对成员指定或移除管理员权限。 | - -### 聊天室属性管理 - -| 功能 | 描述 | -| :----------------- | :----------------------------------------------------------- | -| 修改聊天室名称 | 需要聊天室所有者权限。 | -| 获取/更新聊天室公告 | 仅聊天室所有者有权限更新公告、删除公告。
公告更新会通过监听同步给所有成员。 | -| 管理聊天室自定义属性(key-value) | 设置、获取和删除以及强制设置和强制删除聊天室自定义属性。 | - -### 监听聊天室事件 - -你可以实现聊天室事件监听,聊天室内进行了相关操作,例如,有新成员加入聊天室、退出聊天室、被添加到禁言列表、黑名单列表等,聊天室中的其他人员会收到相关事件,详见[监听聊天室事件](/document/android/room_manage.html#监听聊天室事件)。 - -## 聊天室事件回调 - -你可以实现发送后回调,使环信 IM 服务器将聊天室事件同步给你的应用服务器。若聊天室内发生新成员加入、退出、被添加到禁言列表、黑名单列表等相关操作时,环信 IM 服务器向应用服务器发起 HTTP/HTTPS POST 请求,同步所发生的事件,详见[聊天室事件回调文档](/document/server-side/callback_group_room_create.html)。 - -## 聊天室限制 - -聊天室相关限制,包括聊天室成员数量、基本属性和自定义属性的相关限制,详见[聊天室限制](/product/limitation.html#聊天室)文档。 \ No newline at end of file diff --git a/docs/product/product_dynamics.md b/docs/product/product_dynamics.md deleted file mode 100644 index 78e55eab..00000000 --- a/docs/product/product_dynamics.md +++ /dev/null @@ -1,75 +0,0 @@ -# 产品动态 - -## 2024-12 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.11.0 开发版发布 | **新增特性**:
- 新增拉取服务器漫游消息时会读取服务端的消息已读和送达状态。该功能只适用于单聊消息,默认关闭,如果需要,请联系环信商务开通。
- 聊天室成员被禁言后,该成员会收到禁言事件,可查看禁言过期时间。
- Web 端与移动端对齐,群组/聊天室成员被禁言后,该成员可通过收到的禁言事件查看被禁言的成员。
- uniapp SDK 支持鸿蒙系统。 | 2024-12-3 |
- [Android 4.11.0 更新日志](/document/android/releasenote.html#版本-v4-11-0-dev-2024-12-3-开发版)
- [iOS 4.11.0 更新日志](/document/ios/releasenote.html#版本-v4-11-0-dev-2024-12-3-开发版)
- [Web 4.11.0 更新日志](/document/web/releasenote.html#版本-v4-11-0-dev-2024-12-3-开发版)
- [小程序 4.11.0 更新日志](/document/applet/releasenote.html#版本-v4-11-0-dev-2024-12-3-开发版) | - -## 2024-09 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.10.0 开发版发布 | **新增特性**:
- 移动端支持获取数据库中的消息总数;
- 移动端新增[两个错误码](/document/android/error.html),用于提示用户在群组黑名单或聊天室黑名单中。群组或聊天室黑名单中的用户进行某些操作时,例如,加入群组,会提示该错误。
- 移动端[单向删除服务端会话时也会删除本地会话](/document/android/conversation_delete.html#单向删除服务端会话及本地会话)。
- Web/小程序端的聊天室公告修改事件返回更新的公告,即聊天室公告修改后,聊天室中的其他成员会通过事件收到更新的公告。
- Web/小程序端新增错误码 208 `WEBIM_USER_ALREADY_LOGIN`,提示用户已登录。单设备登录时,若调用登录方法 `open` 时用户已经登录,会触发该错误;新增错误码 512 `MESSAGE_SEND_TIMEOUT`,提示发送消息超时,例如,连接断开时发送消息会提示该错误。| 2024-09-30 |
- [Android 4.10.0 更新日志](/document/android/releasenote.html#版本-v4-10-0-dev-2024-09-30-开发版)
- [iOS 4.10.0 更新日志](/document/ios/releasenote.html#版本-v4-10-0-dev-2024-09-30-开发版)
- [Web 4.10.0 更新日志](/document/web/releasenote.html#版本-v4-10-0-dev-2024-10-11-开发版)
- [小程序 4.10.0 更新日志](/document/applet/releasenote.html#版本-v4-10-0-dev-2024-10-11-开发版) | -| SDK 4.9.1 开发版发布 | uni-app SDK 支持[离线推送](/document/applet/push/uniapp_push.html)。 | 2024-09-06 | [小程序 4.9.1 更新日志](/document/applet/releasenote.html#版本-v4-9-1-dev-2024-09-06-开发版) | - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| HarmonyOS SDK 1.4.0 开发版发布 | **新增特性**:
- 新增[置顶消息功能](/document/harmonyos/message_pin.html#消息置顶)。
- 新增[根据单个或多个消息类型,搜索本地数据库中所有会话或单个会话中的消息](/document/harmonyos/message_search.html#根据消息类型搜索会话消息)。
- 支持[获取 SDK 本地数据库中会话某个时间段内的全部消息数](/document/harmonyos/message_retrieve.html#获取会话在一定时间内的消息数)。
- 支持[会话推送通知方式的本地存储](/document/harmonyos/push/push_notification_mode_dnd.html#从服务器获取所有会话的推送通知方式设置),并支持从服务器获取所有会话的推送通知方式的设置。
- 支持[设备登录时携带自定义扩展信息并传递给被踢的设备](/document/harmonyos/multi_device.html#设置登录设备的扩展信息),应用于被踢设备展示提示信息或进行业务判断。
- 支持用户上线后从服务端拉取离线消息时[收到拉取开始和结束的通知](/document/harmonyos/connection.html)。
- 支持[查看当前用户是否在群组禁言列表中](/document/harmonyos/group_members.html#检查自己是否在禁言列表中)。
- 支持[错误码 213 ChatError#USER_BIND_ANOTHER_DEVICE](/document/harmonyos/error.html),用于当用户达到登录设备上线时,当前设备无法登录的场景。
- 支持在撤回消息的事件中[返回被撤回的消息所属的会话 ID](/document/harmonyos/message_recall.html#设置消息撤回监听)。
- 支持[加入聊天室时携带扩展信息,并指定是否退出之前加入的全部聊天室](/document/harmonyos/room_manage.html#加入聊天室)。当用户加入聊天室携带了扩展信息时,聊天室内其他人可以在用户加入聊天室的回调中,获取到扩展信息。
- 支持[从服务端单向删除聊天室漫游消息](/document/harmonyos/message_delete.html#单向删除服务端的历史消息)。| 2024-09-30 | [HarmonyOS 1.4.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-4-0-dev-2024-09-30-开发版) | -| HarmonyOS SDK 1.3.0 开发版发布 | **新增特性**:
- HarmonyOS 端新增[群成员自定义属性](/document/harmonyos/group_members.html#管理群成员的自定义属性)功能。
- HarmonyOS 端新增[设置推送通知的显示内容](/document/harmonyos/push/push_display.html) 、[推送通知方式和免打扰模式功能](/document/harmonyos/push/push_notification_mode_dnd.html)。
- HarmonyOS 端新增[用户在线状态订阅](/document/harmonyos/presence.html)功能。
- 新增[聊天室自定义属性](/document/harmonyos/room_attributes.html#管理聊天室自定义属性-key-value)功能。 | 2024-09-09 | [HarmonyOS 1.3.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-3-0-dev-2024-09-10-开发版) | - -## 2024-08 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.9.0 开发版发布 | **新增特性**:
- 用户上线后从服务端拉取离线消息时,会[收到拉取开始和结束的通知](/document/android/connection.html)。
- 单聊会话支持[消息置顶](/document/android/message_pin.html)。
- 移动端支持查看当前用户是否在指定的群组的禁言列表中。
- 移动端撤回消息后,你[收到的通知中会体现消息所属的会话 ID](/document/android/message_recall.html#设置消息撤回监听)。
- Web 端可[查看 app 下设置了推送通知方式(接收所有人通知、只接收 @ 我的通知和不接收任何通知)的所有会话](/document/web/push/push_notification_mode_dnd.html#获取设置了推送通知方式的所有会话)。
- 对于 Web 端,你若设置了指定会话的推送通知方式或免打扰时长或时间段,[其他设备会收到事件通知](/document/web/push/push_notification_mode_dnd.html#设置单个会话的推送通知)。
- 对于 Web 端,你若清除了会话的推送通知方式,[其他设备会收到事件通知](/document/web/push/push_notification_mode_dnd.html#清除单个会话的推送通知方式的设置)。| 2024-08-30 |
- [Android 4.9.0 更新日志](/document/android/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版)
- [iOS 4.9.0 更新日志](/document/ios/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版)
- [Web 4.9.0 更新日志](/document/web/releasenote.html#版本-v4-9-0-dev-2024-08-30-开发版) | - -## 2024-07 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.8.0 开发版发布 | **新增特性**:
- 移动端支持 AUT 协议,优化弱网环境下的服务连接成功率。
- 移动端支持[本地存储会话的推送通知方式](/document/ios/push/push_notification_mode_dnd.html#从服务器获取所有会话的推送通知方式设置),并支持从服务器获取所有会话的推送通知方式的设置。
- 移动端支持[本地获取指定会话某个时间段内的消息数](/document/android/message_retrieve.html#获取会话在一定时间内的消息数)。
- 客户端支持[加入聊天室时携带的扩展信息,并可指定是否退出所有其他聊天室](/document/android/room_manage.html#加入聊天室)。
- Web 端[设备登录时允许携带自定义扩展消息并传递给被踢的设备](/document/web/multi_device.html#设置登录设备的扩展信息),应用于被踢设备展示提示信息或进行业务判断。
- Web 端支持[使用固定的设备 ID](/document/web/multi_device.html),这会影响多端登录互踢的策略。
- Web 端支持[聊天室所有者解散聊天室](/document/web/room_manage.html#解散聊天室)。
**优化**:
移动端设置和获取用户属性时,包括[设置当前用户的属性](/document/web/userprofile.html#设置当前用户的属性)、[获取单个或多个用户的用户属性](/document/web/userprofile.html#获取用户属性)和[获取指定用户的指定用户属性](/document/web/userprofile.html#获取指定用户的指定用户属性)时,若超过调用频率限制,会上报错误码 4 `EMErrorExceedServiceLimit`(iOS)或 `EXCEED_SERVICE_LIMIT`(Android)。| 2024-07-01 |
- [Android 4.8.0 更新日志](/document/android/releasenote.html#版本-v4-8-0-dev-2024-07-01-开发版)
- [iOS 4.8.0 更新日志](/document/ios/releasenote.html#版本-v4-8-0-dev-2024-07-01-开发版)。
- [Web 4.8.0 更新日志](/document/web/releasenote.html#版本-v4-8-0-dev-2024-07-01-开发版)。
- [Flutter 4.8.1 更新日志](/document/flutter/releasenote.html#版本-v4-8-1-2024-10-15)。| - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| HarmonyOS SDK 1.2.0 开发版发布 |**新增特性**:
- HarmonyOS 端新增[表情回复 Reaction](/document/harmonyos/reaction.html)功能。
- HarmonyOS 端新增[会话标记](/document/harmonyos/conversation_mark.html)功能。
- HarmonyOS 端新增[会话置顶](/document/harmonyos/conversation_pin.html)功能。
- HarmonyOS 端新增[用户属性](/document/harmonyos/userprofile.html)功能。 | 2024-07-11 | [HarmonyOS 1.2.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-2-0-dev-2024-07-11-开发版) | -| HarmonyOS SDK 1.1.0 开发版发布 |**新增特性**:
- HarmonyOS 端新增[修改消息](/document/harmonyos/message_modify.html)功能。
- HarmonyOS 端新增[自定义消息](/document/harmonyos/message_send_receive.html#发送自定义类型消息)功能。
- HarmonyOS 端新增[合并转发消息](/document/harmonyos/message_send_receive.html#发送和接收合并消息)功能。
- HarmonyOS 端新增[离线推送](/document/harmonyos/push/push_overview.html)功能。 | 2024-07-01 | [HarmonyOS 1.1.0 更新日志](/document/harmonyos/releasenote.html#版本-v1-1-0-dev-2024-07-01-开发版) | - -## 2024-06 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.7.0 开发版发布 | **新增特性**:
- 移动端[设备登录时允许携带自定义扩展消息并传递给被踢的设备](/document/android/multi_device.html#设置登录设备的扩展信息),应用于被踢设备展示提示信息或进行业务判断。
- 移动端支持[根据多个消息类型搜索本地所有会话或单个会话中的消息](/document/android/message_search.html#根据消息类型搜索所有会话中的消息)。
- 移动端支持本地获取群组记录,有助于降低接口调用频率,提升群组信息获取效率。
- 移动端支持[从服务端单向删除聊天室漫游消息](/document/android/message_delete.html#单向删除服务端的历史消息)。 | 2024-06-05 |
- [Android 4.7.0 更新日志](/document/android/releasenote.html#版本-v4-7-0-dev-2024-06-05-开发版)
- [iOS 4.7.0 更新日志](/document/ios/releasenote.html#版本-v4-7-0-dev-2024-06-05-开发版)。 | - -## 2024-04 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.6.0 开发版发布 | **新增特性**:
- 客户端[消息撤回时支持携带自定义信息](/document/android/message_recall.html#实现方法)。
- 客户端支持离线期间撤回的消息通知给接收方。
- 移动端支持[自定义筛选获取本地会话列表](/document/android/conversation_list.html#获取本地所有或筛选的会话)。
- 移动端支持[清除内存中的会话](/document/android/conversation_list.html#清除内存中的会话),并举例说明如何[降低会话占用内存](/document/android/conversation_list.html#降低会话占用内存的实例)。
- Android 端添加绑定推送 token 成功与否的回调。
- Web/小程序端增加接口支持[获取当前用户加入和创建的聊天室](/document/web/room_manage.html#获取当前用户加入的聊天室列表)。
- Web/小程序 端支持 [logger 日志不显示在控制台](/document/web/log.html#输出信息到日志文件)。
**重大变更**
1. **Android**:
从 V4.6.0 版本开始会启用 Kotlin 语言编写的新的 EaseIM App 项目与 EaseIMKIt 项目,老版本的项目将逐渐不再维护,请参考:
- [EaseIMKIt 文档](https://doc.easemob.com/uikit/chatuikit/android/chatuikit_overview.html)
- [EaseIM App 项目](https://github.com/easemob/chat-android-kotlin)
2. **iOS**:
从 V4.6.0 版本开始会启用 Swift 语言编写的新的 `EaseChatUIKit` 与 `EaseChatDemo`,老版本 Demo 和 UIKit 逐渐不再维护,请参考:
- [UIKit 文档](https://doc.easemob.com/uikit/chatuikit/ios/chatuikit_overview.html)
- [Demo 源码](https://github.com/easemob/chat-ios/tree/SwiftDemo) | 2024-04-30 |
- [Android 4.6.0 更新日志](/document/android/releasenote.html#版本-v4-6-0-dev-2024-04-30-开发版)
- [iOS 4.6.0 更新日志](/document/ios/releasenote.html#版本-v4-6-0-dev-2024-04-30-开发版)
- [Web 4.7.0 更新日志](/document/web/releasenote.html#版本-v4-7-0-dev-2024-04-30-开发版)
- [小程序 4.7.0 更新日志](/document/applet/releasenote.html#版本-v4-7-0-dev-2024-04-30-开发版)。 | - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.5.0 开发版发布 | **新增特性**:
- 客户端可[置顶消息](/document/android/message_pin.html),方便会话中的所有用户快速查看重要消息。
- 客户端的消息修改回调中可返回[通过 RESTful API 修改的自定义消息](/document/server-side/message_modify_text_custom.html)。
- 客户端支持[获取聊天室漫游消息](/document/android/message_retrieve.html#从服务器获取指定会话的消息)。若使用该功能,你需要联系商务开通。
- Android 端 SDK 集成支持[动态加载 .so 库文件](/document/android/quickstart.html#方法三-动态加载-so-库文件),减少应用安装包的大小。
- iOS 端可[将所有会话的未读消息设为已读](/document/ios/conversation_unread.html#将所有会话的未读消息数清零),将所有会话的未读消息数清零。
**优化**:
- 优化 token 登录时的错误提示信息,使错误提示更准确。
- 移动端优化[单条转发](/document/android/message_forward.html)功能,附件消息无需重新上传附件即可转发。 | 2024-04-03 |
- [Android 4.5.0 更新日志](/document/android/releasenote.html#版本-v4-5-0-dev-2024-04-03-开发版)
- [iOS 4.5.0 更新日志](/document/ios/releasenote.html#版本-v4-5-0-dev-2024-04-03-开发版)
- [Web 4.6.0 更新日志](/document/web/releasenote.html#版本-v4-6-0-dev-2024-04-02-开发版)
- [小程序 4.6.0 更新日志](/document/applet/releasenote.html#版本-v4-6-0-dev-2024-04-02-开发版)
- [Flutter 4.5.0 更新日志](/document/flutter/releasenote.html#版本-v4-5-0-2024-5-7)。
- [React Native 1.4.0 更新日志](/document/react-native/releasenote.html#版本-v1-4-0-2024-5-7)
- [Unity 1.3.0 更新日志](/document/unity/releasenote.html#版本-v1-3-0-dev-2024-5-7-开发版)
- [Windows 1.3.0 更新日志](/document/windows/releasenote.html#版本-v1-3-0-dev-2024-5-7-开发版)| -| REST API |**新增 API**:
1. [分页获取好友列表](/document/server-side/user_relationship.html#分页获取好友列表);
2. [单向清空漫游消息](/document/server-side/message_delete.html):[根据时间单向清空单聊会话的漫游消息](/document/server-side/message_delete.html#单向清空单聊会话某个时间点及之前的漫游消息);[根据时间单向清空群组或聊天室会话的漫游消息](/document/server-side/message_delete.html#单向清空群组或聊天室会话某个时间点及之前的漫游消息);[清空用户的所有漫游消息](/document/server-side/message_delete.html#单向清空指定用户的漫游消息);
3. [修改文本或自定义消息](/document/server-side/message_modify_text_custom.html);
4. [转让聊天室](/document/server-side/chatroom.html#转让聊天室);
5. [强制指定账号从单设备下线](/document/server-side/account_system.html#强制用户从单设备下线)。| 2024-04 | 关于接口的调用频率限制,详见 [API 调用频率限制](/document/server-side/limitationapi.html)。 | - - -## 2024-01 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.4.0 开发版发布 | **新增特性**:
- 客户端可[清空聊天记录](/document/android/message_delete.html#清空聊天记录):单个用户包含本地或服务端记录。
- 客户端发送消息时如果被内容审核进行了内容替换,你可以通过[设置开关](/document/android/message_send_receive.html#发送消息前的内容审核)决定发送方是否可以获取替换后的内容。
- 移动端的[本地消息搜索可选择搜索范围](/document/android/message_search.html#根据搜索范围搜索当前会话中的消息),如只搜索消息内容、只搜索消息扩展信息以及同时搜索消息内容以及扩展信息。
- 移动端接收消息的回调支持通过[设置开关](/document/android/message_send_receive.html#发送消息前的内容审核)设置是否返回发送成功的消息。
- [Web 端支持向指定设备发消息](/document/web/multi_device.html#获取当前用户的其他登录设备的登录-id-列表),例如,电脑端给手机端发消息,登录同一账号的多个设备均会收到消息。
- Web 端聊天室和群组成员进出事件增加成员人数 `memberCount` 字段。
**优化**:
- 移动端群组全员禁言状态存储到本地数据库,下次登录时可以直接从本地获取到。
- 移动端转发合并消息时导致的附件重复上传问题。| 2024-01-30 |
- [Android 4.4.0 更新日志](/document/android/releasenote.html#版本-v4-4-0-dev-2024-01-30-开发版)
- [iOS 4.4.0 更新日志](/document/ios/releasenote.html#版本-v4-4-0-dev-2024-01-30-开发版)
- [Web 4.5.0 更新日志](/document/web/releasenote.html#版本-v4-5-0-dev-2024-01-30-开发版)
- [小程序 4.5.0 更新日志](/document/applet/releasenote.html#版本-v4-5-0-dev-2024-01-30-开发版)。 | - -## 2023-12 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.3.0 开发版发布 | **新增特性**:
- [会话标记功能](/document/android/conversation_mark.html):支持标记会话,并按照标记获取会话。
**优化**
- 对于原生平台,优化附件类型消息发送时的附件上传,支持分片上传。
- 移动端移除 FPA 功能,减小 SDK 体积。
- 移动端单个日志文件大小由 2 MB 提升到 5 MB。
- Web 端增加 `onMessage` 回调。在收到文本、图片、视频、语音、地理位置和文件等消息时,批量将消息回调给应用。
- Web 端视频类型消息增加视频首帧缩略图, 通过 videoMessage.thumb 访问。 | 2023-12-22 |
- [Android 4.3.0 更新日志](/document/android/releasenote.html#版本-v4-3-0-dev-2023-12-22-开发版)
- [iOS 4.3.0 更新日志](/document/ios/releasenote.html#版本-v4-3-0-dev-2023-12-22-开发版)
- [Web 4.4.0 更新日志](/document/web/releasenote.html#版本-v4-4-0-dev-2023-12-22-开发版)
- [小程序 4.4.0 更新日志](/document/applet/releasenote.html#版本-v4-4-0-dev-2023-12-22-开发版) | - -## 2023-11 - -| 动态名称 | 动态描述 | 发布时间 | 相关文档 | -| :----- | :------- | :---------------- | :---------------- | -| SDK 4.2.0 开发版发布 | **新增特性**:
- 客户端支持[好友备注功能](/document/android/releasenote.html)。
- 客户端支持聊天室全局广播消息,可根据消息属性判断。
- 移动端可以[从服务器获取当前用户已加入的群组数量](/document/android/group_manage.html#查询当前用户已加入的群组数量)。
- 移动端在申请入群被拒绝时,返回的回调中增加了申请者和拒绝者。
- 移动端在初始化时可配置获取会话列表时是否返回空会话。
**优化**
- 客户端统一 Agora Token 和 EaseMob Token 登录方式,新增 EaseMob Token 即将过期及已过期的回调。
- 移动端优化发消息时重试的逻辑。
- 移动端优化数据库升级逻辑。| 2023-11-17 |
- [Android 4.2.1 更新日志](/document/android/releasenote.html#版本-v4-2-1-dev-2023-11-17)
- [iOS 4.2.0 更新日志](/document/ios/releasenote.html#版本-v4-2-0-dev-2023-11-13)
- [Web 4.3.0 更新日志](/document/web/releasenote.html#版本-v4-3-0-dev-2023-11-17)
- [小程序 4.3.0 更新日志](/document/applet/releasenote.html#版本-v4-3-0-dev-2023-11-17)。
- [Flutter 4.2.0 更新日志](/document/flutter/releasenote.html#版本-v4-2-0-2024-1-4)
- [React Native 1.3.0 更新日志](/document/react-native/releasenote.html#版本-v1-3-0-2024-1-4) | -| REST API | 支持[通过 REST API 向 app 下的所有活跃聊天室发送全局广播消息](/document/server-side/message_chatroom.html#发送聊天室全局广播消息) 。活跃聊天室指聊天室至少存在一个成员,而且至少发送过一条消息。| 2023-11-17 | 详见[发送聊天室广播消息](/document/server-side/message_chatroom.html#发送聊天室全局广播消息)。 | -| IM Demo | 好友详情页面可添加和修改好友备注。 | 2023-11-17 |
- [Android 4.2.1 Demo](https://www.easemob.com/download/demo)
- [iOS 4.2.0 Demo](https://www.easemob.com/download/demo) | - diff --git a/docs/product/product_group_overview.md b/docs/product/product_group_overview.md deleted file mode 100644 index 0672202f..00000000 --- a/docs/product/product_group_overview.md +++ /dev/null @@ -1,123 +0,0 @@ -# 群组概述 - - - -## 群组基本介绍 - -群组是支持多人沟通的即时通讯系统,成员关系相对稳定。所有群成员可以收到群中的消息,可以在群中发送消息。群成员离线时可以收到推送消息。群组成员支持多种角色:群主、群管理员和普通成员。群组提供丰富的管理能力,如群组禁言、群公告和群文件等。 - -### 群组分类 - -群组按照是否对用户公开,可以分为公开群和私有群。 - -| 群组分类 | 加群方式 | 获取群组信息 | -| :------- | :---------- | :---------- | -| 公开群 | 任何用户可以搜索到该群,可申请加入群或者被管理员和群主邀请入群。任何用户均可申请入群,是否需要群主和群管理员审批,取决于群组的设置,例如 Android 为 `EMGroupStyle` 参数。 | - 对于群组详情和公开群列表,用户即使不加入群也能获取。
- 对于群公告和群共享文件列表,用户只有加入群时才能获取。 | -| 私有群 | 群外用户不能搜索到此类群组,需要被邀请才能入群。除了群主和群管理员,群成员是否也能邀请其他用户进群取决于群组的设置,例如 Android 为 `EMGroupStyle` 参数。 | 用户只有加入群后才能获取群详情、群公告、群共享文件列表、和群成员列表等群组信息。 | - -### 群组成员角色 - -| 群成员角色
| 描述
| 管理权限 | -| :------ | :-------------- | :------------ | -| 普通成员 | 不具备管理权限的普通成员。 | 普通成员可以:
- 在群组内发送和接收消息;
- 获取群公告;
- 上传、下载、删除、以及从服务器获取共享文件;
- 获取群组列表;
- 获取群成员列表;
- 获取群组详情;
- 查询自己已加入的群组数量;
- 退出群组;
- 屏蔽和解除屏蔽群消息;
- 设置自己的自定义属性(key-value);
- 获取群管理员列表;
- 创建和加入子区;
- 获取子区详情,不论是否加入了群组中的子区;
- 获取已加入和创建的子区;
- 获取子区成员列表,不论是否加入了群组中的子区;
- 退出子区;
- 在所属子区中发送消息。
- 批量获取子区中的最新一条消息。| -| 群管理员 | 由群主指定,协助群主进行管理,拥有一定的管理权限。 | 除了普通成员的权限,管理员还具备以下权限:
- 修改群组名称和群组描述;
- 更新群公告;
- 审批是否允许用户加入群组;
- 修改群组名称和群组描述信息;
- 更新群公告;
- 更新群扩展字段;
- 邀请用户加入群组;
- 将群成员被移出群组;
- 管理群组白名单;
- 管理群组黑名单;
- 管理群组禁言列表;
- 开启和关闭群组全员禁言;
- 修改子区名称;
- 将子区中的成员移出子区;
- 解散群组中的子区。 | -| 群主 | 群组的创建者默认成为群主,在群中拥有最高权限。 | 除了管理员权限,群主还具备以下权限:
- 添加和移除管理员;
- 解散群组;
- 将群主权限转移给群组中的其他成员。 | - -### 群组与聊天室的区别 - -群组和聊天室均为支持多人沟通的即时通讯系统。两者的区别在于,群组中的成员会有固定的强的关系,成员加入后会长时间在群组中。聊天室中的成员没有固定关系,类似于一个开放的空间,大家可以自由加入,离开即退出聊天室。以下为功能对比: - -| 功能
| 群组
| 聊天室 | -| :----------- | :------------------- | :--------------------- | -| 使用场景 | 类似于 Signal,Skype 里的群聊,所有加入的用户拥有固定的关系。 | 类似 Twitch 的直播间,成员间没有固定关系,离开即退出。 | -| 创建方式 | 所有 app 用户都可以创建群组。 | 仅 [超级管理员](/document/server-side/chatroom_superadmin.html) 有权限创建聊天室。 | -| 类型 | 分为公开群和私有群,创建群组时可设置入群是否需获得群主和群管理员的同意,支持不同使用场景。 | 没有公开和私有之分,所有用户均可自由加入或退出。 | -| 最大成员数 | 成员数支持取决于所选择的版本,最高版本默认支持 8,000 人。如需提升该上限,请联系商务。| 成员数支持取决于所选择的版本,最高版本默认支持 10,000 人。如需提升该上限,请联系商务。 | -| 离线消息存储 | 支持离线消息存储。用户离线时,服务器会先保存发送给这些用户的消息,等待这些用户上线时发送。对于单个终端用户,服务器对每个群最多可保存 200 条离线消息。对于超过 3000 人的群组,若希望提供离线推送功能,你必须在创建群组之前联系商务开通,否则群组创建后无法再开通该功能。 | 不支持离线消息存储。离线时,不会收到推送通知和消息;成员(除聊天室白名单中的成员)离线超过 2 分钟会自动退出聊天室。 | -| 漫游消息/历史消息记录存储 | 支持漫游消息和历史记录的存储。服务器存储漫游消息和历史消息记录的时间取决于你订阅的 IM 套餐包,详见[产品价格](/product/pricing.html#套餐包功能详情)。
- 你可以[调用 REST API 接口从服务端获取历史消息记录 JSON 文件](/document/server-side/message_historical.html)。
- 你还可以[调用客户端接口从服务端获取指定会话的漫游消息](/document/android/message_retrieve.html#从服务器获取指定会话的消息),在多设备间同步。 | 支持漫游消息和历史记录的存储。服务器存储漫游消息和历史消息记录的时间取决于你订阅的 IM 套餐包,详见[产品价格](/product/pricing.html#套餐包功能详情)。
- 你可以[调用 REST API 接口从服务端获取历史消息记录 JSON 文件](/document/server-side/message_historical.html)。
- 你还可以[调用客户端接口从服务端获取指定会话的漫游消息](/document/android/message_retrieve.html#从服务器获取指定会话的消息),在多设备间同步。
- 如果需要用户新加入聊天室时服务器发送最近的漫游消息,可以联系商务开通,每个会话默认支持 10 条消息,最多可调整至 200 条。| -| 消息可靠性 | 群组中发送的所有消息,用户都会收到。 | 当消息量大时,聊天室中超过阈值的消息会被丢弃。消息开始丢弃的阈值为每秒 100 条消息,可以根据需求进行调整。 | - -## 群组功能 - -群组功能主要分为群组的创建和管理,群成员管理,以及群属性管理。 - -### 创建和管理群组 - -| 功能 | 描述 | -| :----------------- | :---------------------- | -| 创建群组 | 任何用户都可以创建群组。群组创建者为群主。群组创建时可以指定群组名称、头像、描述,是否是公开群、要加入群组的用户列表、是否需要审批、普通成员是否能邀请新用户加入群组,以及群扩展信息等。群组数量和群成员数量根据套餐版本有所不同,详见 [环信即时通讯 IM 价格](https://www.easemob.com/pricing/im)。 | -| 解散群组 | 只有群主才能解散群组。群组一旦解散,所有本地群组数据都会被删除,所有群成员都被强制退出群。 | -| 封禁/解禁群组 | - 可调用 REST API 封禁指定的群组。例如,群成员经常在群中发送违规消息,可以调用该 API 对该群进行封禁。群组被封禁后,群中任何成员均无法在群组以及该群组下的子区中发送和接收消息,也无法进行群组和子区管理操作。
- 可调用 REST API 解除对指定群组的封禁。群组解禁后,群成员可以在该群组以及该群组下的子区中发送和接收消息并进行群组和子区管理相关操作。| -| 屏蔽和解除屏蔽群消息 | 所有群组成员都可以屏蔽和取消屏蔽群组消息。用户屏蔽群组消息后,他们将不再收到来自指定群组的消息。 | - -### 查询群组信息 - -| 功能 | 描述 | -| :----------------- | :---------------------- | -| 获取群组详情 | - 群成员可以从内存获取群组详情。返回的结果包括群组 ID、群组名称、群组描述、群组基本属性、群主、群组管理员列表,默认不包含群成员。
- 群成员可从服务器获取群组详情。返回的结果包括群组 ID、群组名称、群组描述、群组基本属性、群主、群组管理员列表、是否已屏蔽群组消息以及群组是否禁用等信息。另外,可通过参数设置是否获取群成员列表,默认最多包括 200 个成员。
- 对于公有群,用户即使不加入群也能获取群组详情,而对于私有群,用户只有加入了群组才能获取群详情。 | -| 修改群组详情 | 修改群组详情,例如群组名称、群组描述和扩展信息。 | -| 获取群成员列表 | 所有群组用户都可以从服务器获取群组成员的分页列表。群成员按加入群组时的时间戳降序显示。 | -| 获取 app 中的群组列表 | 可调用 REST API 分页获取应用下的群组的信息。 | -| 获取群组列表 | 用户可以获取公开群列表和自己创建或加入的群组列表。 | -| 查询当前用户已加入的群组数量 | 用户可以从服务器获取当前用户已加入的群组数量。 | -| 获取单个用户加入的所有群组 | 可调用 REST API 根据用户 ID 分页获取指定用户加入的所有群组。 | -| 查看指定用户是否已加入群组 | 可调用 REST API 查看单个用户是否已加入了指定的群组。 | - -:::tip -环信即时通讯 IM 支持用户登录多个设备,用户在一台设备上进行的群组操作,会在其他设备上收到这些操作对应的通知。 -::: - -### 群属性管理 - -| 功能 | 描述 | -| :--------------- | :----------------------------------------------------------- | -| 修改群组信息 | 群主和群管理员可以修改群名称、群组描述和扩展字段。 | -| 修改/获取群公告 | 群主和群管理员可以设置和更新群公告,群成员可以获取群公告。 | -| 管理共享文件 | 群主和群管理员可以上传文件并删除所有群共享文件,群成员只能删除自己上传的文件。所有群成员均可以下载群组的共享文件以及从服务器获取共享文件列表。| - -### 群组扩展字段 - -用户创建群组时可以设置群组扩展字段,群组扩展字段支持 JSON 格式的数据,用于自定义更多群组信息。群扩展字段的长度限制为 8 KB。 - -不过,仅群主和群管理员可以更新群扩展字段: - -- 对于 Web 端,可以[调用修改群组信息的接口](/document/web/group_attributes.html#修改群组信息)更新群组扩展字段。 -- 除 Web 端外,Android、iOS、Web 等其它各端可[调用单独的更新群组扩展字段的接口](/document/android/group_attributes.html#更新群扩展字段)修改群扩展字段。 - -### 群成员管理 - -| 功能 | 描述 | -| :--------------------- | :----------------------------------------------------------- | -| 加入群组 | 公开群和私有群中,群主和管理员均可以邀请用户加入群。
支持需要用户确认后,再加入群。此外用户也可以申请加入公开群。| -| 退出群组 | 群主不支持退群操作,只能解散群。退出群组分为主动退群和被动退群。被动退群即为被群主或群管理员踢出群。 | -| 变更群主 | 群主可以将群组的所有权转让给指定的组成员。所有权转移后,群主成为普通群成员。 | -| 添加/移除/获取群管理员 | 群主可以添加成员到群组管理员列表,将管理员移出该列表。所有群成员均可获取群组下的管理员列表。 | -| 群组白名单 | 群主和管理员可以将群成员加入或移出白名单。白名单中的群成员可以在全员禁言状态下发送群消息。仅群主和群管理员可以获取群组白名单列表。 | -| 群组黑名单 | 群主和群管理员可以将群成员加入或移出黑名单,黑名单中的成员将被移出群且无法再次加入群。仅群主和群管理员可以获取群组白名单列表。 | -| 群组禁言 | - 群主和管理员可以将群成员加入或移出禁言列表,禁言列表中的成员无法发送群消息,但可以接收群消息。
- 仅群主和群管理员可以获取群组禁言列表。
- 群主和管理员可以开启或关闭全员禁言。开启全员禁言后,仅群组、管理员和白名单中的成员可以发送群消息。| -| 管理群成员的自定义属性 | 支持设置群成员自定义属性和获取单个群成员的自定义属性。群主可修改所有群成员的自定义属性,其他群成员只能修改自己的自定义属性。 | - -### 群成员的扩展字段 - -设置群成员的扩展字段即设置群成员的自定义属性,例如在群组中的昵称和头像等。自定义属性为 key-value 格式,key 表示属性名称,value 表示属性值,若 value 设置为空字符串即删除该自定义属性。 - -- 单个群成员的自定义属性总长度不能超过 4 KB。对于单个自定义属性,属性 key 不能超过 16 字节,value 不能超过 512 个字节,否则会报错。 -- 群主可修改所有群成员的自定义属性,其他群成员只能修改自己的自定义属性。 - -## 监听群组事件 - -你可以实现群组事件监听,群组内进行了相关操作,例如,有新成员入群、退群、被添加到禁言列表、黑名单列表等,群组中的其他人员会收到相关事件,详见[监听群组事件](/document/android/group_manage.html#监听群组事件)。 - -## 群组事件回调 - -你可以实现发送后回调,使环信 IM 服务器将群组事件同步给你的应用服务器。若群组内发生新成员入群、退群、被添加到禁言列表、黑名单列表等相关操作时,环信 IM 服务器向应用服务器发起 HTTP/HTTPS POST 请求,同步所发生的事件,详见[群组事件回调文档](/document/server-side/callback_group_room_create.html)。 - -## 群组限制 - -- 群组相关限制,包括群成员数量、群组/群成员属性以及群组共享文件的相关限制,详见[群组限制](/product/limitation.html#群组)文档。 -- 群成员的数量根据不同的套餐版本而不同,详见[产品价格](/product/pricing.html#套餐包功能详情)。 - - - - - diff --git a/docs/product/product_message_format.md b/docs/product/product_message_format.md deleted file mode 100644 index efba5eb9..00000000 --- a/docs/product/product_message_format.md +++ /dev/null @@ -1,401 +0,0 @@ -# 消息格式描述 - -目前,环信即时通讯 IM 支持的消息类型 `type` 如下表所示: - -| 参数 | 类型 | -| :----- | :----- | -| `txt` | 文本消息 | -| `loc` | 位置消息 | -| `cmd` | 透传消息 | -| `img` | 图片消息 | -| `audio` | 语音消息 | -| `video` | 视频消息 | -| `file` | 文件消息 | -| `custom` | 自定义消息 | - -## 消息 body 内容介绍 - -消息 body 为 JSONArray 结构,其中包含消息类型和消息内容。不同类型的消息只是 `body` 字段内容存在差异。 - -### 文本消息 - -文本消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :----- | :----- | :------------------------------- | -| `msg` | String | 消息内容。 | - -示例如下: - -```json -"body": { - "msg": "testmessages" - } -``` - -### 位置消息 - -位置消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :----- | :----- | :--------------------------- | -| `lat` | Long | 位置的纬度。 | -| `lng` | Long | 位置的经度。 | -| `addr` | String | 位置的地址描述。 | - -示例如下: - -```json -"body": { - "lat": "39.966", - "lng":"116.322", - "addr":"中国北京市海淀区中关村" - } -``` - -### 透传消息 - -透传消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :------- | :----- | :--------------------------- | -| `action` | String | 命令内容。 | - -示例如下: - -```json -"body":{ - "action":"action1" - } -``` - -### 图片消息 - -对于图片消息,通过 REST API 发消息时建议传入 `filename` 参数,否则客户端收到图片消息时无法显示文件名称,而且需保证通过 `url` 参数能下载到对应图片。 - -若上传图片时,设置了文件访问限制(`restrict-access`),则图片上传后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`,发送图片消息时传入该参数。上传原图,环信服务器会自动为图片生成缩略图。 - -图片消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :------------------------ | -| `filename` | String | 图片文件名称,包含文件后缀名。 | -| `secret` | String | 图片的访问密钥,即成功上传图片后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`。如果图片文件上传时设置了文件访问限制(`restrict-access`),则发送消息时该字段为必填。 | -| `url` | String | 图片 URL 地址:https://{host}/{org_name}/{app_name}/chatfiles/{file_uuid}。其中 `file_uuid` 为文件 ID,成功上传图片文件后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取。 | -| `size` | JSON | 图片的尺寸。单位为像素。
- `height`:图片高度。
- `width`:图片宽度。 | - -示例如下: - -```json -"body": { - "filename":"testimg.jpg", - "secret":"VfXXXXNb_", - "url":"https://XXXX/XXXX/XXXX/chatfiles/55f12940-XXXX-XXXX-8a5b-ff2336f03252", - "size": { - "width":480, - "height":720 - } - } -``` - -### 语音消息 - -对于语音消息,通过 REST API 发消息时建议传入 `filename` 参数,否则客户端收到语音消息时无法显示文件名称,而且需保证通过 `url` 参数能下载到对应语音。 - -若上传语音文件时,设置了文件访问限制(`restrict-access`),则文件上传后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`,发送语音消息时传入该参数。 - -语音消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :------------------------------------------ | -| `url` | String | 语音文件的 URL 地址:https://{host}/{org_name}/{app_name}/chatfiles/{file_uuid}。其中 `file_uuid` 为文件 ID,成功上传语音文件后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取。 | -| `filename` | String | 语音文件名称,包含文件后缀名。 | -| `length` | Int | 语音时长。单位为秒。 | -| `secret` | String | 语音文件的访问密钥,即成功上传语音文件后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`。如果语音文件上传时设置了文件访问限制(`restrict-access`),则发送消息时该字段为必填。 | - -示例如下: - -```json -"body": { - "url": "https://XXXX/XXXX/XXXX/chatfiles/1dfc7f50-XXXX-XXXX-8a07-7d75b8fb3d42", - "filename": "testaudio.amr", - "length": 10, - "secret": "HfXXXXCjM" - } -``` - -### 视频消息 - -对于视频消息,通过 REST API 发消息时建议传入 `filename` 参数,否则客户端收到视频消息时无法显示文件名称,而且需保证通过 `url` 参数能下载到对应视频。 - -若上传视频文件时,设置了文件访问限制(`restrict-access`),则文件上传后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`,发送视频消息时传入该参数。环信服务器不会自动为视频文件生成缩略图。若需要视频缩略图,需先调用[文件上传](/document/server-side/message_download.html#上传文件)接口上传缩略图。然后,再次调用文件上传接口上传视频源文件。 - -视频消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :------------- | :----- | :--------- | -| `filename` | String | 视频文件名称,包含文件后缀名。 | -| `thumb` | String | 视频缩略图的 URL 地址,格式为 https://{host}/{org_name}/{app_name}/chatfiles/{file_uuid}。其中,`file_uuid` 为视频缩略图上传后,环信服务器返回的缩略图的 UUID。 | -| `length` | Int | 视频时长。单位为秒。 | -| `secret` | String | 视频文件的访问密钥,即成功上传视频文件后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`。如果视频文件上传时设置了文件访问限制(`restrict-access`),则发送消息时该字段为必填。 | -| `file_length` | Long | 否 | 视频文件大小,单位为字节。 | -| `thumb_secret` | String | 缩略图文件访问密钥。如果文件上传时设置了文件访问限制,则该字段存在。 | -| `url` | String | 视频文件的 URL 地址:https://{host}/{org_name}/{app_name}/chatfiles/{file_uuid}。其中 `file_uuid` 为文件 ID,成功上传视频文件后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取。 | - -示例如下: - -```json -"body": { - "filename" : "test.avi", - "thumb" : "https://XXXX/XXXX/XXXX/chatfiles/67279b20-7f69-11e4-8eee-21d3334b3a97", - "length" : 0, - "secret":"VfXXXXNb_", - "file_length" : 58103, - "thumb_secret" : "ZyXXXX2I", - "url" : "https://XXXX/XXXX/XXXX/chatfiles/671dfe30-XXXX-XXXX-ba67-8fef0d502f46" - } -``` - -### 文件消息 - -对于文件消息,通过 REST API 发消息时建议传入 `filename` 参数,否则客户端收到文件消息时无法显示文件名称,而且需保证通过 `url` 参数能下载到对应文件。 - -若上传文件时,设置了文件访问限制(`restrict-access`),则文件上传后,从[文件上传](/document/server-side/message_download.html#上传文件)的响应 body 中获取的 `share-secret`,发送文件消息时传入该参数。 - -文件消息的 body 包含如下字段: - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :------------ | -| `filename` | String | 否 | 文件名称。建议传入该参数,否则客户端收到文件消息时无法显示文件名称。 | -| `secret` | String | 否 | 文件访问密钥,即成功上传文件后,从 [文件上传](message_download.html#上传文件) 的响应 body 中获取的 `share-secret`。如果文件上传时设置了文件访问限制(`restrict-access`),则该字段为必填。 | -| `url` | String | 是 | 文件 URL 地址:`https://{host}/{org_name}/{app_name}/chatfiles/{file_uuid}`。其中 `file_uuid` 为文件 ID,成功上传视频文件后,从 [文件上传](message_download.html#上传文件) 的响应 body 中获取。 | - -示例如下: - -```json -"body": { - "filename":"test.txt", - "secret":"1-g0XXXXua", - "url": "https://XXXX/XXXX/XXXX/chatfiles/d7eXXXX7444" - } -``` - -### 消息携带自定义扩展字段 - -你可以在消息扩展部分 `ext` 中保存更多信息。例如,下面示例中的 `em_ignore_notification` 表示是否发送静默消息。 - -```json -"ext": { - "em_ignore_notification": true - } -``` - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :---------------------------------------------------------------------------- | -| `ext` | JSON | 消息支持扩展字段,可添加自定义信息。不能对该参数传入 `null`。 | - -### 自定义消息 - -自定义消息的 body 包含如下字段: - -| 参数 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------- | -| `customExts` | JSON | 用户自定义的事件属性,类型必须是 `Map`,最多可以包含 16 个元素。`customExts` 是可选的,发消息时不需要可以不传。 | -| `customEvent` | String | 用户自定义的事件类型。该参数的值必须满足正则表达式 [a-zA-Z0-9-_/\.]{1,32},长度为 1-32 个字符。 | -| `type` | String | 消息类型。自定义消息为 `custom`。 | - -自定义类型消息格式示例如下: - -```json -"body": -[ - { - "customExts": - { - "name":"flower", - "size":"16", - "price":"100" - }, - "customEvent":"gift_1", - "type":"custom" - } -] -``` - -## 离线推送的消息扩展字段 - -环信即时通讯 IM 支持 APNs 推送和 Android 厂商离线推送,包括华为、荣耀、FCM、小米、魅族、OPPO 和 vivo。使用离线推送时,你可以通过消息扩展字段实现推送相应功能,例如,设置推送模板中的推送标题和内容、设置仅接收提及(`@`)某些用户的推送通知等。 - -### 推送扩展字段 - -`payload.ext` 结构如下: - -| 字段 | 类型 | 描述 | -| ---------------------- | ------------ | ------------------ | -| `em_push_filter` | Object | 推送过滤。 | -| `em_at_list` | `List` | `@`列表。 | -| `em_push_template ` | Object | 推送模板。 | -| `em_ignore_notification` | Boolean | 静默消息开关,`true` 表示不推送。 | -| `em_force_notification` | Boolean | 强制推送开关,`true` 则不检查用户是否开启免打扰。 | -| `em_apns_ext` | Object | APNs 配置。 | -| `em_android_push_ext` | Object | Android 配置。 | -| `em_harmony_push_ext` | Object | 鸿蒙推送扩展配置。 | -| `em_push_ext` | Object | 通用的配置。 | - -`em_push_filter` 结构如下: - -| 字段 | 类型 | 描述 | -| ---------------- | ------------ | ------------------------ | -| `accept_device_id` | `List` | 接收推送通知的设备 ID 列表。 | -| `ignore_device_id` | `List` | 不接收推送通知的设备 ID 列表。 | -| `accept_notifier_name` | `List` | 接收推送的证书名列表。 | -| `ignore_notifier_name` | `List` | 不接收推送的证书名列表。 | - -`em_push_template` 结构如下: - -| 字段 | 类型 | 描述 | -| ------------ | ------------ | ------------------------------------------------------------ | -| `name` | String | 推送模板名称。 | -| `title_args` | `List` | 推送模板标题参数,内置参数:发送方昵称 `{$fromNickname}`。 | -| `content_args` | `List` | 推送模板内容参数,内置参数:消息内容 `{$msg}`,如果开通了翻译,消息内容会跟随翻译结果显示。 | - -关于 `title_args` 和 `content_args` 字段的设置,详见[推送模板文档](/document/server-side/push.html#使用推送模板)。 - -`em_push_ext` 结构如下: - -| 字段 | 类型 | 描述 | -| --------------------- | ------ | ---------------------------------------------- | -| `title` | String | 自定义推送标题。 | -| `content` | String | 自定义推送内容。 | -| `custom` | Object | 自定义推送扩展参数(t, f, m, g, e) 中 e 的内容。 | -| `group_user_nickname` | String | 发送方群组昵称(用于推送显示替换发送方信息)。 | - -`em_apns_ext` 结构如下: - -| 字段 | 类型 | 描述 | -| -------------- | ---------------- | ------ | -| `em_push_category` | String | APNs 推送配置,推送通知类别。 | -| `em_push_mutable_content` | Boolean | APNs 推送配置,`true` 为富文本推送通知,`false` 则为普通通知。 | -| `em_push_sound` | String | APNs 推送配置,自定义铃声,`Library/Sounds/` 目录下的 `aiff`、`wav` 或 `caf` 文件,例如 `appsound.caf`。 | -| `em_push_badge` | Integer | APNs 推送配置,自定义角标数。 | - -`em_android_push_ext` 结构如下: - -| 字段 | 类型 | 描述 | -| ------------------------- | ------- | ------------------------------------------------------------ | -| `fcm_options` | Object | FCM SDK 功能选项。 | -| `fcm_channel_id` | String | FCM 推送通道(最高优先级)。 | -| `honor_click_action` | String | 荣耀点击跳转,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **荣耀** 页面设置的 **Action** 参数的配置。 | -| `honor_importance` | String | 荣耀推送优先级:
- `LOW`:低优先级;
- (默认)`NORMAL`:普通优先级。 | -| `honor_target_user_type` | Integer | 推送用户类型:
- `0`:普通
- `1`:测试 | -| `huawei_target_user_type` | Integer | 推送用户类型:
- `0`:普通
- `1`:测试 | -| `huawei_category` | String | 完成[自分类权益申请](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835#section893184112272)后,用于标识消息类型,确定[消息提醒方式](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835#ZH-CN_TOPIC_0000001149358835__p3850133955718),对特定类型消息加快发送,取值如下:[华为官方文档中category字段的解释](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/https-send-api-0000001050986197#section13271045101216)。该参数的设置优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **华为** 页面设置的 **Category** 参数的配置。 | -| `huawei_receipt_id` | String | 华为回执地址 ID。 | -| `huawei_click_action` | String | 华为点击跳转 action,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **华为** 页面设置的 **Action** 参数的配置。 | -| `huawei_channel_id` | String | 华为推送通道(最高优先级)。 | -| `meizu_click_activity` | String | 魅族点击跳转 activity,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **魅族** 页面设置的 **Activity** 参数的配置。 | -| `oppo_channel_id` | String | OPPO 推送通道(最高优先级),优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **OPPO** 页面设置的 **Activity** 参数的配置。 | -| `oppo_click_activity` | String | OPPO 点击跳转 activity,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **OPPO** 页面设置的 **Activity** 参数的配置。 | -| `vivo_category` | String | vivo 二级分类配置,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **VIVO** 页面设置的 **Category** 参数的配置。 | -| `vivo_click_activity` | String | vivo 点击跳转 activity,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **VIVO** 页面设置的 **Activity** 参数的配置。 | -| `xiaomi_channel_id` | String | 小米通道 ID,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **小米** 页面设置的 **Channel ID** 参数的配置。 | -| `xiaomi_click_action` | String | 小米点击跳转 action,优先级高于在环信即时通讯控制台的**即时通讯** > **功能配置** > **消息推送** > **证书管理** > **添加推送证书** > **小米** 页面设置的 **Action** 参数的配置。 | - -`em_harmony_push_ext` 结构如下: - -| 字段 | 类型 | 描述 | -| ----------------- | ------- | ------------------------------------- | -| `category` | String | 消息分类。 | -| `click_action` | String | 点击跳转应用内页。 | -| `is_test_message` | Boolean | 是否是推送测试消息(beta 版仅支持测试)。 | -| `notify_id` | Integer | 通知 ID,相同的 ID 通知替换。 | -| `receipt_id` | String | 回执 ID。 | - -### 示例 - -离线推送的消息扩展字段如下所示: - -```json -{ - "ext": { - "em_push_filter": { - "accept_device_id": [ - - ], - "ignore_device_id": [ - - ], - "accept_notifier_name": [ - - ], - "ignore_notifier_name": [ - - ] - }, - "em_at_list": [ - "abc" - ], - "em_push_template": { - "name": "test6", - "title_args": [ - "test1" - ], - "content_args": [ - "{$fromNickname}", - "{$msg}" - ] - }, - "em_push_ext": { - "custom": { - "test": 1 - }, - "group_user_nickname": "happy" - }, - "em_ignore_notification": false, - "em_force_notification": true, - "em_apns_ext": { - "em_push_title": "您有一条新消息", - "em_push_content": "您有一条新消息", - "em_push_category": "", - "em_push_mutable_content": true, - "em_push_sound": "appsound.mp3", - "em_push_badge": 1 - }, - "em_android_push_ext": { - "fcm_options": { - "key": "value" - }, - "fcm_channel_id": "", - "honor_click_action": "", - "honor_importance": "", - "honor_target_user_type": 0, - "huawei_target_user_type": 0, - "huawei_category": "", - "huawei_receipt_id": "", - "huawei_click_action": "", - "huawei_channel_id": "", - "meizu_click_activity": "", - "xiaomi_channel_id": "", - "oppo_channel_id": "", - "oppo_click_activity": "", - "vivo_category": "", - "vivo_click_activity": "", - "xiaomi_channel_id": "", - "xiaomi_click_action": "", - }, - "em_harmony_push_ext": { - "click_action": "com.a.b.shot", - "category": "IM", - "notify_id": 1, - "receipt_id": "RCP78C959D4", - "is_test_message":true - } - } -} -``` - - - - - - diff --git a/docs/product/product_message_overview.md b/docs/product/product_message_overview.md deleted file mode 100644 index 1eda5490..00000000 --- a/docs/product/product_message_overview.md +++ /dev/null @@ -1,146 +0,0 @@ -# 消息概述 - - - -**消息**:表示发送方给接收方发送的内容。消息包括多种类型,如:文本、图片、语音、视频、位置消息等。 - -利用环信即时通讯 IM,开发者可方便以会话为单位对本地消息进行管理,从服务端获取历史会话和消息,提供消息回执等功能。 - -## 消息应用场景 - -### 单聊消息应用场景 - -- 应用内一对一聊天 -- 应用管理员向用户发消息 -- 向单个用户发送系统通知 - -### 群组中消息应用场景 - -- 多用户群组内沟通 -- 应用管理员向群组发消息 -- 向群组发送系统通知 - -### 聊天室中消息应用场景 - -- 多用户聊天室内沟通 -- 应用管理员向聊天室发消息 -- 向所有聊天室发系统通知 - -## 消息类型 - -消息分为以下三大类: -- 非附件类消息:文本消息、位置消息、透传消息; -- 附件类消息:图片消息、语音消息、视频消息; -- 自定义消息。 - -| 类型
| 描述 | -| :------------- | :----------------------------------------------------------- | -| 文本消息 | 文本消息的内容是文本,包含超链接和表情符号等。表情消息基于文本消息实现。
文本消息大小限制为 5 KB。 | -| 位置消息 | 位置消息需要第三方的地图服务提供经纬度信息。接收方接收到位置消息,通过经纬度信息可以在第三方的地图服务中显示位置。 | -| 透传消息 | 透传消息可视为命令消息。通过发送这条命令给对方,通知对方要执行的操作,对方收到消息后系统可以自定义处理。透传消息不会在 UI 上展示。
消息大小限制为 5 KB。
你可以使用透传消息更新头像和昵称以及进行状态同步等。
透传消息不会存入本地数据库。 | -| 图片消息 | 图片消息是附件消息,需要先将图片上传至消息服务器。接收方收到图片时自动下载图片缩略图。
图片默认不能超过 10 MB,图片消息大小限制为 5 KB。 | -| 语音消息 | 语音消息是附件消息,需要先将语音上传至消息服务器。接收方收到语音时自动下载语音。
音频文件默认不能超过 10 MB,音频消息大小限制为 5 KB。 | -| 视频消息 | 视频消息是附件消息,需要先将视频上传至消息服务器。接收方收到视频时自动下载视频缩略图,点击下载视频消息。对于 Web 端,视频消息没有缩略图。
视频文件默认不能超过 10 MB,视频消息大小限制为 5 KB。 | -| 文件消息 | 文件消息是附件消息,需要先将文件上传至消息服务器。
附件大小不能超过 10 MB,文件消息大小限制为 5 KB。 | -| 自定义消息 | 开发者自定义的消息类型。自定义消息支持设置类型名称,开发者可以添加多种自定义消息。
自定义消息大小限制为 5 KB。
自定义消息的使用场景:红包消息、模板消息等。 | - -:::tip -1. 默认情况下,消息附件,例如图片、音频、视频和其他文件不能超过 10 MB,可存储 7 天。若要提升其中一个上限,请联系商务。 -2. 当基础的消息类型不满足需求时,可以使用消息自定义扩展增强基础消息类型,典型的用例是发送引用较早文本或图像消息的消息。使用扩展后,消息大小不能超过原类型消息的大小。 -3. 消息附件的大小及存储时间限制与群组共享文件的相同。如果消息附件的其中一个限制进行了上调,群组共享文件的对应限制也会随之自动调整,反之亦然。 -::: - -## 消息功能列表 - -即时通讯 IM 的消息功能包括发送和接收消息、获取历史消息、撤回消息、搜索、修改和转发消息、以及导入、更新、删除和置顶消息等。 - -下表为各平台/框架支持的消息功能。 - -| 消息功能 | Android | iOS | Web | 小程序 | HarmonyOS | Flutter | React Native | Unity | Windows | -| :----: | :------: |:------: |:------: |:------: |:------: |:------: |:------: |:------: |:------: | -| 发送和接收消息 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 获取服务端历史消息 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 获取本地历史消息 | ✓ | ✓ | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | -| 撤回消息 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 搜索消息 | ✓ | ✓ | — | — | — | ✓ | ✓ | ✓ | ✓ | -| 修改消息 | ✓ | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | -| 转发消息 | ✓ | ✓ | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | -| 导入和插入消息 | ✓ | ✓ | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | -| 更新消息 | ✓ | ✓ | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | -| 删除服务端历史消息 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 删除本地历史消息 | ✓ | ✓ | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | -| 消息回执 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 置顶消息 | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ | -| 翻译消息 | ✓ | ✓ | ✓ | ✓ | — | ✓ | ✓ | ✓ | ✓ | -| 只投在线用户 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 获取消息流量统计 | ✓ | ✓ | — | — | — | — | — | — | — | -| 多端同步 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| 离线推送 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | - -## 消息发送控制 - -### 单聊消息发送控制 - -| 单聊消息发送控制 | 描述 | -| :--------- | :----- | -| 陌生人之间发送消息 | App 内任意两个用户之间均可发送单聊消息。该场景下,在环信即时通讯控制台的**即时通讯 > 服务概览**页面的**设置**区域下关闭了**好友关系检查**功能。 | -| App 管理员发送单聊消息 | App 管理员模拟其他用户向 app 内任意用户发送消息。 | -| 只给好友发送消息 | 只能给好友发送消息,即在环信即时通讯控制台的**即时通讯 > 服务概览**页面的**设置**区域下打开**好友关系检查**功能。 | -| 拒绝来自某用户的消息 | 可通过以下两种方法拒绝来自某个用户的消息:
- **将用户添加到黑名单**,拒绝来自该用户的消息。
- **将该用户从联系人列表移除。**这种情况适用于 app 仅支持好友之间发送消息的情况。如果 app 支持陌生人之间发送消息,例如,用户 A 从用户 B 的联系人列表移除,用户 A 仍然可以向用户 B 发送消息吧。
- **全局禁言 (RESTful API)**:可通过全局禁言功能,使指定用户无法向 app 内的任何用户发送单聊消息。| -|对消息放行或拦截|- **发送前回调**:环信 IM 服务器会在发送消息之前,向你的应用服务器发送请求,你可以根据业务需求配置规则决定下发或拦截消息。
- **内容审核**:基于内容审核结果对消息进行处理,包括拦截、替换敏感信息和放行消息。该服务只对文本、图片、音频和视频消息有效。 | - -### 群组/聊天室消息发送控制 - -| 群组/聊天室消息发送控制 | 描述 | -| :--------- | :----- | -| 消息发送优先级(仅对聊天室有效) |你可以设置聊天室的消息优先级:高、普通和低三种级别。在聊天室内消息并发量较大或消息发送频率过高的情况下,服务器首先丢弃低优先级消息,优先送达高优先级的消息。 | -| 消息优先发送(聊天室白名单)|聊天室白名单中的成员在聊天室中发送的消息为高优先级,会优先送达,但不保证必达。当负载较高时,服务器会优先丢弃低优先级的消息。即便如此若负载仍很高,服务器也会丢弃高优先级消息。 | -| 禁止发送消息 | - **黑名单**:成员加入黑名单后,会被移出群组/聊天室,无法再收发消息。
- **禁言**:成员被加入禁言列表后,将无法在群组/聊天室内发送消息,即使其被加入白名单也不能发消息,但可以正常接收消息。**全员禁言**开启后,除了在白名单中的成员,其他成员不能发消息。
- **全局禁言 (RESTful API)**:用户被全局禁言后,无法发送单聊消息、或在无法在所有群组或聊天室中发送消息。群组或聊天室白名单中的成员被全局禁言后,仍无法在所有单聊、群组或聊天室中发消息。| -|对消息放行或拦截|- **发送前回调**:环信 IM 服务器会在发送消息之前,向你的应用服务器发送请求,你可以根据业务需求配置规则决定下发或拦截消息。
- **内容审核**:基于内容审核结果对消息进行处理,包括拦截、替换敏感信息和放行消息。该服务只对文本、图片、音频和视频消息有效。 | - -## 消息存储 - -消息存储分为本地存储和服务器存储。例如,客户端 A 向客户端 B 发送消息,客户端 A 发送消息到环信服务器的同时,SDK 会保存这条消息到本地数据库(SDK 内部创建数据库,不允许直接操作),环信服务器将消息发送到客户端 B 的同时也会进行记录,客户端 B 收到消息后,SDK 会将消息存储到本地数据库。 - -### SDK 存储 - -SDK 内部使用 SQLite 保存本地消息,你可以获取本地消息。 - -:::tip -Web 和小程序端无本地消息存储。 -::: - -### 服务端存储 - -### 历史消息存储 - -历史消息在服务器上的存储时间与你订阅的套餐包有关,详见[产品价格](/product/pricing.html#套餐包功能详情)。环信即时通讯 IM 提供消息漫游功能,即将用户的所有会话的历史消息保存在消息服务器,用户在任何一个终端设备上都能获取到历史信息,使用户在多个设备切换使用的情况下也能保持一致的会话场景。默认可获取单聊和群组聊天的历史消息。**若要获取聊天室的历史消息,需联系环信商务**。 - -**消息附件的存储** - -默认情况下,消息附件可在服务器存储 **7** 天。若要提升该限制,你需要联系商务。消息附件的大小及存储时间限制与群组共享文件的相同。如果消息附件的其中一个限制进行了上调,群组共享文件的对应限制也会随之自动调整,反之亦然。 - -### 离线消息存储 - -对于单聊和群聊,离线消息默认保存 **7** 天。对于每个终端用户,所有的单聊会话可存储 500 条离线消息,所有的群聊会话可存储 200 条离线消息。若超过存储天数和条数的上限,最新的离线消息会挤掉最早的。如需提升上限,可联系商务。 - -### 事件通知存储 - -各类事件通知的存储时间与消息的存储一致。 - -## 消息重发机制 - -1. 对于 Android、iOS 、HarmonyOS、Windows 端和三个跨平台框架 Unity、React Native 和 Flutter 来说,消息重发机制如下: - -客户端调用发送消息的方法后,会等待服务器返回响应,超时时间为 10 秒。若因响应超时导致发送失败,客户端会再次尝试发送消息,即通过长连接重连服务器,然后发送消息。如果再次失败,SDK 认为消息发送失败,返回服务器不可达的错误消息,即错误码 300,iOS 为 `EMErrorServerNotReachable`,Android, HarmonyOS 和 Windows 为 `SERVER_NOT_REACHABLE`。 - -2. 对于 Web 来说,消息重发机制如下: - -发送消息时如果 WebSocket 已经断开正在进行重连时,重新连接后会重新发送消息;若 WebSocket 断开时发送消息,SDK 会提示网络断开连接导致消息发送失败的错误,即错误码 510 `MESSAGE_WEBSOCKET_DISCONNECTED`。 - -## 消息格式 - -关于各类型消息格式以及离线推送的消息扩展字段,详见[消息格式文档](product_message_format.html)。 - - - diff --git a/docs/product/product_offline_push_overview.md b/docs/product/product_offline_push_overview.md deleted file mode 100644 index e302ef0e..00000000 --- a/docs/product/product_offline_push_overview.md +++ /dev/null @@ -1,120 +0,0 @@ -# 离线推送 - -环信即时通讯 IM 支持集成第三方离线消息推送服务。客户端断开连接或应用进程被关闭等原因导致用户离线时,即时通讯 IM 会通过第三方消息推送服务向该离线用户的设备推送消息通知。当用户再次上线时,服务器会将离线期间的消息发送给用户。例如,当你离线时,有用户向你发送了消息,你的手机的通知中心会弹出消息通知,当你再次打开 app 并登录成功,即时通讯 IM SDK 会主动拉取你不在线时的消息。 - -:::tip -以下两种情况,即时通讯 IM 不会发送离线推送通知: -1. 若应用在后台运行,则用户仍为在线状态,即时通讯 IM 不会向用户推送消息通知。 -2. 应用在后台运行或手机锁屏等情况,若客户端未断开与服务器的连接,则即时通讯 IM 不会收到离线推送通知。 -::: - -## 各端支持的推送服务或推送插件 - -| 平台 | 支持的推送服务 | 参考文档 | -| -------------- | ---------------- | ------ | -| Android | - Google FCM
- 华为
- 荣耀
- OPPO
- VIVO
- 小米
- 魅族 | 各推送服务的集成以及推送设置,详见 [Android 推送文档](/document/android/push/push_overview.html)。 | -| iOS | APNs | APNs 推送服务的集成以及推送设置,详见 [APNs 推送文档](/document/ios/push/push_overview.html)。 | -| uni-app | uni-app SDK 支持推送插件 `EMPushUniPlugin`。 | 推送插件相关描述,详见 [uni-app 推送插件](/document/applet/push/uniapp_push.html) | -| React Native | React Native SDK 支持离线推送配置。| 详见 [React Native 离线推送文档](/document/react-native/push/push_overview.html)。 | - -:::tip -环信 IM Web SDK 本身不支持离线推送,只支持对移动端离线推送进行配置。具体设置,详见 [Web 离线推送文档](/document/web/push/push_overview.html)。 -::: - -## 推送 token - -推送 token(device token) 是第三方推送厂商提供的推送 token。例如,对于 FCM 推送,初次启动你的应用时,FCM SDK 为客户端应用实例生成的注册令牌 (registration token)。该 token 用于标识每台设备上的每个应用,FCM 通过该 token 明确消息是发送给哪个设备的,然后将消息转发给设备,设备再通知应用程序。你可以调用 `FirebaseMessaging.getInstance().getToken()` 方法获得 token。 - -打开应用,初始化环信 IM SDK 成功且成功登录后,获取推送 token,将 token 上传至环信服务器,与 IM 的登录账号绑定。 - -如果退出即时通讯 IM 登录时不解绑 device token。例如,对于 Android 平台,调用 `logout` 方法时对 `unbindToken` 参数传 `false` 时不解绑 `device token`,传 `true` 表示解绑 token),用户在推送证书有效期和 token 有效期内仍会接收到离线推送通知。 - -## 上传推送证书 - -在第三方推送服务控制台创建应用后,下载推送证书并获取证书相关信息,将推送证书上传至环信即时通讯控制台,并配置证书相关信息。 - -例如,对于 FCM 推送证书相关配置,详见 [FCM 推送集成文档](/document/android/push/push_fcm.html#步骤三-上传推送证书)。 - -## 多设备离线推送策略 - -多设备登录时,可在环信即时通讯控制台的证书管理页面配置推送策略,该策略配置对所有推送通道生效: - -- 所有设备离线时,才发送推送消息; -- 任一设备离线时,都发送推送消息。 - -**多端登录时若有设备被踢下线,即使接入了 IM 离线推送,也收不到离线推送消息。** - -## 推送高级功能 - -要使用离线推送的高级功能,包括推送通知方式、免打扰模式和使用推送模板,你可以在环信即时通讯控制台的**即时通讯 > 功能配置 > 功能配置总览**页面激活推送高级功能。**如需关闭推送高级功能必须联系商务,因为该操作会删除所有相关配置。** - -### 推送通知方式 - -推送通知方式包括以下三种: -- 接收所有离线消息的推送通知。 -- 仅接收提及某些用户的消息的推送通知。该参数推荐在群聊中使用。若提及一个或多个用户,需在创建消息时对 ext 字段传 "em_at_list":["user1", "user2" ...];若提及所有人,对该字段传 "em_at_list":"all"。 -- 不接收离线消息的推送通知。 - -推送通知方式在 App 或单聊/群聊会话层级生效,会话级别的设置优先于 app 级别的设置,未设置推送通知方式的会话默认采用 app 的设置。 - -关于推送通知方式的设置,详见相应文档,例如,对于 Android,可参见[推送通知方式文档](/document/android/push/push_notification_mode_dnd.html#推送通知方式)。 - -### 免打扰模式 - -免打扰的设置包括免打扰时间段和免打扰时长。环信 IM 在这两个时间段内不发送离线推送通知,因此,你可以通过设置免打扰模式关闭推送。若在免打扰时段或时长生效期间需要对指定用户推送消息,需设置[强制推送](/document/android/push/push_extension.html#强制推送)。 - -免打扰时间段仅在 app 级别生效,而免打扰时长对 app、单聊和群聊会话均生效。如果你既设置了免打扰时间段,又设置了免打扰时长,免打扰模式的生效时间为这两个时间段的累加。 - -关于免打扰时间段和免打扰时长的设置,详见相应文档,例如,对于 Android,可参见[免打扰模式文档](/document/android/push/push_notification_mode_dnd.html#免打扰模式)。 - -### 推送通知方式与免打扰模式之间的关系 - -对于 app 和 app 中的所有会话,免打扰模式的设置优先于推送通知方式的设置。对于二者关系的具体描述,详见相应文档,例如,对于 Android,可参见[推送通知方式与免打扰模式之间的关系文档](/document/android/push/push_notification_mode_dnd.html#免打扰模式)。 - -### 使用推送模板 - -设置推送模板为推送的高级功能,使用前需要在[环信即时通讯控制台](https://console.easemob.com/user/login)的**即时通讯 > 功能配置 > 功能配置总览**页面激活推送高级功能。 - -推送模板主要用于服务器提供的默认配置不满足你的需求时,可使你设置全局范围的推送标题和推送内容。例如,服务器提供的默认设置为中文和英文的推送标题和内容,你若需要使用韩语或日语的推送标题和内容,则可以设置对应语言的推送模板。推送模板包括默认推送模板 `default` 和自定义推送模板,你可以通过以下两种方式设置: - -- [调用 REST API 配置](/document/server-side/push.html#使用推送模板)。 -- 在[环信即时通讯云控制台](https://console.easemob.com/user/login)设置推送模板,详见[控制台文档](/product/enable_and_configure_IM.html#配置推送模板)。 - -使用推送模板有以下优势: - -1. 自定义修改环信服务端默认的推送内容。 -2. 接收方可以决定使用哪个模板。 -3. 按优先级选择模板使用方式: - - 使用自定义推送模板的优先级高于默认推送模板。 - - 若发送方发消息时设置了推送模板,接收方即使设置了推送模板,收到推送通知后也按照发送方设置的推送模板显示。 - -关于推送模板的详情,可以参见各端的[如何使用推送模板](/document/android/push/push_display.html#使用推送模板)的文档。 - -## 开启第三方离线推送服务 - -在环信即时通讯 IM SDK 初始化时开启相应的离线推送服务,例如 对于 FCM 推送,详见 [FCM 推送集成文档](/document/android/push/push_fcm.html#步骤四-fcm-推送集成)。 - -## 设置推送通知的显示内容 - -对于推送通知的标题和内容,你可以通过多种方式设置,包括调用 API、使用推送模板以及发送消息时使用消息扩展字段。 - -关于这些设置方式的使用和设置优先级,详见具体文档,例如,对于 Android,可参见[设置通知的显示内容](/document/android/push/push_display.html)。 - -## 推送翻译 - -推送通知与[翻译功能](/document/android/message_translation.html)协同工作。如果用户启用自动翻译功能并发送消息,SDK 会同时发送原始消息和翻译后的消息。 - -作为接收方,你可以设置你在离线时希望接收的推送通知的首选语言。如果翻译消息的语言符合你的设置,则翻译消息显示在推送通知中;否则,将显示原始消息。翻译功能由 Microsoft Azure Translation API 提供,你可以点击[这里](https://learn.microsoft.com/zh-cn/azure/ai-services/translator/language-support)了解支持的翻译语言。 - -关于如何设置和获取推送通知的首选语言,详见相应文档,例如,对于 Android,可参见[设置推送翻译文档](/document/android/push/push_translation.html)。 - -## 推送扩展 - -你可以利用扩展字段实现自定义推送设置,包括仅对群组中某些成员推送通知、设置通知栏折叠、强制推送和发送静默消息。 - -关于如何设置推送扩展字段,详见相应文档,例如,对于 Android,可参见[设置推送扩展功能文档](/document/android/push/push_extension.html)。 - - - - - diff --git a/docs/product/product_thread_overview.md b/docs/product/product_thread_overview.md deleted file mode 100644 index bd234b89..00000000 --- a/docs/product/product_thread_overview.md +++ /dev/null @@ -1,39 +0,0 @@ -# 子区 - -子区可由群成员基于一条群组消息创建,是群组的子集,该条群组消息称为子区的父消息。 - -## 子区管理 - -| 功能 | 描述 | -| :--------- | :----- | -| 创建子区 | 所有群成员均可基于一条群组消息新建子区。 | -| 解散子区 | 仅子区所在群组的群主和群管理员可以解散子区。 | -| 加入子区 | 子区所在群组的所有成员均可以加入子区。你可以调用 REST API 批量加入子区。 | -| 退出子区 | 子区成员均可以退出子区。你可以调用 REST API 将成员批量踢出子区。退出子区后,该成员将不会再收到子区消息:
- 子区成员主动退出子区;
- 子区成员被移出子区。仅群主和群管理员有该权限。 | -| 修改子区名称 | 仅群主和群管理员以及子区创建者可以修改子区名称。 | -| 获取子区详情 | 子区所属群组的所有成员均可以从服务器获取子区详情。 | -| 获取子区成员列表 | 子区所属群组的所有成员均可以从服务器分页获取子区成员列表。 | -| 获取子区列表 | - 用户可以从服务器分页获取自己加入和创建的子区列表。
- 从服务器分页获取指定群组中自己加入和创建的子区列表。 | -| 批量获取子区中的最新消息 | 用户可以从服务器批量获取子区中的最新一条消息。 | -| 获取子区 | 你可以调用 REST API 获取子区:
- 获取 app 下的所有子区。
- 获取单个用户加入的所有子区。
- 获取当前用户加入的所有子区。
- 获取单个用户在指定群组中加入的所有子区。| - -## 子区消息管理 - -| 功能 | 描述 | -| :--------- | :----- | -| 发送子区消息 | 发送子区消息和发送群组消息的方法基本一致。唯一不同的是,发送子区消息需要指定是否是子区的标记。| -| 接收子区消息 | 接收子区消息与接收单聊、群聊和聊天室相同,详见[接收消息](/document/android/message_send_receive.htm)。 | -| 撤回子区消息 | 撤回子区消息的逻辑与撤回单聊、群聊和聊天室相同。消息撤回后,子区所属群组的所有成员收到子区更新回调,子区成员收到子区消息撤回的回调。 | -| 获取子区消息 | 你可以从服务器或本地获取单个子区的消息。 | - -## 监听子区事件 - -你可以实现子区事件监听,若子区内进行了相关操作,包括子区创建、子区名称修改、子区解散、子区成员被移除,子区中的其他人员会收到相关事件,详见[监听子区事件](/document/android/thread.html#监听子区事件)。 - -## 子区事件回调 - -你可以实现发送后回调,使环信 IM 服务器通过 HTTP/HTTPS POST 请求将子区事件(例如,对子区中的一条消息进行相关操作,包括发送、撤回或修改)同步给你的应用服务器,详见[子区事件回调文档](/document/server-side/callback_thread.html)。 - -## 子区限制 - -子区相关限制,详见[子区限制文档](/product/limitation.html#子区)。 \ No newline at end of file diff --git a/docs/product/product_user_attribute.md b/docs/product/product_user_attribute.md deleted file mode 100644 index b717c1e4..00000000 --- a/docs/product/product_user_attribute.md +++ /dev/null @@ -1,26 +0,0 @@ -# 用户属性 - -用户属性指实时消息互动用户的资料,如用户昵称、头像、邮箱、电话、性别、签名、生日等。 - -环信 IM 提供用户资料的存储能力, 你可以根据自己的需要设置存储内容: - -- 默认资料字段的读写能力; -- 自定义资料字段的读写能力。 - -## 用户属性字段 - -单个用户的所有属性最大不超过 2 KB,单个 app 所有用户属性数据最大不超过 10 GB。 - -关于用户属性,客户端针对用户的昵称、头像 URL、联系方式、邮箱、性别、签名、生日和扩展字段默认使用以下键名。调用 [RESTful 接口设置](/document/server-side/userprofile.html#设置用户属性)或[删除](/document/server-side/userprofile.html#删除用户属性)用户属性时,若要确保在客户端能够获取设置,请求中必须传以下键名与客户端保持一致,键值可根据实际使用场景确定。 - -| 字段 | 类型 | 描述 | -| :---------- | :----- | :------- | -| `nickname` | String | 用户昵称。长度在 64 个字符内。 | -| `avatarurl` | String | 用户头像 URL 地址。长度在 256 个字符内。 | -| `phone` | String | 用户联系方式。长度在 32 个字符内。 | -| `mail` | String | 用户邮箱。长度在 64 个字符内。 | -| `gender` | Int | 用户性别:
- `1`:男;
- `2`:女;
- (默认)`0`:未知;
- 设置为其他值无效。 | -| `sign` | String | 用户签名。长度在 256 个字符内。 | -| `birth` | String | 用户生日。长度在 64 个字符内。 | -| `ext` | String | 扩展字段。 | - diff --git a/docs/product/product_user_presence.md b/docs/product/product_user_presence.md deleted file mode 100644 index b77f7832..00000000 --- a/docs/product/product_user_presence.md +++ /dev/null @@ -1,92 +0,0 @@ -# 用户在线状态管理 - -用户在线状态(即 Presence)包含用户的在线、离线和自定义状态。 - -## 用户在线状态类型 - -### 在线 - -用户启动 app 后,客户端和即时通信 IM 服务端成功建立了网络连接。客户端可以发消息给即时通信 IM 服务端,也可以收到来自即时通信 IM 服务端推送的消息。即时通信 IM 服务端保存客户端的在线信息,例如,客户端的网络链路信息,客户端的平台版本等。App 在运行过程中,**IM SDK 每隔 5 分钟发一个心跳包给服务器,以确认用户的在线状态。** - -### 离线 - -离线指用户成功登出环信即时通讯 IM 系统或与即时通讯 IM 系统断开连接后的状态。用户登出即时通讯 IM 系统之后,无法发送和接收消息,在下次登录后可以接收到离线消息。 - -在以下场景下,用户为离线状态: - -- **杀掉 App 进程**:用户将 App 切后台后进程后被设备的操作系统杀掉,或用户主动杀掉 App 进程。 -- **网络连接断开**:用户主动关闭客户端网络,状态立即会变成离线。或者,客户端网络完全不可用时,例如,进入没有网络信号的隧道或打开移动设备的飞行模式,环信即时通信 IM 服务端等待 5 分钟后发现心跳包超时,状态会变成离线。 - -### 自定义状态 - -用户可以设置自定义状态,例如忙碌、马上回来、离开、接听电话、外出就餐等。 - -## 查询用户在线状态 - -环信即时通讯 IM 支持调用 [REST API](/document/server-side/presence.html#批量获取在线状态信息) 或[客户端接口](/document/android/presence.html#查询被订阅用户列表)批量查询用户的在线状态。 - -## 用户状态变更 - -### 用户在线状态变更通知 - -1. 用户的状态从“在线”变为“离线”时,客户端收到连接断开通知(例如,Android 为 `OnDisconnected`),从“离线”变为“在线”时,客户端收到已连接通知(例如,Android 为 `OnConnected`)。 - -2. 用户发布自定义在线状态后,发布者和订阅者均会收到自定义在线状态变更的回调,例如,Android 为 `EMPresenceListener#onPresenceUpdated` 回调。 - -3. 当 SDK 监测到当前账号从“自定义状态”变更为“离线”状态后,会自动清除自定义状态,并且触发状态变更通知,例如,Android 为 `OnConnected`。 - -### 用户状态回调事件 - -用户成功登入时,状态为在线,成功登出或被踢下线时,用户状态为离线。 - -用户登入、登出或被踢时,环信服务器会向你设置的发送后回调地址发送相关事件时携带用户状态,详见[用户登入和登出事件](/document/server-side/callback_login_logout.html)。 - -### 状态变更感知的实时性 - -#### Android/iOS/HarmonyOS/Flutter/React Native - -用户可实时感知用户状态变化: - -- 用户登录成功,状态变成在线; -- 用户登出成功,状态变成离线。若调用登出接口时,设置了解绑推送 token(device token),则用户无法收到离线推送通知;若不解绑,则用户可以收到离线推送通知。 -- 用户主动杀掉客户端进程或用户将 App 切后台后进程被设备的操作系统杀掉,状态变成离线。 -- 当网络不可用,例如,用户打开移动设备飞行模式或进入无网络的隧道,环信即时通信 IM 服务端等待 5 分钟后发现心跳包超时,用户状态会变成离线。 - -#### Web - -用户成功登录 Web 端时,环信服务器可以实时感知到状态变成在线: - -- 直接关闭页面,可以实时感知,状态变成离线。 -- 页面不关闭时,网络断开,需要 5 分钟左右才能感知到,状态变成离线。 -- 主动调用 `close` 接口,可以实时感知,变成离线。 -- 当网络不可用,例如,用户打开移动设备飞行模式或进入无网络的隧道,环信即时通信 IM 服务端等待 5 分钟后发现心跳包超时,用户状态会变成离线。 - -#### 小程序 - -用户成功登录小程序端时,环信服务器可以实时感知到状态变成在线: - -- 点右上角退出,5s 内感知到状态变成离线。 -- 断网(如手机开启飞行模式) ,需要 5 分钟左右 感知到状态变成离线。 -- 微信切后台,30s 左右状态变成离线。 -- 杀掉微信进程,可以实时感知,变成离线。 -- 主动调用 `close` 接口,可以实时感知,变成离线。 -- 当网络不可用,例如,用户打开移动设备飞行模式或进入无网络的隧道,环信即时通信 IM 服务端等待 5 分钟后发现心跳包超时,用户状态会变成离线。 - -#### Unity/Windows - -用户可实时感知用户状态变化: - -- 用户登录成功,状态变成在线; -- 用户登出成功,状态变成离线。 -- 用户主动杀掉客户端进程或用户将 App 切后台后进程被设备的操作系统杀掉,状态变成离线。 -- 当网络不可用,例如,用户打开移动设备飞行模式或进入无网络的隧道,环信即时通信 IM 服务端等待 5 分钟后发现心跳包超时,用户状态会变成离线。 - -## 多端登录 - -- **多设备同时在线**:多端登录时,即时通讯 IM 每端默认最多支持 4 个设备同时在线。如需增加支持的设备数量,可以联系环信即时通讯 IM 的商务经理。 - -单设备登录场景下,后登录的设备会将之前登录的设备踢下线。被踢下线的设备处于未登录状态,不会收到离线推送。 - -- **踢下线**:多设备登录时,若达到登录设备数量的上限,新登录的设备会将之前登录的设备踢下线。被踢下线的设备处于未登录状态,不会收到离线推送。 - -关于多端登录,详见[相关文档](/document/android/multi_device.html)。 \ No newline at end of file diff --git a/docs/product/product_user_registration_login.md b/docs/product/product_user_registration_login.md deleted file mode 100644 index 8902ec8d..00000000 --- a/docs/product/product_user_registration_login.md +++ /dev/null @@ -1,43 +0,0 @@ -# 用户注册与登录 - -本文介绍用户注册模式与登录方式。 - -## 用户注册模式 - -用户注册模式分为以下两种: - -- 开放注册:一般在体验 Demo 和测试环境时使用,正式环境中不推荐使用该方式注册环信账号。要使用开放注册,需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**开放注册**。只有打开该开关,才能使用客户端或 [REST API](/document/server-side/account_system.html#开放注册单个用户)开放注册用户。 -- 授权注册:通过环信提供的 REST API 注册环信用户账号,注册后保存到你的服务器或返给客户端。要使用授权注册,你需要在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**即时通讯** > **服务概览**的**设置**区域,将**用户注册模式**设置为**授权注册**。相关的 REST API 介绍,详见[授权注册单个用户](/document/server-side/account_system.html#授权注册单个用户)和[批量授权注册用户](/document/server-side/account_system.html#批量授权注册用户)的接口介绍。 - -除此以外,可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建用户,详见[创建用户相关介绍](/product/enable_and_configure_IM.html#创建-im-用户)。 - -## 用户登录 - -初始化环信即时通讯 IM SDK 后,你需要调用登录接口进行登录。只有登录成功后,你才能正常使用 IM 的各种功能,例如消息和会话。 - -目前登录服务器支持主动和自动登录。主动登录有两种方式: - -- 用户 ID + 密码 -- 用户 ID + token - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :-------------------------------------------- | -| `username` | String | 是 | 用户 ID,长度不可超过 64 个字节。不可设置为空。支持以下字符集:
- 26 个小写英文字母 a-z;
- 26 个大写英文字母 A-Z;
- 10 个数字 0-9;
- “_”, “-”, “.”。

- 该参数不区分大小写,因此 `Aa` 和 `aa` 为相同的用户 ID。
- 请确保同一个 app 下,用户 ID 唯一;
- 用户 ID 为公开信息,请勿使用 UUID、邮箱地址、手机号等敏感信息。
| -| `token` | String | 是 | token 可以通过调用 REST API 获取,即传入用户 ID (或用户 ID + 密码)和 token 有效期参数获取,详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。

- 你可以在调用 REST API 获取 token 时,传入 `ttl` 参数,设置 token 的有效期。此外,你也可以通过[环信即时通讯云控制台](https://console.easemob.com/user/login/)的**用户认证**页面设置 token 的有效期。该参数值以最新设置为准。
- 环信服务器完全信赖用户 token,为避免业务受影响,你需要确保 token 的安全。
| -| `password` | String | 是 | 用户的登录密码,长度不可超过 64 个字符。| - -## 登录流程 - -- 用户 ID + 密码 - -![img](/images/product/login_userid_pwd.png) - -- 用户 ID + Token - -![img](/images/product/login_userid_token.png) - -:::tip -1. 关于获取 token,详见[获取 App Token](/document/server-side/easemob_app_token.html)和[获取 User Token](/document/server-side/easemob_user_token.html)。 -2. 获取 token 时,token 有效期 `ttl` 以传入的值为准。若不传该参数,以[环信即时通讯云控制台](https://console.easemob.com/user/login)的**用户认证**页面的 token 有效期的设置为准,默认为 60 天。若设置为 `0`,则 token 永久有效。 -::: - diff --git a/docs/product/product_user_relationship.md b/docs/product/product_user_relationship.md deleted file mode 100644 index 29feb7ec..00000000 --- a/docs/product/product_user_relationship.md +++ /dev/null @@ -1,83 +0,0 @@ -# 用户关系 - -环信即时通讯 IM 支持用户关系管理能力,提供完整的社交关系管理方案: - -- 支持用户关系存储能力, 包括: 好友关系和用户黑名单。 -- 支持用户关系管理能力,包括: - - 添加好友; - - 删除好友; - - 添加好友至黑名单; - - 将好友移除黑名单。 -- 支持方便易用的客户端和服务端接口, 满足多种业务场景需求。 - -## 联系人列表 - -你可以对联系人列表进行相关管理操作,包括添加好友、删除好友、从服务端和本地获取联系人列表以及导入联系人列表。 - -联系人列表相关的限制,如单个用户的好友数上限,详见[产品使用限制](/product/limitation.html)。 - -### 添加好友 - -即时通讯 IM 支持每次添加单个好友。添加好友的流程如下: - -- 服务端:调用 REST API 可直接将用户添加至联系人列表,要添加的好友无需确认。 -- 客户端:例如,若用户 A 添加用户 B 为好友:用户 A 申请添加用户 B,用户 B 接到好友邀请后,选择同意或拒绝成为好友;若同意,则添加好友成功,则用户 A 和 B 均被添加到对方的联系人列表中。若拒绝,则添加好友失败。 - -好友表中的好友信息如下: - -- 为哪个用户添加的好友。 -- 好友的用户 ID。 -- 好友备注(如果调用添加好友备注接口进行了设置)。 - -### 删除联系人 - -即时通讯 IM 支持每次删除单个联系人。删除联系人的同时会删除对方联系人列表中的该用户。 - -删除操作不需要对方同意或者拒绝。此外,删除联系人时支持选择是否保留其会话和消息。 - -### 获取联系人列表 - -- 利用服务端 API: - - 可[调用推荐的方法分页获取联系人列表](/document/server-side/user_relationship.html#分页获取好友列表),其中每个好友对象包含好友的用户 ID 和备注。不过, - - 你也可以[调用之前的方法一次性获取所有联系人的列表](/document/server-side/user_relationship.html#一次性获取好友列表),该列表只包含联系人的用户 ID。 -- 利用客户端 API: - - 可调用推荐的方法[从服务器一次性或分页获取联系人列表](/document/android/user_relationship.html#从服务端获取好友列表),其中每个好友对象包含联系人的用户 ID 和备注。你也可以调用之前的方法一次性获取所有联系人的列表,该列表只包含联系人的用户 ID。 - - 可一次性获取本地联系人列表或单个联系人的信息,包括联系人的用户 ID 和备注。 - -:::tip -需要从服务器获取联系人列表之后,才能从本地获取到联系人列表。 -::: - -### 导入联系人列表 - -你可以[调用 REST API](/document/server-side/user_relationship.html#导入好友列表) 一次性导入多个联系人。 - -## 开启或关闭发送消息权限控制 - -单聊用户之间的消息通讯,包括好友之间和陌生人之间的通讯。例如,对于企业内部的移动办公 app 来说,企业内部同事之间可以互相发送消息,可能不需要消息发送权限控制,而对于一个交友类 app,可能要控制只有好友之间才能发送消息,陌生人之间若要发消息,需要发送好友邀请,同意加好友后才能发消息。 - -环信即时通信 IM 默认支持陌生人之间发送单聊消息,即无需添加好友即可聊天。若仅允许好友之间发送单聊消息,你需要按以下步骤开启好友关系检查。 - -1. 在环信即时通讯云的左侧导航栏中,选择 **即时通讯** > **服务概览**。 -2. 在 **设置** 区域,点击 **好友关系检查**对应的 **打开**,则该功能的状态为**已开启**。若关闭该功能,点击 **关闭**。 - 该功能开启后,SDK 会在用户发起单聊时检查好友关系,若用户向陌生人发送单聊消息,SDK 会提示错误码 221。 - -## 黑名单 - -每个用户都有一份黑名单,用于保存被拉黑的用户。黑名单最多可添加 500 个用户。 - -用户可以将任何用户加入黑名单,不论该用户与你是否是好友关系。黑名单上的用户无法向你发送消息,也无法发送好友申请。好友被加入黑名单后仍在联系人列表上显示。 - -你可以[添加用户到黑名单](/document/android/user_relationship.html#添加用户到黑名单)、[将用户从黑名单移除](/document/android/user_relationship.html#将用户从黑名单移除)以及[从服务器和本地数据库获取黑名单](/document/android/user_relationship.html#从服务器获取黑名单列表)。 - - - - - - - - - - - - diff --git a/docs/product/request_quality_overview.md b/docs/product/request_quality_overview.md deleted file mode 100644 index 6d450305..00000000 --- a/docs/product/request_quality_overview.md +++ /dev/null @@ -1,98 +0,0 @@ -# 请求质量概览 - - - -**请求质量概览** 模块提供质量数据的阶段性分析,帮助你掌握用量变化趋势、跟踪产品质量情况: - -- 自动采集、处理和存储多个用量和质量指标的数据,数据延时为 1 小时。 - -- 支持查看终端 SDK API 和服务器端 RESTful API 调用的请求次数、请求成功率和平均时延等。 - -## 请求质量监控 - -![img](/images/console/requestmonitor/terminalsum.png) - -### 终端数据 - -**终端数据** 页面展示终端 SDK API 的请求次数、请求成功率和平均时延数据。 - -#### 指标类型 - -![img](/images/console/requestmonitor/terminalindextype.png) - -| 指标类型 | 描述 | -| :----------- | :-------------------------------- | -|手动登录 |客户端用户通过用户ID、密码或者 token 登录。| -|自动登录 |客户端对于已登录过的账户,直接采用默认账户登录。| -|发送消息 |客户端发送的消息的统计。| -|好友管理 |客户端加好友、删除好友等好友相关操作。| -|用户管理 |客户端创建用户、更新用户信息等用户管理操作。| -|群组管理 |客户端创建群组、解散群组等群组管理操作。| -|聊天室管理 |客户端创建聊天室、解散聊天室等群组管理操作。| - -#### 指标 - -![](/images/console/requestmonitor/terminalindex.png) - -|指标|描述| -| :----------- | :-------------------------------- | -|请求次数|客户端 SDK API 的总请求次数。| -|1s/3s/5s 请求成功率|客户端 SDK API 在 1s/3s/5s 成功的请求次数 ÷ 总有效请求次数 × 100%。| -|平均时延|客户端 SDK API 请求的总延时 ÷ 总请求次数。| - -总有效请求次数不包含客户端操作失误的次数。操作失误具体指以下情况: -- 用户名或密码为空或错误。 -- 用户名不合法。 -- 密码无效。 -- 不具备操作权限,需要应用程序管理员许可。 -- 用户不存在。 -- 群组不存在。 -- 用户不在群组中。 - -为了更直观的呈现数据,不同指标采用了不同的图表形式,具体说明如下: - -|指标|左侧地图|右侧图|交互说明| -| :------- | :----- | :------------------------ | :------- | -|请求次数|请求次数越高,该区域的颜色越深。|折线图。|首次进入页面时,右侧时序图默认展示左侧地图上所有区域的指标数据之和。在左侧地图单击某一区域后,右侧时序图会更新为该区域的指标数据。| -|1s/3s/5s 请求成功率|请求次数越高,该区域的颜色越深。 气泡直径越大,该区域的请求成功率越低。|折线图。| | -|平均时延|请求次数越高,该区域的颜色越深。气泡直径越大,该区域的平均时延越高。|热力图,其中横坐标为时间,纵坐标为时延分桶。方块颜色越深,对应时间范围内的请求次数越高。|  | - -### Server API 数据 - -**Server API 数据** 页面以折线图展示服务器端 RESTful API 接口调用的请求次数、请求成功率和平均时延数据。 - -Server API 数据包含了一部分 SDK 对 RESTful API 接口的调用。例如,SDK 端的群组操作通过 RESTful API 调用,因此也统计在 Server API 数据中。 - -![](/images/console/requestmonitor/serverapidata.png) - -#### 指标类型 -![](/images/console/requestmonitor/serverapiindexdata.png) - -|指标类型|描述| -| :----------- | :-------------------------------- | -|获取 token|通过 RESTful API 实现获取管理员权限 token 的功能。| -|用户体系集成|通过 RESTful API 实现用户的注册、获取、修改、删除等管理功能。| -|文件上传下载|通过 RESTful API 实现语音和图片等文件的上传和下载功能。| -|发送消息|通过 RESTful API 实现发送消息功能。| -|群组管理|通过 RESTful API 实现群组创建、删除等管理功能。| -|聊天室管理|通过 RESTful API 实现聊天室创建、删除等管理功能。| -|用户属性|通过 RESTful API 实现用户属性设置、删除等管理功能。| - -#### 指标 - -![](/images/console/requestmonitor/serverapiindex.png) - -|指标|说明| -| :----------- | :-------------------------------- | -|请求次数|服务器端 RESTful API 的总请求次数。| -|1s/3s/5s 请求成功率|服务器端 RESTful API 在 1s/3s/5s 成功的请求次数 ÷ 总请求次数 × 100%。| -|平均时延|服务器端 RESTful API 请求的总延时 ÷ 总请求次数。| - -为了更直观的呈现数据,不同指标采用了不同的图表形式,具体说明如下: - -|指标|图| -| :----------- | :-------------------------------- | -|请求次数|折线图。| -|1s/3s/5s 请求成功率|折线图。| -|平均时延|热力图,其中横坐标为时间,纵坐标为时延分桶。方块颜色越深,对应时间范围内的请求次数越高。| - diff --git a/docs/product/security_best_practices.md b/docs/product/security_best_practices.md deleted file mode 100644 index a73c3df5..00000000 --- a/docs/product/security_best_practices.md +++ /dev/null @@ -1,45 +0,0 @@ -# 环信即时通讯 IM 安全最佳实践 - - - -安全合规对于即时通讯技术至关重要,为了提供安全可靠的云服务,环信即时通讯 IM 遵循不同国家、地区和行业的合规要求。环信即时通讯 IM 采用多种安全措施,防御即时通讯场景中的常见攻击。本文介绍环信即时通讯 IM 采用的一些安全最佳实践以及为开发者提供的安全工具。 - -环信用户隐私协议见:[环信用户隐私协议](https://www.easemob.com/protocol)。 -| 安全措施 | 默认启用 | 建议场景 | -|:-------------|:---------|:--------------------------------------------------| -| 数据中心隔离 | 是 | 所有即时通讯场景。 | -| Token 鉴权 | 是 | 所有即时通讯应用都必须使用用户身份的 token 进行鉴权。 | -| 数据传输加密 | 是 | 所有即时通讯场景。 | -| 数据存储加密 | 是 | 所有即时通讯场景。 | - -## 数据中心隔离 - -为了满足不同国家和地区的法律和规定,环信即时通讯 IM 支持服务区域隔离,以保证指定区域内的用户隐私数据不跨境。 - -环信即时通讯 IM 在如下区域设立数据中心,数据中心支持区域访问: - -| 数据中心 | 地点 | 服务区域 | -|:---------|:---------------|:---------| -| 新加坡 | 新加坡 | 东南亚 | -| 中国大陆 | 北京 | 中国大陆 | -| 欧洲 | 法兰克福,德国 | 欧洲 | -| 北美 | 弗吉尼亚,美国 | 北美 | - -要使用环信即时通讯 IM,你需要指定一个数据中心。选择数据中心后,对消息服务器的 RESTful 请求和 SDK API 请求都将指向对应的数据中心,你的业务数据也存储在该数据中心。国内的应用只能使用国内的数据中心,支持全球接入,而且数据中心一旦选择将无法更改。即时通讯服务不支持跨服务区的数据迁移。 - -## Token 鉴权 - -环信即时通讯 IM 使用 token 进行最终用户身份验证。Token 是一个访问密钥,开发者可以设置 token 的有效期。它由应用后端生成,包含环信即时通讯 IM 项目的 App ID、项目 APP 证书、用户 ID 等重要信息。它允许最终用户在用户通过应用程序正确验证后访问环信即时通讯 IM 服务。 - -## 数据传输和存储 - -用户和环信即时通讯 IM 服务器的通信进行了传输加密,比如:环信即时通讯 IM 私有传输协议,Transport Layer Security (TLS) 和 Web Socket Secure (WSS)。使用环信即时通讯 IM 产生的用户数据和消息将存储在指定的区域的数据中心。我们仅在为您提供服务期间保留您的信息,保留时间不超过满足相关使用目的所必须的时间。 - -| 数据类型 | 数据分类 | 存储时间 | -|:-----------------------------------------|:---------|:--------------------------------------------------------------------------------------| -| Console 注册数据 | 客户信息 | 直至客户删除账号或服务停用 6 个月。 | -| 消息(包括历史消息、漫游消息、离线消息) | 用户信息 | 消息的云存储时长与套餐版本相关,详见[产品价格](/product/pricing.html#套餐包功能详情)。 | -| 消息附件 | 用户信息 | 7 天。 | -| 消息回调 | 用户信息 | 3 天。 | -| 用户资料托管 | 用户信息 | 直到客户删除或服务停用 6 个月。 | -| 监控数据 | 运营数据 | 7 天。 | \ No newline at end of file diff --git a/docs/product/solution_common/group_@.md b/docs/product/solution_common/group_@.md deleted file mode 100644 index c91c543a..00000000 --- a/docs/product/solution_common/group_@.md +++ /dev/null @@ -1,268 +0,0 @@ -# 群组 @ 消息 - -群组 @ 消息指在群组聊天中,用户可以 @ 单个、多个或所有成员,发送消息。群组中的每个成员均可使用 @ 功能,而且可以 @ 群所有成员。 - -:::tip -目前,该功能只支持文本消息和表情。 -::: - -例如,该功能的 UI 实现如下图所示: - -1. 在输入框输入 "@" 字符后,选择要 @ 的群成员。 -2. 选择群成员后,返回聊天界面,编辑消息,然后发送。 -3. 如果有消息 @ 我,会收到会话更新,例如,“Somebody@You”。 -4. 打开会话页面,查看消息。 - -- Android/iOS 的 UI 实现示例图: - -![img](/images/product/solution_common/group_mention/group_@_mobile.png) - -- Web 的 UI 实现示例图: - -![img](/images/product/solution_common/group_mention/group_@_web.png) - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 SDK 初始化,详见各端快速开始,例如[Android 端](/document/android/quickstart.html)。 -- 了解即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 - -## 实现过程 - -在群组中,@ 某人发送消息与发送普通消息没有区别,只是被 @ 的用户在 UI 上显示会有不同。该功能可以通过扩展消息实现: - -1. 发送方将要 @ 的用户的用户 ID 通过扩展字段添加到消息,并将消息发送到群组。 -2. 群组成员收到消息时,检查对应的扩展字段是否存在。若存在,检查当前登录的用户 ID 是否包含在扩展字段中。 -3. 若包含,需要对被 @ 的用户在 UI 上进行特殊处理,显示出相应的提示信息,如“[Somebody@You]”。若不包含,表明用户没有被 @,则 UI 无需处理。 - -群组 @ 消息的扩展数据结构如下: - -- @ 单个或多个群组成员:"em_at_list": [user1, user2, user3] -- @ 群全体成员:"em_at_list":"All" - -### 发送消息 - -发送方 @ 用户发送消息的过程如下示例代码所示。 - -#### Android 代码 - -::: tabs#code - -@tab Java - -```java -JSONArray atUserList = new JSONArray(); -atUserList.put("@User1"); -atUserList.put("@User2"); -EMMessage msg = EMMessage.createTextSendMessage("@userId 你好", conversationID); -msg.setChatType(EMMessage.ChatType.GroupChat); -// @ 指定用户的消息构造如下。 -msg.setAttribute("em_at_list",atUserList); -// 如果要 @ 所有人,ext 可以设置为 ["em_at_list": "ALL"]。 -//msg.setAttribute("em_at_list","ALL"); -EMClient.getInstance().chatManager().sendMessage(msg); - -``` - -@tab Kotlin - -```kotlin - val atUserList = JSONArray() - atUserList.put("@User1") - atUserList.put("@User2") - val msg = EMMessage.createTextSendMessage("@userId 你好", conversationID) - msg.chatType = EMMessage.ChatType.GroupChat - // @ 指定用户的消息构造如下。 - msg.setAttribute("em_at_list", atUserList) - // 如果要 @ 所有人,ext 可以设置为 ["em_at_list": "ALL"]。 - //msg.setAttribute("em_at_list","ALL"); - EMClient.getInstance().chatManager().sendMessage(msg) - -``` - -::: - -#### iOS/Web 代码 - -::: tabs#code - -@tab iOS - -```swift -let textBody = EMTextMessageBody(text: "@userId1 你好") -// @ 指定用户的消息构造如下。如果要 @ 所有人,ext 可以设置为 ["em_at_list": "All"]。 -let msg = EMMessage(conversationID: "groupId", body: textBody, ext: ["em_at_list": ["userId1"]]) -// 指定聊天类型为群组。 -msg.chatType = .groupChat -// 发送消息 -EMClient.shared().chatManager?.send(msg, progress: nil, completion: { msg, err in - if err == nil { - print("send success") - } -}) -``` - -@tab Web - -```javascript -const message = chatSDK.message.create({ - to: "userId", - chatType: "groupChat", - type: "txt", - msg: "hello", - ext: { - em_at_list: "ALL" || ["user1", "user2"], - }, -}); - -client.send(message); -``` - -::: - -### 接收消息 - -接收方收到消息时,通过解析消息扩展字段 `ext`,检查消息是否 @ 了自己,过程如下。 - -#### Android 代码 - -::: tabs#code - -@tab Java - -```java -private void handleMentionedMessage(EMMessage messages) { - try { - String groupId = msg.getTo(); - JSONArray jsonArray = msg.getJSONArrayAttribute("em_at_list"); - for(int i = 0; i < jsonArray.length(); i++){ - String username = jsonArray.getString(i); - if(EMClient.getInstance().getCurrentUser().equals(username)){ - // 消息 @ 自己,需要更新 UI。 - } - } - - } - catch (Exception e1) { - //确认是否是 @ 所有人 - String usernameStr = msg.getStringAttribute("em_at_list", null); - if(usernameStr != null){ - String s = usernameStr.toUpperCase(); - if(s.equals("ALL")){ - // 消息 @ 所有人,需要更新 UI。 - } - } - } -} - - @Override - public void onMessageReceived(List messages) { - super.onMessageReceived(messages); - for (EMMessage message : messages) { - if (message.getChatType() == EMMessage.ChatType.GroupChat && message.getType()== EMMessage.Type.TXT){ - handleMentionedMessage(message) - } - } - } - -``` - -@tab Kotlin - -```kotlin - private fun handleMentionedMessage(messages: EMMessage) { - try { - val groupId: String = messages.to - val jsonArray: JSONArray = messages.getJSONArrayAttribute("em_at_list") - for (i in 0 until jsonArray.length()) { - val username = jsonArray.getString(i) - if (EMClient.getInstance().currentUser == username) { - // 消息 @ 自己,需要更新 UI。 - } - } - } catch (e1: java.lang.Exception) { - //确认是否是 @ 所有人 - val usernameStr: String = messages.getStringAttribute("em_at_list", null) - val s = usernameStr.uppercase(Locale.getDefault()) - if (s == "ALL") { - // 消息 @ 所有人,需要更新 UI。 - } - } - } - - override fun onMessageReceived(messages: MutableList?) { - super.onMessageReceived(messages); - messages?.forEach { - if (it.chatType == EMMessage.ChatType.GroupChat && it.type == EMMessage.Type.TXT){ - handleMentionedMessage(it) - } - } - } - -``` - -::: - -#### iOS/Web 代码 - -::: tabs#code - -@tab iOS - -```swift -func handleMentionedMessage(_ message: EMChatMessage) { - let atListInfo = message.ext?["em_at_list"] - if let atListInfo = atListInfo as? String, - atListInfo.lowercased() == "all" { - // 消息 @ 所有人,需要更新 UI。 - } - if let atListInfo = atListInfo as? [String], - let currentUserId = EMClient.shared().currentUsername, - atListInfo.contains(currentUserId) { - // 消息 @ 自己,需要更新 UI。 - } -} -func messagesDidReceive(_ aMessages: [EMChatMessage]) { - for msg in aMessages { - if msg.chatType == .groupChat, - msg.body.type == .text { - handleMentionedMessage(msg) - } - } -} -``` - -@tab Web - -```javascript -receiveMessage(message){ - let mentionList = message?.ext?.em_at_list; - // 收到文本消息 - if (mentionList && message.from !== client.user && message.type === 'txt') { - // 消息 @ 所有人或包含自己时,需要更新 UI。 - if (mentionList === "ALL" || mentionList.includes(client.user)) { - } - } -} - -``` - -::: - -## 常见问题 - -1. Q:@ 群所有人时为何发消息失败? - - A:可能是 `ALL` 的拼写错误,比较时可兼容处理先统一转为小写或者大写。 - -2. Q:@ 多人与 @ 所有人有什么区别? - - A:设置 `ext` 时,若 @ 单个、多个群成员,字段的值为要 @ 的用户的用户 ID 数组;@ 所有人时,字段值为 `ALL` 字符串。 - - - - - - - diff --git a/docs/product/solution_common/message_quote.md b/docs/product/solution_common/message_quote.md deleted file mode 100644 index 87ec72aa..00000000 --- a/docs/product/solution_common/message_quote.md +++ /dev/null @@ -1,361 +0,0 @@ -# 消息引用 - -消息引用是指用户可以引用一条已发送的消息。消息引用可以帮助用户回复特定的消息,或强调特定的信息。 - -除了透传消息,各类发送成功的消息均支持该功能,发送失败的消息不支持该功能。 - -对引用的消息进行回复时,你可以发送各种类型(除透传消息外)的消息。 - -:::tip -消息引用时,回复消息的长度为默认的消息长度限制,即消息内容和扩展字段的总和不超过 5 KB。 -::: - -1. Android/iOS 端各类型的消息引用的 UI 展示示例如下表所示: - -| 消息类型 | 原消息存在 | 原消息不存在 | -| :--------- | :----- | :------- | -| 文本消息 | ![img](/images/product/solution_common/message_reply/text_normal_mobile.png) | ![img](/images/product/solution_common/message_reply/text_no_mobile.png) | -| 图片消息 | ![img](/images/product/solution_common/message_reply/image_normal_mobile.png) | ![img](/images/product/solution_common/message_reply/image_no_mobile.png)| -| 语音消息 | ![img](/images/product/solution_common/message_reply/voice_normal_mobile.png)| ![img](/images/product/solution_common/message_reply/voice_no_mobile.png)| -| 视频消息 | ![img](/images/product/solution_common/message_reply/video_normal_mobile.png)| ![img](/images/product/solution_common/message_reply/video_no_mobile.png)| -| 文件消息 | ![img](/images/product/solution_common/message_reply/file_normal_mobile.png)| ![img](/images/product/solution_common/message_reply/file_no_mobile.png)| -| 名片消息 | ![img](/images/product/solution_common/message_reply/card_normal_mobile.png)| ![img](/images/product/solution_common/message_reply/card_no_mobile.png)| -| 合并消息 | ![img](/images/product/solution_common/message_reply/combine_normal_mobile.png)| ![img](/images/product/solution_common/message_reply/combine_no_mobile.png)| - -2. Web 端各类型的消息引用的 UI 展示示例如下表所示: - -| 消息类型 | 原消息存在 | 原消息不存在 | -| :--------- | :----- | :------- | -| 文本消息 | ![img](/images/product/solution_common/message_reply/text_normal_web.png) | ![img](/images/product/solution_common/message_reply/text_no_web.png) | -| 图片消息 | ![img](/images/product/solution_common/message_reply/image_normal_web.png) | ![img](/images/product/solution_common/message_reply/image_no_web.png)| -| 语音消息 | ![img](/images/product/solution_common/message_reply/voice_normal_web.png)| ![img](/images/product/solution_common/message_reply/voice_no_web.png)| -| 视频消息 | ![img](/images/product/solution_common/message_reply/video_normal_web.png)| ![img](/images/product/solution_common/message_reply/video_no_web.png)| -| 文件消息 | ![img](/images/product/solution_common/message_reply/file_normal_web.png)| ![img](/images/product/solution_common/message_reply/file_no_web.png)| -| 名片消息 | ![img](/images/product/solution_common/message_reply/card_normal_web.png)| ![img](/images/product/solution_common/message_reply/card_no_web.png)| -| 合并消息 | ![img](/images/product/solution_common/message_reply/combine_normal_web.png)| ![img](/images/product/solution_common/message_reply/combine_no_web.png)| - - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 SDK 初始化,详见各端 [快速开始](/document/android/quickstart.html)。 -- 了解即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 - -## 实现过程 - -为展示原消息的引用,需要在发送消息时,将原消息的信息传入新消息的拓展字段中。 - -以下为扩展字段的数据结构的示例: - -``` -"msgQuote": { - "msgID": 原消息的 ID,字符串类型。 - "msgPreview": 本地找不到原消息时的默认文本展示,字符串类型。 - "msgSender": 原消息的发送方的用户 ID,字符串类型。 - "msgType": 原消息类型,字符串类型。 -} -``` - -在消息列表中展示时,可从新消息的拓展字段中提取上述 JSON 信息,拼接展示 "${msgSender}: ${messageAbstract}"。 - -如需支持点击展示引用消息的区域,跳转至被引用的原消息。可根据上述 JSON 中的 `msgID` 字段,在消息列表中找到该消息进行跳转。 - -如果被引用消息已经删除,可以提示 **引用内容不存在**。 - -### 发送引用的消息 - -以回复文本消息为例,发送引用消息的过程如下: - -#### Android 代码 - -::: tabs#code - -@tab Java - -```java - -EMMessage msg = EMMessage.createTextSendMessage("hi", conversationId); - JSONObject jsonObject = new JSONObject(); - try { - jsonObject.put("msgID","quoted messageId"); - jsonObject.put("msgPreview","quoted message text"); - jsonObject.put("msgSender","quoted message senderId"); - jsonObject.put("msgType","txt"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - msg.setAttribute("msgQuote",jsonObject); - EMClient.getInstance().chatManager().sendMessage(msg); - - -``` - -@tab Kotlin - -```kotlin - - val msg = EMMessage.createTextSendMessage("hi", conversationId) - val jsonObject = JSONObject() - try { - jsonObject.put("msgID", "quoted messageId") - jsonObject.put("msgPreview", "quoted message text") - jsonObject.put("msgSender", "quoted message senderId") - jsonObject.put("msgType", "txt") - } catch (e: JSONException) { - throw RuntimeException(e) - } - msg.setAttribute("msgQuote", jsonObject) - EMClient.getInstance().chatManager().sendMessage(msg) - -``` - -::: - -#### iOS/Web 代码 - -::: tabs#code - -@tab iOS - -```swift -let textBody = EMTextMessageBody(text: "hi") - let ext = ["msgQuote": [ - "msgID": <#quoted messageId#> - "msgPreview": <#quoted message text#> - "msgSender": <#quoted message senderId#> - "msgType": "txt" - ] - ] - let message = EMChatMessage(conversationID: "userId", body: textBody, ext: ext) - EMClient.shared().chatManager?.send(message, progress: nil, completion: { msg, err in - - }) -``` - -@tab Web - -```javascript -sendMessage(message){ - // 若引用消息存在,则将该消息到要发送的消息扩展中。 - if ( - repliedMessage != null && - message.type != 'read' && - message.type != 'delivery' && - message.type != 'channel' && - message.type != 'cmd' - ){ - let ext = message.ext || {}; - let msgPreview = ''; - switch (repliedMessage.type) { - case 'txt': - msgPreview = repliedMessage.msg; - break; - case 'img': - msgPreview = '[Image]'; - break; - case 'audio': - msgPreview = '[Voice]'; - break; - case 'video': - msgPreview = '[Video]'; - break; - case 'file': - msgPreview = '[File]'; - break; - case 'custom': - msgPreview = '[Custom]'; - break; - default: - msgPreview = '[unknown]'; - break; - } - ext.msgQuote = { - msgID: repliedMessage.mid || repliedMessage.id, - msgPreview: msgPreview, - msgSender: repliedMessage.from, - msgType: repliedMessage.type, - }; - message.ext = ext; - } - - client.send(message) -} -``` -::: - -### 接收方解析收到的消息 - -接收方收到消息时,通过解析 `ext`,检查消息是否是引用消息。 - -#### Android 代码 - -::: tabs#code - -@tab Java - -```java -private void handleQuotedMessage(EMMessage message) { - if(message.ext() != null && message.ext().containsKey("msgQuote")) { - String msgQuote = message.getStringAttribute("msgQuote",""); - JSONObject jsonObject = null; - try { - if (!TextUtils.isEmpty(msgQuote)){ - try { - jsonObject = new JSONObject(msgQuote); - } catch (JSONException e) { - e.printStackTrace(); - } - }else { - jsonObject = message.getJSONObjectAttribute("msgQuote"); - } - } catch (ChatException e) { - EMLog.e(TAG, "error message: "+e.getMessage()); - } - - if(jsonObject != null){ - try { - // 读取 msgQuote 中的源消息信息 - String quoteMsgID = jsonObject.getString("msgID"); - String quoteSender = jsonObject.getString("msgSender"); - String quoteType = jsonObject.getString("msgType"); - String quoteContent = jsonObject.getString("msgPreview"); - //获取引用消息数据 更新 UI - } catch (JSONException e) { - e.printStackTrace(); - } - } -} - -@Override - public void onMessageReceived(List messages) { - super.onMessageReceived(messages); - for (EMMessage message : messages) { - handleQuotedMessage(message) - } - } -``` - -@tab Kotlin - -```kotlin - private fun handleMentionedMessage(message: EMMessage) { - message.ext()?.let { - if (it.containsKey("msgQuote")){ - val msgQuote = message.getStringAttribute("msgQuote","") - var jsonObject:JSONObject? = null - try { - if (!msgQuote.isNullOrEmpty()){ - try { - jsonObject = JSONObject(msgQuote) - }catch (e:JSONException){ - e.printStackTrace(); - } - }else{ - jsonObject = message.getJSONObjectAttribute("msgQuote") - } - }catch (e:HyphenateException){ - EMLog.e(TAG, "error message: "+e.getMessage()); - } - jsonObject?.let { - try { - // 读取 msgQuote 中的源消息信息 - val quoteMsgID = jsonObject.getString("msgID") - val quoteSender = jsonObject.getString("msgSender") - val quoteType = jsonObject.getString("msgType") - val quoteContent = jsonObject.getString("msgPreview") - //获取引用消息数据 更新 UI - }catch (e:JSONException){ - e.printStackTrace(); - } - } - } - } - } - - override fun onMessageReceived(messages: MutableList?) { - super.onMessageReceived(messages); - messages?.forEach { - handleMentionedMessage(it) - } - } - -``` - -::: - -#### iOS/Web 代码 - -::: tabs#code - -@tab iOS - -```swift - func handleQuotedMessage(_ message: EMChatMessage) { - if let ext = message.ext { - if let quotedInfo = ext["msgQuote"] as? [String: AnyObject] { - // 读取 msgQuote 中的源消息信息 - if let quotedMessageId = quotedInfo["msgID"] as? String, - let msgPreview = quotedInfo["msgPreview"] as? String, - let msgSender = quotedInfo["msgSender"] as? String, - let msgType = quotedInfo["msgType"] as? String { - // 消息引用了其他消息,需要更新 UI - } - } - } - } -func messagesDidReceive(_ aMessages: [EMChatMessage]) { - for msg in aMessages { - handleQuotedMessage(msg) - } -} -``` - -@tab Web - -```javascript - -receiveMessage(message){ - let msgQuote = message.ext.msgQuote; - if(msgQuote){ - // 找到被引用的消息 - const quotedMessage = messages.filter(msg => { - return msg.mid === msgQuote.msgID || msg.id === msgQuote.msgID; - }) - - if (quotedMessage[0]) { - // 找到被引用消息的 dom 节点 - const messageDom = document.getElementById(quotedMessage[0].id); - } - } -} -// 点击引用的消息回滚到被引用消息的位置,并高亮显示。 -const scrollToMsg = () => { - messageDom?.scrollIntoView({ behavior: 'smooth' }); - messageDom?.classList.add('reply-message-twinkle'); - - setTimeout(() => { - messageDom?.classList.remove('reply-message-twinkle'); - }, 1500); - }; -``` -::: - - -## 常见问题 - -1. Q: 被引用消息不存在时,如何显示? - A: 可以显示 `msgPreview` 内容,也可以显示**引用内容不存在**。 - -2. Q: 对于 Android/iOS 端,跳转到被引用消息时,如果被引用消息加载到当前消息的条数太多,怎么办? - A: 这种情况下,将当前消息与被引用的消息之间的所有消息都展示到 UI 会导致内存占用太多,你需要设置一个加载消息数量的阈值,超过该阈值就不再跳转。 - - - - - - - - - - diff --git a/docs/product/solution_common/migrate_to_easemob.md b/docs/product/solution_common/migrate_to_easemob.md deleted file mode 100644 index 5a52cb23..00000000 --- a/docs/product/solution_common/migrate_to_easemob.md +++ /dev/null @@ -1,119 +0,0 @@ -# 平滑迁移 - - - -环信多年来一直在致力于提供稳定,安全的即时通讯服务,在开发者中积累了良好的口碑。如果您希望接入环信的IM服务,但正在使用自研或友商提供的即时通讯服务,这篇文档正是针对这一场景,介绍了一套迁移方案,这套方案已经成功为多家客户实现了平滑迁移。 - -用户也可以通过环信提供的存量迁移工具、平滑迁移 Relay-server 来完成迁移。这两个工具已经完成了绝大部分迁移工作,用户只需要关注感兴趣部分即可。 - -## 基本概念 - -- 应用服务器:客户方自有,服务于客户应用业务功能的服务器。 -- 环信 IM 服务器:环信提供的即时通讯服务器。 -- 原 IM 服务器:用户原先实现 IM 功能的服务器,可以是自有服务器或友商提供的云服务。 -- 老应用:与原 IM 服务器连接的老版本 app。 -- 新应用:迁移后与环信服务器连接的新版本 app。 - -## 迁移准备 - -进行 IM 平滑迁移,需要提前进行以下准备: - -注册环信账号,创建应用并开通 IM 功能。 - -## 强制升级迁移 - -如果新应用上架,可以强制所有的老应用升级至新应用,可以使用强制迁移方式。此方式下不存在新老应用的兼容问题。 主要工作如下: - -### 1. 导入用户体系至环信服务器 - -用户体系包含两部分内容: - -一是用户在环信的 ID 和密码; - -二是用户之间的好友关系。如果你的应用服务器保存了用户的好友关系,则不需要在环信服务器中保存该部分。 - -环信只是即时通讯的消息通道。环信本身不提供除用户 ID 和密码外的其他资料。比如说,你的 APP 是一个婚恋交友 APP,那么你的 APP 用户的头像、昵称、身高、体重、三围、电话号码等信息是保存在你自己的 APP 业务服务器上,这些信息不需要告诉环信。 - -[用户管理 REST API](/document/server-side/account_system.html) 提供了一个创建环信账号的 REST 方法。这个方法很简单,只需要提供账号 ID 和密码 2 个参数,就可以创建一个环信账号。对一个已经上线,已经有很多现有用户的 APP 来说,要集成环信,只需要写一个脚本,循环调用创建环信用户的 REST 方法。 - -### 2. 导入单聊和群聊信息至环信服务器 - -需要将客户业务中的单聊和群聊信息从旧的 IM 服务器中导入环信服务器,例如群建对应的群组,并加入对应的用户至群组中。 - -对应的 REST API 如下: - -[REST 导入单聊消息](/document/server-side/message_import.html#导入单聊消息) - -[REST 导入群聊消息](/document/server-side/message_import.html#导入群聊消息) - -### 3. 存量迁移工具 - -环信为了用户更好的迁移数据(用户体系、群组),提供了存量迁移工具。用户只需要在此基础上简单二次开发,向工具中集成需要迁移的数据,即可使用。如有需要,请联系销售。 - -### 4. 导入用户设备上的历史消息 - -在新版本 App 中集成环信 IM SDK 后,如果需要继续使用用户设备上的旧消息,可以使用导入消息的 API,构建环信消息结构,导入环信 SDK 中的消息数据库。 - -具体可以参考: - -[Android 导入消息至本地数据库](/document/android/message_import_insert.html#批量导入消息到数据库) - -[iOS 导入消息至本地数据库](/document/ios/message_import_insert.html#批量导入消息到数据库) - -## 新老兼容的平滑迁移 - -新老兼容迁移的方式,是指在迁移过程中,环信 IM 服务器和原IM服务器同时提供服务,新应用和旧应用并存,支持新旧应用互通。待用户逐步更新至新应用,旧应用逐步无人使用后,原 IM 服务器停止服务。 - -平滑迁移需要原服务支持并开通服务端消息路由功能(用户 A 给用户 B 发消息的过程中,服务器支持通过消息回调(也经常称为:callback,WebHook 或者消息抄送服务)的模式将消息转发给开发者提供的服务器 URL 地址)。 - -平滑迁移的主要内容如下: - -### 1. 导入用户体系和群组信息 - -与强制升级的步骤相同,请参考强制升级中的说明。 - -### 2. 利用消息路由功能完成新旧版本之间的消息互通 - -如果需要老用户和新用户互相通信,老用户(需要注册一个环信的 ID 和老用户关联)可以发消息到自己的服务端,服务端来调环信的 REST 发送消息接口给新用户发送消息,新用户收到对方的消息,回复消息给老用户,先走到环信服务器,环信服务器调用旁路接口(自己服务器提供的一个接口)到自己服务器上,再由自己服务器的聊天系统发消息给客户端。 - -注:在这里需要注意的是,新老用户之间发送文字容易处理,但是如果发送的消息里面带有附件情况,需要 User Server 提供可以上传下载附件的旁路接口,并且需要音视频转换的方法,目前环信客户端这边音频格式统一为 AMR 格式。 - -![新老用户通信过程](/images/product/message.png) - -#### 消息回调的开通 - -消息回调为增值服务,需要联系商务开通,具体步骤可以参考如下文档: - -[消息回调](/document/server-side/callback.html) - -#### 消息格式的转换 - -环信 IM 服务的消息可能与旧的 IM 服务的消息格式稍有差别,需要用户自己实现格式的转换。环信的消息支持文本消息,图片消息,语音消息,视频消息,位置消息等不同的类型,具体请参考[发送各类型单聊消息的 API 中的请求 body](/document/server-side/message_single.html#发送文本消息)。 - -用户也可以参考 Relay-server 此部分的实现。 - -#### 语音消息的格式 - -环信的移动端语音消息为 amr 格式,其中 iOS 端是录制后转换为 amr 格式,web 端是由服务器端在下载语音消息时转换为 mp3 格式。如果旧的 IM 服务器支持的格式不符,需要适当的进行转换。 - -用户也可以参考 Relay-server 此部分的实现。 - -### 3. 平滑迁移 Relay-server - -环信为了更好帮助客户从云信、融云平台迁移到环信,环信开发平滑迁移服务(Relay-server),来完成 “利用消息路由功能完成新旧版本之间的消息互通”。 Relay-server 提供了大多数的消息转换,如:文字、语音、视频、图片、文件、位置等消息。 客户只需要进行简单开发即可高度适配客户特有需求,如客户的自定义消息转换等。 如有需要,请联系销售。 - -### 其他迁移问题 - -#### 推送问题 - -为保证消息的到达率,环信 IM 服务支持各平台的推送通道,同时支持免打扰功能(即设定时间不收推送时,或者不接收某个群组的推送),如果旧的 IM 服务中有类似功能需要迁移的话,可以使用服务器的 API 提前设置,也可以使用 SDK 的 API 根据需要设置。 - -[免打扰设置](/document/server-side/push.html#设置离线推送) - -#### 聊天室迁移 - -聊天室一般是临时使用的场景中加入退出,因此建议在迁移时通过后台 API 创建聊天室,用户在需要时加入退出即可。 - -#### 音视频功能迁移 - -音视频功能涉及到信令和媒体流协议的不同,暂无法平滑迁移,建议一次性迁移至环信服务器。 \ No newline at end of file diff --git a/docs/product/solution_common/typing_indication.md b/docs/product/solution_common/typing_indication.md deleted file mode 100644 index 6f32c9c6..00000000 --- a/docs/product/solution_common/typing_indication.md +++ /dev/null @@ -1,393 +0,0 @@ -# 通过透传消息实现输入指示器 - -输入指示器显示其他用户何时输入消息。通过该功能,用户之间可进行有效沟通,增加了用户对聊天应用中交互的期待感。 - -## 前提条件 - -开始前,请确保满足以下条件: - -- 完成 SDK 初始化,详见各端快速开始,例如 [Android 端](/document/android/quickstart.html)。 -- 了解即时通讯 IM 的使用限制,详见 [使用限制](/product/limitation.html)。 - -## 实现过程 - -你可以通过透传消息实现输入指示器。下图为输入指示器的工作原理。 - -![img](/images/common/typing_indicator.png) - -监听用户 A 的输入状态。一旦有文本输入,通过透传消息将输入状态发送给用户 B,用户 B 收到该消息,了解到用户 A 正在输入文本。 - -- 用户 A 向用户 B 发送消息,通知其开始输入文本。 -- 收到消息后,如果用户 B 与用户 A 的聊天页面处于打开状态,则显示用户 A 的输入指示器。 -- 如果用户 B 在几秒后未收到用户 A 的输入,则自动取消输入指示器。 - -:::tip -用户 A 可根据需要设置透传消息发送间隔。 -::: - -### 发送输入状态的透传消息 - -以下示例代码展示如何发送输入状态的透传消息。 - -::: tabs#code - -@tab Android - -```java -//发送表示正在输入的透传消息 -private static final String MSG_TYPING_BEGIN = "TypingBegin"; -private long previousChangedTimeStamp; - -private void textChange() { - long currentTimestamp = System.currentTimeMillis(); - if(currentTimestamp - previousChangedTimeStamp > 5) { - sendBeginTyping(); - previousChangedTimeStamp = currentTimestamp; - } -} - -private void sendBeginTyping() { - EMMessage beginMsg = EMMessage.createSendMessage(EMMessage.Type.CMD); - EMCmdMessageBody body = new EMCmdMessageBody(MSG_TYPING_BEGIN); - // 将该透传消息只发送给在线用户 - body.deliverOnlineOnly(true); - beginMsg.addBody(body); - beginMsg.setTo(toChatUsername); - EMClient.getInstance().chatManager().sendMessage(beginMsg); -} -``` - -@tab iOS - -```objectivec -//发送表示正在输入的透传消息 -#define MSG_TYPING_BEGIN @"TypingBegin" - -- (void)textViewDidChange:(UITextView *)textView -{ - long long currentTimestamp = [self getCurrentTimestamp]; - // 5 秒内不能重复发送消息 - if ((currentTimestamp - _previousChangedTimeStamp) > 5) { - // 发送开始输入的透传消息 - [self _sendBeginTyping]; - _previousChangedTimeStamp = currentTimestamp; - } -} - -- (void)_sendBeginTyping -{ - EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:MSG_TYPING_BEGIN]; - body.isDeliverOnlineOnly = YES; - EMChatMessage *message = [[EMChatMessage alloc] initWithConversationID:conversationId body:body ext:nil]; - [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil]; -} -``` - -@tab Web/Applet - -```typescript -let previousChangedTimeStamp = 0; -// 监听输入状态的变化 -const onInputChange = function () { - const currentTimestamp = new Date().getTime(); - if (currentTimestamp - previousChangedTimeStamp > 5000) { - sendBeginTyping(); - previousChangedTimeStamp = currentTimestamp; - } -}; - -// 创建输入状态消息并发送 -const sendBeginTyping = function () { - const option = { - // 会话类型:单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。 - chatType: "singleChat", - // 消息类型。 - type: "cmd", - // 消息接收方:单聊为对方用户 ID,群聊和聊天室分别为群组 ID 和聊天室 ID。 - to: "", - // 用户自定义操作。 - action: "TypingBegin", - }; - const typingMessage = message.create(option); - - connection - .send(typingMessage) - .then(() => { - console.log("success"); - }) - .catch((e) => { - console.log("fail"); - }); -}; -``` - -@tab Flutter - -```dart -//发送表示正在输入的透传消息 -final String msgTypingBegin = "TypingBegin"; - -void textChange() { - int currentTimestamp = getCurrentTimestamp(); - if (currentTimestamp - _previousChangedTimeStamp > 5) { - _sendBeginTyping(); - _previousChangedTimeStamp = currentTimestamp; - } -} - -void _sendBeginTyping() async { - var msg = EMMessage.createCmdSendMessage( - targetId: conversationId, - action: msgTypingBegin, - // 将该透传消息只发送给在线用户 - deliverOnlineOnly: true, - ); - msg.chatType = ChatType.Chat; - EMClient.getInstance.chatManager.sendMessage(msg); -} - -``` - -@tab React Native - -```typescript -// 发送自己在输入状态中的命令消息 -const action = "inputting"; -const msg = ChatMessage.createCmdMessage(targetId, action, chatType); -EMClient.getInstance().chatManager().sendMessage(msg, callback).then().catch(); -``` - -@tab Unity/Windows - -```csharp -//发送表示正在输入的透传消息 -string msgTypingBegin = "TypingBegin"; - -void textChange() { - int currentTimestamp = getCurrentTimestamp(); - if (currentTimestamp - _previousChangedTimeStamp > 5) { - _sendBeginTyping(); - _previousChangedTimeStamp = currentTimestamp; - } -} - -void _sendBeginTyping() { - var msg = Message.CreateCmdSendMessage( - username: conversationId, - action: msgTypingBegin, - deliverOnlineOnly: true, - ); - msg.chatType = MessageType.Chat; - SDKClient.getInstance.chatManager.sendMessage(msg); -} - -``` -::: - -### 接收和解析输入状态的透传消息 - -以下示例代码展示如何接收和解析输入状态的透传消息。 - -::: tabs#code - -@tab Android - -```java -private static final int TYPING_SHOW_TIME = 10000; -private static final int MSG_TYPING_END = 1; -private Handler typingHandler; - -private void initTypingHandler() { - typingHandler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(@NonNull Message msg) { - switch (msg.what) { - case MSG_TYPING_END : - cancelTimer(); - break; - } - } - }; -} - -@Override -public void onCmdMessageReceived(List messages) { - for (EMMessage msg : messages) { - if(!TextUtils.equals(msg.conversationId(), currentConversationId)) { - return; - } - EMCmdMessageBody body = (EMCmdMessageBody) msg.getBody(); - if(TextUtils.equals(body.action(), MSG_TYPING_BEGIN)) { - // 这里需更新 UI,显示“对方正在输入” - beginTimer(); - } - } -} - -private void beginTimer() { - if(typingHandler != null) { - typingHandler.removeMessages(MSG_TYPING_END); - typingHandler.sendEmptyMessageDelayed(MSG_TYPING_END, TYPING_SHOW_TIME); - } -} - -private void cancelTimer() { - // 这里需更新 UI,不再显示“对方正在输入” - if(typingHandler != null) { - typingHandler.removeCallbacksAndMessages(null); - } -} - -``` - -@tab iOS - -```objectivec -#define TypingTimerCountNum 10 -- (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages -{ - NSString *conId = self.currentConversation.conversationId; - for (EMChatMessage *message in aCmdMessages) { - if (![conId isEqualToString:message.conversationId]) { - continue; - } - EMCmdMessageBody *body = (EMCmdMessageBody *)message.body; - // 收到正在输入的透传消息 - if ([body.action isEqualToString:MSG_TYPING_BEGIN]) { - if (_receiveTypingCountDownNum == 0) { - [self startReceiveTypingTimer]; - }else { - _receiveTypingCountDownNum = TypingTimerCountNum; - } - } - - } -} - -- (void)startReceiveTypingTimer { - [self stopReceiveTypingTimer]; - _receiveTypingCountDownNum = TypingTimerCountNum; - _receiveTypingTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(startReceiveCountDown) userInfo:nil repeats:YES]; - - [[NSRunLoop currentRunLoop] addTimer:_receiveTypingTimer forMode:UITrackingRunLoopMode]; - [_receiveTypingTimer fire]; - // 这里需更新 UI,显示“对方正在输入” -} - -- (void)startReceiveCountDown -{ - if (_receiveTypingCountDownNum == 0) { - [self stopReceiveTypingTimer]; - // 这里需更新 UI,不再显示“对方正在输入” - - return; - } - _receiveTypingCountDownNum--; -} - -- (void)stopReceiveTypingTimer { - _receiveTypingCountDownNum = 0; - if (_receiveTypingTimer) { - [_receiveTypingTimer invalidate]; - _receiveTypingTimer = nil; - } -} -``` - -@tab Web/Applet - -```typescript -// 设置状态监听器 -let timer; -conn.addEventHandler("message", { - onCmdMessage: (msg) => { - console.log("onCmdMessage", msg); - if (msg.action === "TypingBegin") { - // 这里需更新 UI,显示“对方正在输入” - beginTimer(); - } - }, -}); - -const beginTimer = () => { - timer && clearTimeout(timer); - timer = setTimeout(() => { - // 这里需更新 UI,不再显示“对方正在输入” - }, 5000); -}; -``` - -@tab Flutter - -```dart -final int typingTime = 10; -Timer? _timer; - -void onCmdMessagesReceived(List list) { - for (var msg in list) { - if (msg.conversationId != currentConversationId) { - continue; - } - EMCmdMessageBody body = msg.body as EMCmdMessageBody; - if (body.action == msgTypingBegin) { - // 这里需更新 UI,显示“对方正在输入” - beginTimer(); - } - } -} - -void beginTimer() { - _timer = Timer.periodic( - Duration(seconds: typingTime), - (timer) { - // 这里需更新 UI,显示“对方正在输入” - cancelTimer(); - }, - ); -} - -void cancelTimer() { - _timer?.cancel(); -} -``` - -@tab React Native - -```typescript -let listener = new (class implements ChatMessageEventListener { - onCmdMessagesReceived(messages: ChatMessage[]): void { - // 收到命令消息 - for (msg of messages) { - // 过略消息 - if (msg.body.action === "inputting") { - // todo: 界面显示正在输入中的状态 - } - } - } -})(); -ChatClient.getInstance().chatManager.addMessageListener(listener); -``` - -@tab Unity/Windows - -```csharp -int typingTime = 10; - -void OnCmdMessagesReceived(List list) { - for (var msg in list) { - if (msg.ConversationId != currentConversationId) { - continue; - } - MessageBody.CmdBody body = msg.Body as MessageBody.CmdBody; - if (body.Action == msgTypingBegin) { - // 这里需更新 UI,显示“对方正在输入” - - Timer timer = new Timer((state) => - { - // 这里需更新 UI,不再显示“对方正在输入” - }, null, typingTime, Timeout.Infinite); - } - } -} -``` -::: diff --git a/docs/product/uc_deploy.md b/docs/product/uc_deploy.md deleted file mode 100644 index 2c5d6697..00000000 --- a/docs/product/uc_deploy.md +++ /dev/null @@ -1,109 +0,0 @@ -# 私有化部署流程说明 - - - -## 1、服务说明 - -​为满足私有化客户试用体验、二次开发验证及正式使用等需求,我们致力于提供一种高效、安全、灵活的自动化安装部署方案,无论部署在本地服务器、云端或者信创等任意环境,都可以使用到一致的高质量服务。 - -同时为了客户能够更便捷地开始使用产品,整套自动化部署流程非常简单,已提供相应安装介质及统一申请授权流程,只需提供使用需求信息,即可快速获取授权,具体流程可见文中详解,期待满足您的私有化部署需求,为您提供卓越的服务体验。 - -## 2、部署流程 - -![img](/images/privitization/deploy_flowchart.png) - -### 2.1 下载部署资料 - -信息安全已成为国家重要安全战略,各行业客户对业务环境、功能及数据存储的安全性要求越来越高。需要将功能完备的即时通讯服务部署到内网物理服务器集群、公有云以及私有云等多种平台,请根据实际使用场景选择安装包及部署手册,下载后请按照部署手册要求准备环境并实施部署。 - -| 安装包名称 | 适配环境要求 | 下载安装包 | 下载部署手册 | -| :------------ | :----- | :------- | :------------------------------------------- | -| 环信私有化即时通讯服务安装包(单机版) | 操作系统:Linux、ubuntu 20 及以上、centos 7 及以上 CPU 架构:X86(优先推荐)、ARM | [立即下载](https://zim-private.oss-cn-beijing.aliyuncs.com/zim/ZIM-23.1.5.x86_64-license/20230912/ZIM-23.1.5.x86_64.all.tar) | [立即下载](https://zim-private.oss-cn-beijing.aliyuncs.com/zim/ZIM-23.1.5.x86_64-license/%E7%8E%AF%E4%BF%A1%E7%A7%81%E6%9C%89%E5%8C%96IM%E9%83%A8%E7%BD%B2%E6%96%87%E6%A1%A320230516.pdf) | - -### 2.2 申请授权 - -当服务部署完成后,处于未授权状态,需要根据当前服务机器码申请授权。 - -1. 获取机器码 - -使用部署手册中提供的环信控制台信息(包括登录地址、登录账号)进行登录,登录成功后,在环信控制台首页获取机器码标识。 - -![img](/images/privitization/deploy_machine_code.png) - -2. 申请授权码 license - -无论是正式版还是试用版服务,均可通过填写机器码信息申请授权,[申请授权地址](https://get-license.easemob.com/)。 - --正式版:支持设置服务用户量及使用时间,申请后商务经理一日内反馈提供; - --试用版:固定服务用户量及使用时间,申请后立即生成,可进行试用体验; - -3. 配置授权码 license - -获取授权码后,登录环信控制台首页,点击 **激活 License** 按钮,在弹窗中填写授权码信息,点击 **确定** 生效。 - -![img](/images/privitization/deploy_auth_code.png) - -### 2.3 验证服务 - -当服务配置完成后,可直接使用 Web IM-Demo 进行各类消息及功能测试,在浏览器中输入地址:**http://IP:12005**,即可访问 Web IM-Demo。 - -1. 验证授权: - -通过注册用户账号验证服务是否被授权,如果注册成功,则已开通用户授权;如果注册失败,客户端提示错误码 “无license”,此时需要登录环信控制台检查 license 配置是否生效。 - -2. 验证功能: - -启动两个 Web IM-Demo ,可以完成添加好友、创建会话、发送消息等功能验证。 - -## 3、集成测试 - -当服务端验证完成后,可通过下载需要的客户端 SDK 及 Demo 进行集成体验。环信客户端 SDK 已对 IM 核心服务完成封装, 通过调用 SDK API 接口,即可快速获得消息收发 、会话管理 、群组 、好友 、聊天室等功能。目前客户端 SDK 已覆盖 Windows 、Linux 、MacOS 、Android 、iOS 、Web 、小程序等多种平台,服务器端 SDK 已覆盖 Java 、PHP 等平台,[下载私有化客户端 SDK](http://doc.easemob.com/product/uc_private.html#私有化-sdk-下载)。 - -示例一:以 Android 端 demo 体验为例 - -下载并安装 demo 后,打开应用服务器设置页面,配置以下信息: - -- 使用自定义服务器:开启 -- appkey:easemob-demo#zim -- 使用私有化服务器:开启 -- IM server:私有化服务器主机地址 -- IM Port:msync 端口,6717 -- Rest server 地址&端口:Rest API 地址 - -![img](/images/privitization/deploy_android_custom_server.png) - -示例二:以iOS端 demo体验为例 - -下载并安装demo后,打开应用服务器设置页面,配置以下信息 - -- 使用自定义服务器:开启 -- appkey:easemob-demo#zim -- Specify Server:开启 -- IM server:私有化服务器主机地址 -- IM Port:msync端口,6717 -- Rest server 地址&端口:Rest api地址 - -![img](/images/privitization/deploy_ios_custom_server.png) - -## 4、联系我们 - -如果您准备使用或正在使用私有化即时通讯服务,有任何疑问和建议,欢迎您添加方案负责人或提交工单与我们交流 - -1. 联系方案负责人 - -微信 扫一扫,添加方案负责人: - -![img](/images/privitization/deploy_wechat_code.png) - -2. 提交工单 - -登录[环信通讯云管理后台](https://console.easemob.com/user/login),点击“服务支持-工单支持”,点击“进入工单系统” - -![img](/images/privitization/deploy_ticket.png) - -3. Geek 社区 - -[Geek开发者社区](http://www.imgeek.org/)里面的环信专区/环信技术交流板块提供了很多常见问题的讨论和解答,您也可以发帖提问,我们的技术和服务人员会尽力解答您的疑问! - -- 技术咨询邮箱:[support@easemob.com](mailto:support@easemob.com) \ No newline at end of file diff --git a/docs/product/uc_overview.md b/docs/product/uc_overview.md deleted file mode 100644 index f0c426aa..00000000 --- a/docs/product/uc_overview.md +++ /dev/null @@ -1,87 +0,0 @@ -# 环信通 - - - -[下载环信通 >>](#下载体验)。 - -## 产品介绍 - -企业智能办公场景解决方案(简称:环信通)是环信基于 10 年以上的行业服务经验,深挖企事业单位办公场景需求,全力打造的安全统一通讯平台,具有低代码、跨平台、易扩展、灵活部署、定制化、全面信创适配等特性,帮助企事业单位快速搭建一站式智慧办公平台,提升沟通与业务协同效率,实现安全高效的数字化转型。 - -![img](/images/privitization/uc_architecture.png) - -## 产品功能 - -#### 即时通讯 - -多样化场景功能,为沟通创造无限可能 - - 单聊、千人群聊 - - 全消息类型 - - 多终端消息同步 - - 已读未读状态 - -#### 音视频会议 - -稳定通话质量,随时随地便捷开会 - - 1080P 高清码流 - - 远程桌面共享 - - 会议控制 - - 成员管理 - -#### 企业通讯录 - -精细化企业通讯录,成员架构灵活配置 - - 组织架构配置 - - 成员批量导入 - - 星标好友 - - 群组管理 - -#### 协同办公 - -任务日程高效协同,重要事项不遗漏 - - 日程管理 - - 会议日程 - - 系统推送 - -#### 信息安全 - -全流程加密策略,信息安全多重保障 - - 水印、阅后即焚 - - 敏感词管理 - - 通讯安全 - - 客户端安全 - -#### 开放平台 - -高度开放接口,快速满足个性化需求 - - H5 应用嵌入 - - 开放 REST 接口 - - 全平台 SDK - - 定制化开发 - -## 全面信创适配 - -![img](/images/privitization/uc_client.png) - -## 产品规格 - -环信通支持私有云、混合云及服务器等多种环境自动部署,既可满足千人以下专有单服务器部署,亦可弹性扩容满足万人以上集群部署。 - - - 单机版:适用于 5000 人以下使用,服务配置(8 核 32GB 内存 200GB 以上硬盘) - - 集群版:适用于万人以上使用,服务可随业务扩展弹性扩容,服务配置(至少3台 8核 32GB 内存 200GB以上硬盘) - -## 下载体验 - -环信通支持全端(Linux、Windows、macOS、Android 和 iOS)覆盖,为帮助开发者及企业客户更好的体验产品功能,各端应用可通过以下链接下载。您也可以拨打400-622-1776 联系我们,环信会安排专业的顾问,为贵单位提供定制、安全、可扩展的企业协同办公解决方案。 - -| 应用端 | 下载地址 | -| :------------------- | :----- | -| Windows | [下载体验](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/win/%E7%8E%AF%E4%BF%A1%E9%80%9A.2.x.exe) | -| Linux | [下载体验](http://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/linux/easemoboa_2.0.3-build0110_amd64.deb)
当前应用适配 Ubuntu 18-Ubuntu 20,如需其他版本请联系商务。| -| macOS | [下载体验](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/mac/%E7%8E%AF%E4%BF%A1%E9%80%9A.2.x.dmg) | -| Android | [下载体验](https://download-sdk.oss-cn-beijing.aliyuncs.com/mp/poc/android/app-release.apk) | -| iOS | [下载体验](https://testflight.apple.com/join/j1ssvXm0)| - -**授权开源** - -通过签署授权协议,环信可提供环信通源码以帮助合作伙伴或最终客户降低开发成本,加速项目进程。请联系程先生 (Tel:17611319060)。 \ No newline at end of file diff --git a/docs/product/uc_private.md b/docs/product/uc_private.md deleted file mode 100644 index 03f0c8ad..00000000 --- a/docs/product/uc_private.md +++ /dev/null @@ -1,255 +0,0 @@ -# 私有化即时通讯 - - - -[下载私有化 SDK >>](#私有化-sdk-下载)。 - -环信即时通讯私有化服务是基于 IM 核心技术实现的可私有化部署解决方案。本方案可适配内网物理服务器集群、公有云以及私有云等任意部署环境,提供功能完备、安全可靠、易于扩展的即时通讯平台。整体通讯平台架构主要由三部分组成,分别为客户端、服务端、Web 控制台。 - - - **客户端**:采用 SDK 形式,对核心通信模块进行封装,提供场景功能接口,覆盖多种平台(包括:Android、iOS、Web、小程序、 Windows/Mac OS、Linux),支持快速集成终端用户应用。 - - **服务端**:采用 Java 和 Erlang 语言编写,可支持用户高并发连接和系统动态调配,高效处理用户长连接相关的服务和用户管理、推送等无状态服务。同时提供服务端REST API 和 Java Server SDK 接口,便于完成即时通讯软件中服务的控制、数据的转发存储工作。 - - **Web 控制台**:是基于 B/S 模式的可视化操作平台,可支持开通与配置应用功能,查询各类 IM 服务情况,管理与维护用户体系(增、删、改、查),满足系统管理员、开发者等多种业务角色使用需求,提升业务集成与运营管理效率。 - -## 私有化服务优势 - -### 部署多样化 - -环信即时通讯系统支持 Linux 裸系统、容器化等多种部署方式。不仅可以提供更灵活、更便捷、更稳定的平台性能,同时容器化部署可实现自动部署,具备服务自动发现、服务自动负载均衡等特点。 - -### 高可用 - -环信即时通讯系统具备高可用特性,当系统内某一个节点或主机出现宕机后,该故障节点上的所有服务会自动转移到其他节点上而不会引发服务中断,保障系统可用性。 - -### 易扩展 - -环信即时通讯系统服务架构支持弹性扩展,系统内所有资源可在各节点之间实现灵活调度,当 CPU、内存等计算资源利用率较高时,可通过横向添加 node 实现平滑扩容。 -### 安全性 - -环信即时通讯系统实现通讯全流程安全加密,支持客户端敏感信息加密存储、服务器密钥权限管理、消息传输过程私有协议加密以及用户信息隐私保护等措施。 - -### 国产化 - -环信即时通讯系统严格遵循国家法律法规和技术标准规范,积极响应国内自主可控、安全可控要求,从IT基础设置、操作系统、数据库等方面进行国产化升级,满足信创环境部署要求。 - -## 私有化 SDK 下载 - -环信客户端及服务端SDK已对IM核心服务完成封装,通过调用SDK API接口,即可快速获得消息收发、会话管理、群组、好友、聊天室等功能,目前客户端 SDK 已覆盖 Windows、Linux、MacOS、Android、iOS、Web、小程序等多种平台,服务器端 SDK 已覆盖 Java、PHP 等平台,各端 SDK 下载及开发指南如下所示。 - -:::tip -1. 若要体验环信即时通讯 IM 的功能,可下载[公有云 Demo](https://www.easemob.com/download/demo)。 -2. 若要体验私有化 Demo,需下载下表中对应平台的 Demo,然后在登录页面的**服务器配置**区域完成配置。 -3. 若要集成,需选择下表中的 SDK 及 Demo 版本,按照下表中**开发指南**一列的文档配置私有化环境信息。 -::: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

SDK 类型

-
-

平台

-
-

版本号

-
-

下载地址

-
-

开发指南

-
-

 

-

客户端 SDK

-
-

Android

-
-

3.9.1

-
-

下载 SDK 及 Demo 体验 Demo

-
-

查看

-
-

Web

-
-

4.0.4

-
-

• React: 下载 SDK 及 Demo 体验 Demo
• Vue 2: 下载 SDK 及 Demo
• Vue 3: 下载 SDK 及 Demo

-
-

查看

-
-

iOS

-
-

3.9.1

-
-

下载 SDK 及 Demo 

-
-

查看

-
-

Windows(C++)

-
-

3.9.1

-
-

下载 SDK 及 Demo

-
-

查看

-
-

Windows(C#)

-
-

1.0.2

-
-

下载 SDK

-
-

查看

-
-

Linux

-
-

3.1.0

-
-

下载 SDK

-
-

查看

-
-

Electron

-
-

3.8.4

-
-

下载 SDK

-
-

查看

-
-

uni-app

-
-

4.0.4

-
-

下载 SDK 及 Demo

-
-

查看

-
-

小程序

-
-

4.0.4

-
-

下载 SDK 及 Demo

-
-

查看

-
-

Unity

-
-

3.9.0

-
-

下载 SDK

-
 
-

Flutter

-
-

3.9.0+2

-
-

下载 SDK

-
-

查看

-
-

 

-

服务端 SDK

-
-

Java

-
-

0.6.3

-
-

下载 SDK

-
-

查看

-
-

PHP

-
-

0.1.0

-
-

下载 SDK

-
-

查看

-
- diff --git a/docs/product/voiceroom/client_implementation_android.md b/docs/product/voiceroom/client_implementation_android.md deleted file mode 100644 index 3b38eccc..00000000 --- a/docs/product/voiceroom/client_implementation_android.md +++ /dev/null @@ -1,307 +0,0 @@ -# 客户端实现 - -## 场景描述 - -本文介绍如何通过环信 IM SDK 和 Agora RTC SDK 在 Android 项目里实现语聊房的主要功能。 - -## 技术原理 - -### 房间管理 - -语聊房 Demo 内部依赖环信 IM 聊天室与 Agora RTC 频道。 - -以下为房间管理流程图。 - -![img](/images/voiceroom/voiceroom_mgmt.png) - -Demo 中创建或加入语聊房的流程如下: - -1. 启动 Demo。在 `application` 中调用 `ChatroomConfigManager.getInstance.initRoomConfig` 方法初始化环信 IM SDK。 -2. 利用手机号和验证码登录环信 IM。 -3. 登录 IM 后,通过 App Server 创建语聊房。成功后,房间创建者成为房主自动加入语聊房并跳转至语聊房页面。 -4. 进入房间后加入环信 IM 聊天室和 RTC 频道。 - 首先检查是否具有 RTC 所需权限。获取到所需权限并得到授权后执行 `onPermissionGrant` 方法,调用 `initSdkJoin` 进行 RTC 初始化(初始化 RTC 加入频道需要的参数由登录时由 App Server 返回)。 -5. 检查是否成功加入环信 IM 聊天室 和 RTC 频道。 - - 若成功加入,房主可以发送本地音频流和消息,观众可以发消息。 - - 若未成功加入,则退出房间,返回房间列表页面。 -6. 退出房间。 - -语聊房的用户角色如下表所示: - -| 角色 | 描述 | -| :--- | :-------------------------- | -| 房主 | 语聊房创建者,在 Demo 中占用 0 号麦位,不可修改。房主可以接收、发送音频流和消息。 | -| 主播 | 进入语聊房后,通过上麦成为主播,可以接收、发送音频流和消息。 | -| 观众 | 进入语聊房后,未进行上麦的成员只能发送和接收消息。申请上麦或房主邀请上麦成功后,可以和主播实时互动。 | - -语聊房的相关操作如下表所示: - -| 操作 | 描述 | -| :--------- | :---------------------------------------- | -| 创建房间 | 房主调用 App Server 的 `ChatroomHttpManager.getInstance.createRoom` 方法创建语聊房,创建成功后自动加入语聊房。房主自动上麦成为主播,更新房间内麦位信息。
创建语聊房前,房主调用 `ChatroomConfigManager.getInstance.initRoomConfig` 方法初始化环信 IM SDK。 | -| 加入房间 | 用户调用 App Server 的 `ChatroomHttpManager.getInstance.joinRoom` 方法加入语聊房。加入语聊房前,首先调用 `ChatroomHttpManager.getInstance.loginWithToken` 方法登录环信 IM,然后调用 `initSdkJoin` 进行 RTC 初始化。 | -| 离开房间 | 观众或主播可调用 `ChatroomHttpManager.getInstance.leaveRoom` 方法离开语聊房。房主离开语聊房,语聊房对象自动销毁,其他成员自动离开语聊房。 | -| 发送音频流 | 观众或主播可调用 `RtcRoomController.get.joinChannel` 方法发送音频流。 | -| 发送消息 | 语聊房内的用户可调用 `ChatroomHelper.getInstance.sendTextMsg` 或者 `CustomMsgHelper.getInstance.sendCustomMsg` 方法发送消息。观众也可以调用 `ChatroomHelper.getInstance.sendGiftMsg` 方法发送礼物消息。 | - -### 麦位管理 - -麦位管理流程图如下所示: - -![img](/images/voiceroom/voiceroom_seatmgmt.png) - -麦位相关操作如下表所示: - -| 操作 | 描述 | -| :----------- | :------------------ | -| 邀请上麦 | 房主调用 `ChatroomHttpManager.getInstance.invitationMic` 方法邀请观众上麦。观众收到 `ChatroomListener.receiveInviteSite` 回调,选择是否上麦。
- 观众调用 `ChatroomHttpManager.getInstance.agreeMicInvitation` 方法同意上麦,成为主播,房间内所有用户会收到 `ChatroomListener.roomAttributesDidUpdated`,更新房间内麦位信息。
- 观众调用 `ChatroomHttpManager.getInstance.rejectMicInvitation` 方法拒绝上麦,房主收到 `ChatroomListener receiveInviteRefusedSite` 回调。 | -| 申请上麦 | 观众调用 `ChatroomHttpManager.getInstance.submitMic` 方法向房主申请上麦。房主收到 `ChatroomListener.receiveApplySite` 回调,选择同意或拒绝申请。
- 房主调用 `ChatroomHttpManager.getInstance.applySubmitMic` 方法同意上麦申请,房间内所有用户会收到 `ChatroomListener roomAttributesDidUpdated` 回调,更新房间内麦位信息。
- 房主调用 `ChatroomHttpManager.getInstance.rejectSubmitMic` 方法拒绝上麦申请,申请者收到 `ChatroomListener receiveDeclineApply` 回调。 | -| 撤销上麦申请 | 观众向房主申请上麦后,可以调用 `ChatroomHttpManager.getInstance.cancelSubmitMic` 方法撤销上麦申请。 | -| 下麦 | 下麦分为主动和被动两种方式:
- 主动下麦:主播可调用 `ChatroomHttpManager.getInstance.leaveMic` 方法下麦成为观众。
- 被踢下麦:房主调用 `ChatroomHttpManager.getInstance.kickMic` 方法对所在麦位主播发起下麦指令。
对于这两种下麦方式,房间内所有用户都会收到 `ChatroomListener.roomAttributesDidUpdated` 回调,更新房间内麦位信息。 | -| 开麦 | 房主和主播调用 `ChatroomHttpManager.getInstance.cancelCloseMic` 方法开麦,发言时房间内其他用户可听到。房间内所有用户会收到 `ChatroomListener roomAttributesDidUpdated` 回调,更新麦位状态。 | -| 关麦 | 房主和主播调用 `ChatroomHttpManager.getInstance.closeMic` 方法关麦,关闭自己的声音。房间内所有用户会收到 `ChatroomListener roomAttributesDidUpdated` 回调,更新麦位状态。 | -| 禁麦 | 房主调用 `ChatroomHttpManager.getInstance.muteMic` 方法禁麦,不允许指定连麦主播发言,该主播的音频流将关闭。包括主播在内的房间内所有用户会收到 `ChatroomListener roomAttributesDidUpdated` 回调,更新麦位状态。 | -| 解禁麦位 | 房主调用 `ChatroomHttpManager.getInstance.cancelMuteMic` 方法解禁麦位,恢复连麦主播的发言权限,即恢复该麦位主播的音频流。包括主播在内的房间内所有用户会收到 `ChatroomListener.roomAttributesDidUpdated` 回调,更新麦位状态。 | -| 锁麦 | 房主调用 `ChatroomHttpManager.getInstance.lockMic` 方法锁麦,不允许任何人上该麦位。锁麦时,若该麦位有主播连麦,该主播收到 `ChatroomListener.roomAttributesDidUpdated` 回调被踢下来成为普通观众。房间内所有用户也会收到该回调,更新房间内麦位信息。 | -| 解锁麦位 | 房主调用 `ChatroomHttpManager.getInstance.cancelLockMic` 方法解锁麦位,使指定麦位恢复空闲状态,观众可申请该麦位上麦。房间内所有用户会收到 `ChatroomListener roomAttributesDidUpdated` 回调,更新麦位状态。 | -| 换麦 | 主播调用 `ChatroomHttpManager.getInstance.exChangeMic` 方法换麦,即从当前麦位切换到另一个空闲麦位。包括主播在内的房间内所有用户会收到 `ChatroomListener roomAttributesDidUpdated` 回调,更新房间内麦位信息。 | - -### 发送单向消息 - -![img](/images/voiceroom/voiceroom_oneway_msg.png) - -邀请用户上麦的流程如下: - -1. 房主调用 RESTFul API 邀请用户上麦。 -2. App Server 收到邀请消息后,利用房主角色向用户发送该消息。 -3. 用户同意邀请后调用 RESTful API 上麦。 -4. App Server 设置聊天室属性通知房间全员刷新房间设置。 - -用户申请上麦的流程如下: - -1. 用户调用 RESTful 接口申请上麦。 -2. App Server 收到上麦申请消息后以用户角色向房主发送该消息。 -3. 房主收到上麦申请后调用 RESTful API 同意上麦。 -4. App Server 设置聊天室属性通知房间全员刷新房间设置。 - -### 发送礼物消息 - -![img](/images/voiceroom/voiceroom_gift_msg.png) - -发送礼物消息的流程如下: - -1. 用户 A 发送礼物详情到 App Server。 -2. App Server 统计礼物信息后对用户 A 返回响应。 -3. SDK 将礼物消息发送到语聊房。 - -## 前提条件 - -- Android Studio 3.0 或以上版本; -- Android SDK API 等级 23 或以上; -- Android 6.0 或以上版本的设备; -- 有效的环信 IM 开发者账号和 App key,详见[环信即时通讯云控制台](https://console.easemob.com/user/login); -- [有效的 Agora 项目,获取项目的 App ID 以及一个 RTC Token,实现语音通话](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_android_ng?platform=Android); -- 如果你的网络环境部署了防火墙,请联系环信技术支持设置白名单。 - -## 项目配置 - -| 产品 | SDK 下载 | 集成文档 | -| :------------------ | :------------------------ | :------------------------------------------------ | -| 环信即时通讯 IM SDK | 环信即时通讯 IM SDK 3.9.8 | [发送和接收消息](/document/android/message_send_receive.html) | -| Agora RTC SDK | Agora RTC SDK 4.0.1 | [实现音频通话](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_android_ng?platform=Android)| - -## 基础 API 参考 - -本节提供环信 IM SDK 和 Agora RTC SDK 的基本 API 参考。 - -### 初始设置 - -加入语聊房前,进行[环信 IM SDK 初始化](/document/android/quickstart.html#实现单聊)和 [Agora RTC 初始化](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_android_ng?platform=Android#处理-android-系统逻辑)设置。 - -### App Server 相关 - -以下表格为 App Server 的基础 API。 - -房间管理 API 如下表所示: - -| API | 实现功能 | -| :-------------------------------------------------- | :--------------------- | -| [`ChatroomHttpManager.getInstance.getRoomDetails`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 获取指定语聊房的信息。 | -| [`ChatroomHttpManager.getInstance.createRoom`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 创建房间。 | -| [`ChatroomHttpManager.getInstance.deleteRoom`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 根据房间 ID 删除房间。 | -| [`ChatroomHttpManager.getInstance.updateRoomInfo`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 修改语聊房信息。 | -| [`ChatroomHttpManager.getInstance.getRoomFromServer`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 获取房间列表。 | -| [`ChatroomHttpManager.getInstance.getRoomMembers`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 获取房间内的成员。 | -| [`ChatroomHttpManager.getInstance.joinRoom`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 加入房间。 | -| [`ChatroomHttpManager.getInstance.checkPassword`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 校验密码。 | -| [`ChatroomHttpManager.getInstance.leaveRoom`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 离开房间。 | -| [`ChatroomHttpManager.getInstance.kickRoomMember`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 踢出房间。 | - -麦位管理 API 如下表所示: - -| API | 实现功能 | -| :---------------------------------------------------- | :----------------- | -| [`ChatroomHttpManager.getInstance.getMicInfo`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 获取麦位信息。 | -| [`ChatroomHttpManager.getInstance.getApplyMicList`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 获取上麦申请列表。 | -| [`ChatroomHttpManager.getInstance.invitationMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 邀请上麦。 | -| [`ChatroomHttpManager.getInstance.agreeMicInvitation`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 用户同意上麦邀请。 | -| [`ChatroomHttpManager.getInstance.rejectMicInvitation`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 用户拒绝上麦邀请。 | -| [`ChatroomHttpManager.getInstance.submitMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 提交上麦申请。 | -| [`ChatroomHttpManager.getInstance.cancelSubmitMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 撤销上麦申请。 | -| [`ChatroomHttpManager.getInstance.rejectSubmitMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 拒绝上麦申请。 | -| [`ChatroomHttpManager.getInstance.applySubmitMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 同意上麦申请。 | -| [`ChatroomHttpManager.getInstance.closeMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 关麦。 | -| [`ChatroomHttpManager.getInstance.cancelCloseMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 开麦。 | -| [`ChatroomHttpManager.getInstance.leaveMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 主动下麦。 | -| [`ChatroomHttpManager.getInstance.muteMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 封禁指定麦位。 | -| [`ChatroomHttpManager.getInstance.cancelMuteMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 解禁指定麦位。 | -| [`ChatroomHttpManager.getInstance.exChangeMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 换麦。 | -| [`ChatroomHttpManager.getInstance.kickMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 踢用户下麦。 | -| [`ChatroomHttpManager.getInstance.lockMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 锁定麦位。 | -| [`ChatroomHttpManager.getInstance.cancelLockMic`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 解锁麦位。 | - -礼物榜单 API 如下表所示: - -| API | 实现功能 | -| :-------------------------------------------- | :----------------- | -| [`ChatroomHttpManager.getInstance.getGiftList`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 获取赠送礼物榜单。 | -| [`ChatroomHttpManager.getInstance.sendGift`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 赠送礼物。 | - -### Agora RTC 相关 - -| API | 实现功能 | -| :----------------------------------------------------------- | :---------------------- | -| [initializeAndJoinChannel](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_android_ng?platform=Android#实现语音通话逻辑) | 初始化 app 并加入频道。 | - -其他 API,详见[声网官网](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/java_ng/API/rtc_api_overview_ng.html)。 - -### Easemob IM SDK 相关 - -Easemob IM SDK 的 API 如下表所示: - -| API | 实现功能 | -| :--------------------------------------------- | :-------------- | -| [`EMClient.getInstance.init`](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_client.html#a739c181ecd146af520cde6076e4b4de4) | 初始化 IM SDK。 | -| [`EMClient.getInstance.chatManager.sendMessage`](http://sdkdocs.easemob.com/apidoc/android/chat3.0/classcom_1_1hyphenate_1_1chat_1_1_e_m_chat_manager.html#ad50be7183f088c415b9507bc7ce792e6) | 发送消息。 | - -### 语聊房监听 - - 初始化 SDK(ChatroomConfigManager.getInstance.initRoomConfig)时已注册了连接监听、消息监听、聊天室监听,可以实现 `ChatroomListener` 接口。 - -| API | 实现功能 | -| :----------------------------------------------------------- | :------------------------------------- | -| [`ChatroomHttpManager.getInstance.receiveTextMessage`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 收到普通文本消息。 | -| [`ChatroomHttpManager.getInstance.receiveGift`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 收到礼物消息。 | -| [`ChatroomHttpManager.getInstance.receiveApplySite`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 接收申请消息。 | -| [`ChatroomHttpManager.getInstance.receiveCancelApplySite`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 接收取消申请消息。 | -| [`ChatroomHttpManager.getInstance.receiveInviteSite`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 接收邀请消息。 | -| [`ChatroomHttpManager.getInstance.receiveInviteRefusedSite`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 接收拒绝邀请消息。 | -| [`ChatroomHttpManager.getInstance.receiveDeclineApply`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 接收拒绝申请消息。 | -| [`ChatroomHttpManager.getInstance.onMemberExited`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 用户离开房间。 | -| [`ChatroomHttpManager.getInstance.announcementChanged`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 聊天室公告更新。 | -| [`ChatroomHttpManager.getInstance.userBeKicked`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 聊天室成员被踢出房间。 | -| [`ChatroomHttpManager.getInstance.roomAttributesDidUpdated`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 聊天室属性变更。 | -| [`ChatroomHttpManager.getInstance.roomAttributesDidRemoved`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 聊天室属性移除。 | -| [`ChatroomHttpManager.getInstance.onTokenWillExpire`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | Token 即将过期。 | -| [`ChatroomHttpManager.getInstance.onTokenExpired`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | Token 已过期。 | -| [`ChatroomHttpManager.getInstance.receiveSystem`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 收到系统消息(目前用来实现成员加入)。 | -| [`ChatroomHttpManager.getInstance.voiceRoomUpdateRobotVolume`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 机器人音量更新。 | -| [`ChatroomHttpManager.getInstance.onRoomDestroyed`](https://github.com/apex-wang/voiceroom_demo_android/blob/dev/business/chatroom/src/main/java/com/easemob/chatroom/general/net/ChatroomHttpManager.java) | 聊天室被销毁。 | - -### 音频相关 - -主播调用以下方法设置音频流: - -| API | 实现功能 | -| :--------------- | :------------------- | -| [`setAudioProfile [2/2\]`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_setaudioprofile2) | 设置音频编码属性。 | -| [`muteLocalAudioStream`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_mutelocalaudiostream) | 主播可以关闭或开启本地麦克风。 | -| [`adjustRecordingSignalVolume`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_adjustrecordingsignalvolume) | 调节人声音量。 | - -### 附加功能 - -#### 最佳音效 - -设置最佳音效,示例代码如下: - -``` -annotation class SoundSelection { - companion object { - const val SocialChat = 0 //社交语聊 - - const val Karaoke = 1 //在线 K 歌 - - const val GamingBuddy = 2 //游戏陪玩 - - const val SoundCardHQ = 3 //专业主播 - } - } - - rtcEngine?.apply { - when (config.soundType) { - SoundSelection.SocialChat, SoundSelection.Karaoke -> { // 社交语聊,KTV - setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING) - setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY) - setAudioScenario(Constants.AUDIO_SCENARIO_GAME_STREAMING) - } - SoundSelection.GamingBuddy -> { // 游戏陪玩 - setChannelProfile(Constants.CHANNEL_PROFILE_COMMUNICATION) - } - else -> { //专业主播 - setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY) - setAudioScenario(Constants.AUDIO_SCENARIO_GAME_STREAMING) - setParameters("{\"che.audio.custom_payload_type\":73}") - setParameters("{\"che.audio.custom_bitrate\":128000}") - // setRecordingDeviceVolume(128) 4.0.1 上才支持 - setParameters("{\"che.audio.input_channels\":2}") - } - } - } -``` - -#### AI 降噪 - -AI 降噪插件使用声网人工智能噪声消除算法,能够让远程交流和面对面交谈一样实时。 - -可以开启或关闭 AI 降噪以及设置中级降噪和高级降噪。示例代码如下: - -``` -internal class AgoraRtcDeNoiseEngine : RtcBaseDeNoiseEngine() { - - override fun closeDeNoise(): Boolean { - engine?.apply { - setParameters("{\"che.audio.ains_mode\":0}") - setParameters("{\"che.audio.nsng.lowerBound\":80}") - setParameters("{\"che.audio.nsng.lowerMask\":50}") - setParameters("{\"che.audio.nsng.statisticalbound\":5}") - setParameters("{\"che.audio.nsng.finallowermask\":30}") - setParameters("{\"che.audio.nsng.enhfactorstastical\":200}") - } - return true - } - - override fun openMediumDeNoise(): Boolean { - engine?.apply { - setParameters("{\"che.audio.ains_mode\":2}") - setParameters("{\"che.audio.nsng.lowerBound\":80}") - setParameters("{\"che.audio.nsng.lowerMask\":50}") - setParameters("{\"che.audio.nsng.statisticalbound\":5}") - setParameters("{\"che.audio.nsng.finallowermask\":30}") - setParameters("{\"che.audio.nsng.enhfactorstastical\":200}") - } - return true - } - - override fun openHeightDeNoise(): Boolean { - engine?.apply { - setParameters("{\"che.audio.ains_mode\":2}") - setParameters("{\"che.audio.nsng.lowerBound\":10}") - setParameters("{\"che.audio.nsng.lowerMask\":10}") - setParameters("{\"che.audio.nsng.statisticalbound\":0}") - setParameters("{\"che.audio.nsng.finallowermask\":8}") - setParameters("{\"che.audio.nsng.enhfactorstastical\":200}") - } - return true - } -} -``` diff --git a/docs/product/voiceroom/client_implementation_ios.md b/docs/product/voiceroom/client_implementation_ios.md deleted file mode 100644 index 5fd64a39..00000000 --- a/docs/product/voiceroom/client_implementation_ios.md +++ /dev/null @@ -1,276 +0,0 @@ -# 客户端实现 - -## 场景描述 - -本文介绍如何通过环信 IM SDK 和 Agora Audio SDK 在你的 iOS 项目里实现语聊房的主要功能。 - -## 技术原理 - -### 房间管理 - -语聊房 SDK 内部依赖环信 IM 聊天室(Chatroom)与 Agora Audio 的音频房间(RTC Channel)。 - -语聊房内用户角色说明如下: - -| 角色 | 描述 | -| ---- | ------------------------------------------------------------ | -| 房主 | 语聊房创建者,在 Demo 中占用 0 号麦位,不可修改。房主可以接收、发送音频流。 | -| 主播 | 进入语聊房后,通过上麦成为主播,可以接收、发送音频流。 | -| 观众 | 进入语聊房后,接收音频流。申请上麦或房主邀请上麦后,可以和主播实时互动。 | - -以下为房间管理流程图。 - -![img](/images/voiceroom/voiceroom_mgmt.png) - -房间管理流程如下: - -1. 用户利用手机号和验证码登录环信 IM。 -2. 房主可创建语聊房,普通用户加入语聊房。 -3. 加入环信 IM 和 RTC 频道。 -4. 进入语聊房,检查是否成功加入环信 IM 和 RTC 频道。 - - 若成功加入,房主可以发送本地音频流和消息,观众可以发消息。 - - 若未成功加入,退出房间,返回房间列表页面。 -5. 退出房间。 - -房间相关操作如下表所示: - -| 操作 | 描述 | -| ---------- | ------------------------------------------------------------ | -| 创建房间 | 房主通过 App Server 创建语聊房,创建成功后自动加入语聊房。房主自动上麦成为主播,更新房间内麦位信息。加入语聊房前,调用 `VoiceRoomIMManager.configIM` 方法初始化环信 IM,调用 `ASRTCKit.getSharedInstance` 方法初始化 Agora Audio。 | -| 加入房间 | 用户可调用 `joinRoom` 方法加入语聊房。加入语聊房前,调用 `VoiceRoomIMManager.loginIM` 方法登录环信 IM,然后调用 `VoiceRoomIMManager.joinChatRoom` 和 `self.rtcKit.joinChannel` 方法加入聊天室和 RTC 频道,成功后再加入语聊房。 | -| 离开房间 | 观众或主播可调用 `leaveRoom()` 方法离开语聊房。房主离开语聊房,语聊房对象自动销毁,其他成员自动离开语聊房。 | -| 发送音频流 | 观众或主播可调用 `self.rtcKit.joinChannel` 方法发送音频流。 | -| 发送消息 | 语聊房内的用户可调用 `VoiceRoomIMManager.sendMessage` 或者 `VoiceRoomIMManager.sendCustomMessage` 方法发送消息。观众也可以调用 `VoiceRoomIMManager.sendGift` 方法发送礼物消息。 | - -### 麦位管理 - -以下为麦位管理流程图: - -![img](/images/voiceroom/voiceroom_seatmgmt.png) - -麦位相关操作如下所示: - -| 操作 | 描述 | -| -------- | ------------------------------------------------------------ | -| 邀请上麦 | 房主调用 `inviteUserToMic` RESTful API 邀请观众上麦。观众收到 `receiveInviteSite` 回调,选择是否同意上麦。
- 观众调用 `agreeInvite` RESTful API 同意上麦,成为主播,App Server 设置聊天室属性。同时,房间内所有用户会收到该观众连麦的回调 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate`,更新房间内麦位信息。 | -| 申请上麦 | 观众调用 `requestSpeak` 方法向房主申请上麦。房主收到 `VoiceRoomIMManager.receiveApplySite` 回调,选择同意或拒绝申请。
- 房主调用 `agreeUserApply` 方法同意上麦申请,申请者收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调并调用 `self.rtcKit.joinChannel` 方法成为主播。同时,房间内所有用户会收到该观众连麦的回调 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate`,并更新房间内麦位信息。
- 房主调用 `refuseApply` RESTful API 方法拒绝上麦申请。 | -| 下麦 | 下麦分为主动和被动两种方式:
- 主动下麦:主播可调用 `leaveMic` 方法下麦成为观众。
- 被踢下麦:房主调用 `kickOff` RESTful API 对主播发起下麦指令。该连麦主播收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,然后下麦成为观众。
对于这两种下麦方式,房间内所有用户都会收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,更新房间内麦位信息。 | -| 禁麦 | 房主调用 `muteMic` RESTful API 禁麦,不允许指定连麦主播发言,该主播的音频流将关闭。包括主播在内的房间内所有用户会收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,更新房间内麦位信息。 | -| 解禁麦位 | 房主调用 `unmuteMic` RESTful API 解禁麦位,恢复连麦主播的发言权限,即恢复该麦位主播的音频流。包括主播在内的房间内所有用户会收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,更新房间内麦位信息。 | -| 锁麦 | 房主调用 `lockMic` RESTful API 锁麦,不允许任何人上该麦位。锁麦时,若该麦位有主播连麦,该主播收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,被踢下来成为普通观众。房间内所有用户也会收到该回调,更新房间内麦位信息。 | -| 解锁麦位 | 房主调用 `unlockMic` RESTful API 解锁麦位,使指定麦位恢复空闲状态,观众可以在该麦位申请上麦。房间内所有用户会收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,更新房间内麦位信息。 | -| 换麦 | 主播可调用 `changeMic` 方法换麦,即从当前麦位切换到另一个空闲麦位。包括主播在内的房间内所有用户会收到 `VoiceRoomIMDelegate.chatroomAttributesDidUpdate` 回调,更新房间内麦位信息。 | - -### 发送单向消息流程图 - -![img](/images/voiceroom/voiceroom_oneway_msg.png) - -邀请用户上麦的流程如下: - -1. 房主调用 RESTFul API 邀请用户上麦。 -2. App Server 收到邀请消息后,利用房主角色向用户发送该消息。 -3. 用户同意邀请后调用 RESTful API 上麦。 -4. App Server 设置聊天室属性通知房间全员刷新房间设置。 - -用户申请上麦的流程如下: - -1. 用户调用 RESTful 接口申请上麦。 -2. App Server 收到上麦申请消息后以用户角色向房主发送该消息。 -3. 房主收到上麦申请后调用 RESTful API 同意上麦。 -4. App Server 设置聊天室属性通知房间全员刷新房间设置。 - -### 发送礼物消息流程图 - -![img](/images/voiceroom/voiceroom_gift_msg.png) - -发送礼物消息的流程如下: - -1. 用户 A 发送礼物详情到 App Server。 -2. App Server 统计礼物信息后对用户 A 返回响应。 -3. SDK 将礼物消息发送到语聊房。 - -## 前提条件 - -- Xcode 13.0 或以上版本。 -- CocoaPods。你可以参考 [CocoaPods 安装指南](https://guides.cocoapods.org/using/getting-started.html#getting-started) 安装。 -- iOS 13.0 或以上版本的设备。部分模拟机可能无法支持本项目的全部功能,所以推荐使用真机。 -- 有效的环信 IM 开发者账号和 App key,详见[环信即时通讯云控制台](https://console.easemob.com/user/login)。 -- [有效的 Agora 项目,获取项目的 App ID 以及一个 RTC Token,实现语音通话](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_ios_ng?platform=iOS)。 -- 如果你的网络环境部署了防火墙,请联系环信技术支持设置白名单。 - -## 项目配置 - -| 产品 | SDK 下载 | 集成文档 | -| ------------------- | ---------------------------------- | ------------------------------------------------------------ | -| 环信即时通讯 IM SDK | 环信即时通讯 IM SDK 3.9.8 或以上版本 | [发送、接收消息、聊天室属性 KV](/document/ios/message_send_receive.html) | -| Agora Audio SDK | 声网 RTM SDK 4.0.1 | [实现音频通话](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_ios_ng?platform=iOS) | - -## 基本 API 参考 - -本节提供环信 IM SDK 和 Agora Audio SDK 的基本 API 参考。 - -- [App Server API 文档](https://github.com/easemob/voiceroom_demo_ios/blob/dev/redoc-static.html.zip)。该文档为静态 HTML 页面,需下载后查看。 - -- [Demo 中的方法与 App Server API 之间的映射](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift)。 - -### 房间管理 API 列表 - -| API | 实现功能 | -| ------------------------------------------------------------ | ---------------------- | -| [VoiceRoomBusinessApi.fetchRoomInfo](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 获取指定语聊房的信息。 | -| [VoiceRoomBusinessApi.createRoom](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 创建房间。 | -| [VoiceRoomBusinessApi.deleteRoom](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 根据房间 ID 删除房间。 | -| [VoiceRoomBusinessApi.modifyRoomInfo](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 修改语聊房信息。 | -| [VoiceRoomBusinessApi.fetchRoomList](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 获取房间列表。 | -| [VoiceRoomBusinessApi.fetchRoomMembers](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 获取房间内的成员。 | -| [VoiceRoomBusinessApi.joinRoom](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 加入房间。 | -| [VoiceRoomBusinessApi.validatePassWord](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 校验密码。 | -| [VoiceRoomBusinessApi.leaveRoom](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 离开房间。 | -| [VoiceRoomBusinessApi.kickUser](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 踢出房间。 | - -### 麦位管理 API 列表 - -| API | 实现功能 | -| ------------------------------------------------------------ | ------------------ | -| [VoiceRoomBusinessApi.fetchMicsInfo](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 获取麦位信息。 | -| [VoiceRoomBusinessApi.fetchApplyMembers](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 获取上麦申请列表。 | -| [VoiceRoomBusinessApi.inviteUserToMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 邀请上麦。 | -| [VoiceRoomBusinessApi.agreeInvite](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 用户同意上麦邀请。 | -| [VoiceRoomBusinessApi.refuseInvite](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 用户拒绝上麦邀请。 | -| [VoiceRoomBusinessApi.submitApply](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 提交上麦申请。 | -| [VoiceRoomBusinessApi.cancelApply](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 撤销上麦申请。 | -| [VoiceRoomBusinessApi.refuseApply](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 拒绝上麦申请。 | -| [VoiceRoomBusinessApi.agreeApply](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 同意上麦申请。 | -| [VoiceRoomBusinessApi.closeMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 关麦。 | -| [VoiceRoomBusinessApi.cancelCloseMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 开麦。 | -| [VoiceRoomBusinessApi.leaveMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 主动下麦。 | -| [VoiceRoomBusinessApi.muteMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 封禁指定麦位。 | -| [VoiceRoomBusinessApi.unmuteMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 解禁指定麦位。 | -| [VoiceRoomBusinessApi.exchangeMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 换麦。 | -| [VoiceRoomBusinessApi.kickMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 踢用户下麦。 | -| [VoiceRoomBusinessApi.lockMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 锁定麦位。 | -| [VoiceRoomBusinessApi.unlockMic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 解锁麦位。 | - -麦位相关方法,详见 [VoiceRoomViewController+Mic](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Business/VoiceChat2.0/Controller/VoiceRoomViewController%2BMic.swift) 文件。 - -### 礼物榜单 API 列表 - -| API | 实现功能 | -| ------------------------------------------------------------ | ------------------ | -| [VoiceRoomBusinessApi.fetchGiftContribute](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 获取赠送礼物榜单。 | -| [VoiceRoomBusinessApi.giftTo](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomBusinessApi.swift) | 赠送礼物。 | - -### 对 HyphenateChat IM SDK 进行封装的类中的方法 - -| API | 实现功能 | -| ------------------------------------------------------------ | ------------------------------ | -| [VoiceRoomIMManager.configIM](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomIMManager.swift) | 初始化环信 IM。 | -| [VoiceRoomIMManager.loginIM](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomIMManager.swift) | 登录环信 IM。 | -| [VoiceRoomIMManager.addChatRoomListener](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomIMManager.swift) | 添加 IM 消息以及聊天室回调监听。 | -| [VoiceRoomIMManager.removeListener](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Common/Network/VoiceRoomIMManager.swift) | 移除 IM 消息以及聊天室回调监听。 | - -### Agora Audio iOS SDK 的 API 封装回调 - -| API | 实现功能 | -| ------------------------------------------------------------ | ----------------- | -| [AgoraRtcEngineKit.sharedEngine(withAppId: AgoraConfig.rtcId, delegate: nil)](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Compoment/AgoraRtcKit/ASRTCKit.swift) | 初始化 RTC。 | -| [ASRTCKit.joinVoicRoomWith](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Compoment/AgoraRtcKit/ASRTCKit.swift) | 加入 RTC 频道。 | -| [ASRTCKit.setClientRole](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Compoment/AgoraRtcKit/ASRTCKit.swift) | 设置 RTC 角色。 | -| [ASRTCKit.leaveChannel](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Compoment/AgoraRtcKit/ASRTCKit.swift) | 离开 RTC 频道。 | - -### 初始化设置 - -加入语聊房前,进行[环信 IM SDK 初始化](http://doc.easemob.com/document/android/quickstart.html#实现单聊)和 [Agora Audio 初始化](https://docportal.shengwang.cn/cn/voice-call-4.x/start_call_audio_ios_ng?platform=iOS#实现语音通话逻辑)设置。 - -### 加入/离开环信 IM 聊天室或者声网 RTC 频道 - -| API | 实现功能 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| [joinChatroom](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chatroom_manager-p.html#ac66d04fd0182c7499ed539c0ea610152) | 加入语聊房。房间内的观众会收到 `userDidJoinChatroom` 回调。用户加入语聊房后才能接收或发布音频流。 | -| [leaveChatroom](http://sdkdocs.easemob.com/apidoc/ios/chat3.0/protocol_i_e_m_chatroom_manager-p.html#ac66d04fd0182c7499ed539c0ea610152) | 离开语聊房。其他成员收到 `userDidLeaveChatroom` 回调。房主离开语聊房后,房间对象自动销毁,其他成员会自动离开语聊房。 | -| [joinChannelbyToken](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_irtcengine_joinchannel) | 加入 RTC 频道。用户加入语聊房后才能接收或发布音频流。房间内的观众会收到 `ASManagerDelegate.didRtcLocalUserJoinedOfUid` 回调。 | -| [leaveChannel](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_irtcengine_leavechannel) | 离开 RTC 频道。 | - -通过 App Server 加入或离开语聊房的方法的示例代码如下: - -```swift -// 加入语聊房 - func uploadStatus( status: Bool) { - guard let roomId = self.roomInfo?.room?.room_id else { return } - VoiceRoomBusinessRequest.shared.sendPOSTRequest(api: .joinRoom(roomId: roomId), params: [:]) { dic, error in - if let result = dic?["result"] as? Bool,error == nil,result { - self.view.makeToast("Joined successful!".localized(),point: self.toastPoint, title: nil, image: nil, completion: nil) - } else { - self.didHeaderAction(with: .back,destroyed: false) - } - } - } -// 离开语聊房 - @objc private func leaveRoom() { - if let room_id = roomInfo?.room?.room_id { - VoiceRoomBusinessRequest.shared.sendDELETERequest(api: .leaveRoom(roomId: room_id), params: [:]) { map, err in - print(map?["result"] as? Bool ?? false) - } - } - } -``` - -- 环信 IM 相关回调以及处理的方法,详见 [VoiceRoomViewController+IM](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Business/VoiceChat2.0/Controller/VoiceRoomViewController%2BIM.swift) 文件。 - -- 送礼物相关方法及其底部时间回调,详见 [VoiceRoomViewController+ChatBar](https://github.com/easemob/voiceroom_demo_ios/blob/dev/EasemobVoice_iOS/EasemobVoice_iOS/Business/VoiceChat2.0/Controller/VoiceRoomViewController%2BChatBar.swift) 文件。 - -### 音频相关 - -主播调用以下方法设置音频流: - -| API | 实现功能 | -| ------------------------------------------------------------ | ------------------------------ | -| [`setAudioProfile [2/2]`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_setaudioprofile2) | 设置音频编码属性。 | -| [`muteLocalAudioStream`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_mutelocalaudiostream) | 主播可以关闭或开启本地麦克风。 | -| [`adjustRecordingSignalVolume`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#api_adjustrecordingsignalvolume) | 调节人声音量。 | - -### 附加功能 - -#### 最佳音效 - -调用 [`setAudioEffectPreset`](https://docportal.shengwang.cn/cn/voice-call-4.x/API%20Reference/ios_ng/v4.2.2/API/rtc_api_overview_ng.html#ariaid-title129) 方法,在不改变原声的性别特征的前提下,设置人声音效。设置音效后,频道内所有用户都能听到该效果。 - -```swift - rtcKit.setChannelProfile(.liveBroadcasting) - rtcKit.setAudioProfile(.musicHighQuality) - rtcKit.setAudioScenario(.gameStreaming) -``` - -#### AI 降噪 - -AI 降噪插件使用声网人工智能噪声消除算法,能够让远程交流和面对面交谈一样实时。 - -可以开启或关闭 AI 降噪以及设置中级降噪和高级降噪。示例代码如下: - -```swift -public func setAINS(with level: AINS_STATE) { - switch level { - case .high: - rtcKit.setParameters("{\"che.audio.ains_mode\":2}") - rtcKit.setParameters("{\"che.audio.nsng.lowerBound\":10}") - rtcKit.setParameters("{\"che.audio.nsng.lowerMask\":10}") - rtcKit.setParameters("{\"che.audio.nsng.statisticalbound\":0}") - rtcKit.setParameters("{\"che.audio.nsng.finallowermask\":8}") - rtcKit.setParameters("{\"che.audio.nsng.enhfactorstastical\":200}") - case .mid: - rtcKit.setParameters("{\"che.audio.ains_mode\":2}") - rtcKit.setParameters("{\"che.audio.nsng.lowerBound\":80}") - rtcKit.setParameters("{\"che.audio.nsng.lowerMask\":50}") - rtcKit.setParameters("{\"che.audio.nsng.statisticalbound\":5}") - rtcKit.setParameters("{\"che.audio.nsng.finallowermask\":30}") - rtcKit.setParameters("{\"che.audio.nsng.enhfactorstastical\":200}") - case .off: - rtcKit.setParameters("{\"che.audio.ains_mode\":0}") - rtcKit.setParameters("{\"che.audio.nsng.lowerBound\":80}") - rtcKit.setParameters("{\"che.audio.nsng.lowerMask\":50}") - rtcKit.setParameters("{\"che.audio.nsng.statisticalbound\":5}") - rtcKit.setParameters("{\"che.audio.nsng.finallowermask\":30}") - rtcKit.setParameters("{\"che.audio.nsng.enhfactorstastical\":200}") - } -} -``` \ No newline at end of file diff --git a/docs/product/voiceroom/demo_experience.md b/docs/product/voiceroom/demo_experience.md deleted file mode 100644 index 2fad2795..00000000 --- a/docs/product/voiceroom/demo_experience.md +++ /dev/null @@ -1,19 +0,0 @@ -# Demo 体验 - -环信为 Android 和 iOS 平台提供了一个环信语聊房 Demo。你可以下载安装 APK 包体验语聊房。 - -- iOS:先在 iPhone 或 iPad 上安装 TestFlight,然后再体验 Demo。详见使用 [TestFlight 测试 App](https://testflight.apple.com/join/wmJGRdLh) 页面。 - -- Android:在[环信官网的 IM Demo 页面](https://www.easemob.com/download/demo)或点击[这里](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/IMDemo/easevoiceroom-demo1.0.apk)下载。 - -由于语聊房涉及到主播和观众,我们建议你准备两台设备进行体验。若你使用一台设备,可以添加机器人测试语音。 - -完成下载和安装后,参考如下步骤试用环信语聊房: - -1. 在两台手机上点击**环信语聊房**。 -2. 在一台手机上,点击**创建房间**,根据屏幕提示,输入语聊房名称,选择房间为公开或私密,点击**下一步**。 -3. 在**最佳音效**页面,选择最佳音效,点击**开始直播**,创建一个新的语聊房,选择是否允许“环信语聊房”录制音频,然后进入语聊房。创建语聊房的用户为房主。 -4. 在另一台手机上,点击进入刚刚创建的语聊房。进入已创建语聊房的用户就是观众。创建的语聊房会在 10 分钟后自动销毁,需要重新创建。 - -![img](/images/voiceroom/demo_homepage.png) - diff --git a/docs/product/voiceroom/demo_scenario_introduction.md b/docs/product/voiceroom/demo_scenario_introduction.md deleted file mode 100644 index 15febeae..00000000 --- a/docs/product/voiceroom/demo_scenario_introduction.md +++ /dev/null @@ -1,63 +0,0 @@ -# 环信语聊房场景介绍 - -## 场景描述 - -环信语聊房(Easemob Chat Room)场景方案是环信打造的一款低门槛、高可用的语聊房场景方案。该场景方案融合了环信即时通讯云的聊天室和声网 RTC 的音频技术,提供市面主流的语聊房 App 的功能,其核心功能包括房间管理、麦位控制、聊天打赏和音频特效等,覆盖语音游戏、语音社交、相亲交友等场景,能够较为全面满足客户的语聊房开发需求。同时,环信 IM 的聊天室中的 [KV 属性管理和自动销毁](/document/ios/room_attributes.html)以及[消息优先级](/document/ios/message_send_receive.html#设置聊天室消息优先级)等功能能够对语聊房的功能性进行有效补充和拓展。 - -## 功能列表 - -语聊房通常需要实现如下功能: - -| 功能 | 描述 | 实现产品 | -| :--------------- | :------------------ | :------------------ | -| 实时音频互动 | 超低延时下,观众实时接收主播的音频流,保证直播间互动的流畅性。 | Agora Audio SDK | -| 实时消息互动 | 直播间内的房主和观众使用文字消息实时交流;观众还可以通过实时消息给主播赠送礼物,增加互动气氛。 | 环信 IM SDK | -| 房间管理 | 语聊房的管理包括创建房间、加入房间、 离开房间、踢出房间和销毁房间。 | App Server | -| 麦位控制 | 麦位即语聊房的座位,同房间内最多支持 64 人同时连麦。房主可对麦位进行管理,包括邀请观众上麦、禁麦、解禁、封麦和解封以及使主播强制下麦等操作。
- 上麦:观众上麦。上麦后,观众成为连麦主播,可以和房主实时互动。
- 下麦:主播主动下麦或房主将主播踢下麦,使其恢复为普通观众。
- 禁麦:房主不允许连麦主播发言。
- 解禁麦位:房主恢复连麦主播的发言权限。
- 锁麦:锁定麦位,不允许任何人上麦。锁麦时,该麦位的主播会被踢下来成为普通观众。
- 解锁麦位:麦位恢复空闲状态,观众可以在该麦位申请上麦。
- 换麦:主播可申请从一个麦位切换到另一个空闲麦位。 | 环信 IM SDK 或者 App Server | - -## 技术方案 - -环信语聊房是通过使用环信即时通讯和声网 RTC 共同搭建。 - -Android Demo 架构如下图所示: - -![img](/images/voiceroom/voiceroom_demo_architecture_android.png) - -iOS Demo 架构如下图所示: - -![img](/images/voiceroom/voiceroom_demo_architecture_ios.png) - -各模块实现的功能如下: - -| 模块 | 实现功能 | -| :------------- | :----------------------------------------------------------- | -| RoomService/business | 基于 App Server 的房间管理。 | -| Commons/commons | 公用工具类和基类。 | -| RoomScene/component | 基于 App Server 的语聊房内部场景管理。 | -| IM 组件 | 对聊天室 API 和事件的封装。 | -| 基础请求组件 | 基础网络请求的实现。 | -| 音频组件 | 实现音频流的传输和互动。 | -| App Server | 实现用户登录、房间管理、房间内信息管理和麦位管理。 | - -## 方案优势 - -### 全面的场景核心功能 - -功能丰富,支持房间管理、麦位控制、聊天室、点赞打赏等核心模块。 - -### 完整的麦位控制 - -全面麦位控制,支持上麦申请和邀请机制以及锁麦、禁麦和换麦等操作。 - -### 真实的打赏模块 - -贴近真实场景,支持发送礼物、自定义礼物数量、打赏榜单和打赏统计等功能。 - -### 完成度较高的 Demo - -环信提供完成度较高的语聊房 Demo、App Server 核心代码供参考,协助快速打造语聊房场景。 - -### 完善的聊天室功能 - -聊天室消息分级和 KV 属性管理等功能协助实现可靠消息优先送达和房间保活,支持多种玩法拓展的需求,提升语聊房可用性。 - diff --git a/docs/product/voiceroom/run_through_demo_android.md b/docs/product/voiceroom/run_through_demo_android.md deleted file mode 100644 index 86714cc8..00000000 --- a/docs/product/voiceroom/run_through_demo_android.md +++ /dev/null @@ -1,33 +0,0 @@ -# 跑通语聊房示例项目 - -环信提供一个开源的[语聊房示例项目](https://github.com/easemob/voiceroom_demo_android),演示了如何使用环信 IM SDK、App Server 和 Agora RTC SDK 实现基本的消息互动、音频互动、房间管理和麦位管理等场景。 - -本文展示如何编译并运行 Android 平台的语聊房示例项目,体验房间内的互动。 - -## 前提条件 - -开始前,确保你的开发环境满足如下条件: - -- Android Studio 3.0 或以上版本; -- Android SDK API 等级 23 或以上; -- Android 6.0 或以上版本的设备。 - -## 操作步骤 - -### 获取示例项目 - -- 下载 [Easemob Chat Room 示例项目](https://github.com/easemob/voiceroom_demo_android)。 -- 下载 [Easemob Chat Room APK](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/IMDemo/easevoiceroom-demo1.0.apk)。 - -### 运行示例项目 - -- 使用 Android Studio 打开 VoiceChatRoom 工程文件。 -- 项目中使用的 Gradle 7.3.3 和 Gradle Plugin 7.2.1。若下载失败,可以尝试使用代理或者降低 Gradle 版本。 -- 编译项目前,需要在 `local.properties` 文件中配置环信 App Key、agora_appid 和 app_server_host。如未搭建 App Server,可以从官网下载 APK 安装体验。 -- Easemob Chat Room 为模块化项目。在 `gradle.properties` 文件中配置 `isChatroomModule=true` 使 chatroom 模块成为可独立运行的项目。 -- 配置项完成且编译通过后,使用 USB 线将 Android 设备接入你的电脑。启动选择 `business.chatroom` 项目,点击 `Run business.chatroom` 进行编译安装。 -- 打开 Easemob Chat Room 应用进行体验。 - -## 运行常见问题 - -在编译示例项目过程中,如果在 Android 12 设备运行报错,可以在 `gradle.properties` 文件中添加 `android.injected.testOnly=false`。 diff --git a/docs/product/voiceroom/run_through_demo_ios.md b/docs/product/voiceroom/run_through_demo_ios.md deleted file mode 100644 index 148c487c..00000000 --- a/docs/product/voiceroom/run_through_demo_ios.md +++ /dev/null @@ -1,39 +0,0 @@ -# 跑通语聊房示例项目 - -环信提供一个开源的[语聊房示例项目](https://github.com/easemob/voiceroom_demo_ios),演示了如何使用环信 IM SDK、App Server 和 Agora Audio SDK 实现基本的消息互动、音频互动、房间管理和麦位管理等场景。 - -本文展示如何编译并运行 iOS 平台的语聊房示例项目,体验房间内的互动。 - -## 前提条件 - -开始前,确保你的开发环境满足如下条件: - -- Xcode 13.0 或以上版本。 -- CocoaPods。你可以参考 [CocoaPods 安装指南](https://guides.cocoapods.org/using/getting-started.html#getting-started)。 -- iOS 13.0 或以上版本的设备。部分模拟机可能无法支持本项目的全部功能,所以推荐使用真机。 - -## 操作步骤 - -### 获取示例项目 - -- 下载 [Easemob Chat Room 示例项目](https://github.com/easemob/voiceroom_demo_ios)。 - -- 进入项目文件夹拖拽文件夹到终端,然后运行如下命令安装依赖库: - - ``` - pod update - pod install - ``` - -### 运行示例项目 - -- 使用 Xcode 打开 xcworkspace 工程文件。 -- 通过 USB 线将 iOS 设备接入你的电脑。 -- 在 Xcode 中,点击 **Build and run** 按钮。运行一段时间后,EaseMobVoiceChatRoom 应用会安装在 iOS 设备上。 -- 打开 EaseMobVoiceChatRoom 应用进行体验。 - -## 编译常见问题 - -在编译示例项目过程中,如果 Xcode 报错 `Error: Multiple commands produce`,可以参考如下步骤进行错误排查: -- 在 Xcode 中,选择 **File > Workspace Settings**。 -- 在弹出的面板中,点击 **Shared Workspace Settings** 区域的 **Build System** 框,将 **New Build System (Default)** 切换为 **Legacy Build System**。 diff --git a/docs/push/README.md b/docs/push/README.md deleted file mode 100644 index e3b83646..00000000 --- a/docs/push/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 即时推送 ---- diff --git a/docs/push/push_androidchannel_restriction.md b/docs/push/push_androidchannel_restriction.md deleted file mode 100644 index eeeb941c..00000000 --- a/docs/push/push_androidchannel_restriction.md +++ /dev/null @@ -1,91 +0,0 @@ -# 厂商通道限制及解决方案 - -## 华为 - -华为PUSH通道将根据应用类型对资讯营销类消息的每日推送数量进行上限管理。详情请参考[推送数量管理细则](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-restriction-description-0000001361648361)。 - -环信建议您做出以下调整: - -1、[申请华为消息自分类权益功能](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835)。 - -2、环信服务端请求,补充华为配置category的传值。 - -## OPPO - -OPPO PUSH推送服务将增加区分应用类型的推送频控限制,公信消息单用户限制2~5条,私信消息不受限。详情请登录OPPO PUSH开发者账号,管理中心查阅《【OPPO PUSH】推送服务规则更新说明》。 - -环信建议您做出以下调整: - -1、[申请OPPO PUSH私信通道权限](https://open.oppomobile.com/new/developmentDoc/info?id=11227)。 - -2、[客户端创建私信通道](https://open.oppomobile.com/new/developmentDoc/info?id=11252)。 - -3、环信服务端请求,补充OPPO配置channelId的传值。 - -## 小米 - -小米推送通道将分为“私信消息”和“公信消息”两个类别,不同类别对应不同的权限,若应用选择不接入私信或公信,则会接入默认通道,单个应用单个设备单日1条消息。详情查看[小米推送消息限制说明](https://dev.mi.com/console/doc/detail?pId=2086)。 - -环信建议您做出以下调整: - -1、[申请小米公私信渠道id](https://dev.mi.com/console/doc/detail?pId=2422#_2)。 - -2、环信服务端请求,补充小米配置 channelId的传值。 - -## vivo - -vivo 推送通道区分 “系统消息” 和”运营消息”,消息类别决定单日单用户推送量上限(环信服务端默认”系统消息”,即 classification = 1)。 - -[推送消息限制说明](https://dev.vivo.com.cn/documentCenter/doc/695#w1-53292792) ,在此基础上进行消息分类优化,新增 “二级分类”功能,根据推送内容界定不同推送分类。 - -环信建议您做出以下调整: - -1、[二级分类说明和申请](https://dev.vivo.com.cn/documentCenter/doc/359#_Toc64906673)。 - -2、环信服务端请求,补充 vivo 配置 category 传值。 - -注意:vivo 提醒配置使用请保证category与classification是正确对应关系,否则推送失败。 - -## 荣耀 - -荣耀推送服务将通知消息分为资讯营销、服务与通讯两大类别。资讯营销类消息的每日推送数量根据应用类型对推送数量进行上限管理,服务与通讯类消息每日推送数量不受限。 - -1、荣耀推送消息分类。[基础服务-消息分类标准 | 荣耀开发者服务平台](https://developer.hihonor.com/cn/kitdoc?category=基础服务&kitId=11002&navigation=guides&docId=notification-class.md) - -2、荣耀推送数量限制。[基础服务-推送数量管理细则 | 荣耀开发者服务平台](https://developer.hihonor.com/cn/kitdoc?category=基础服务&kitId=11002&navigation=guides&docId=notification-push-standards.md&token=) - -3、环信服务端请求,补充honor 配置 importance 传值。 - -环信服务端请求体示例: - -```json -{ - "pushMessage":{ - "title":"title", - "content":"content", - "huawei":{ - "message":{ - "android":{ - "category":"IM" - } - } - }, - "oppo":{ - "channelId":"test-channel-id" - }, - "xiaomi":{ - "channelId":"10135" - }, - "vivo":{ - "category":"IM" - }, - "honor":{ - "androidConfig": { - "androidNotification":{ - "importance":"NORMAL" - } - } - } - } -} -``` \ No newline at end of file diff --git a/docs/push/push_androidvendor_msgclassification.md b/docs/push/push_androidvendor_msgclassification.md deleted file mode 100644 index 6f405e44..00000000 --- a/docs/push/push_androidvendor_msgclassification.md +++ /dev/null @@ -1,285 +0,0 @@ -# 推送厂商消息分类使用指南 - -## 华为 - -### 华为消息推送限制 - -#### 华为每日推送数量上限要求 - -根据[消息分类标准](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835),华为推送服务将通知消息分为资讯营销、服务与通讯两大类别。资讯营销类消息的每日推送数量自2023年01月05日起根据应用类型对推送数量进行上限管理,服务与通讯类消息每日推送数量不受限。 - -| 消息分类 | 类型说明 | 推送数量限制 | -| :------ | :--------------------- | :------------- | -| 资讯营销类消息 | 内容资讯:内容推荐,新闻,财经动态,生活资讯,社交动态,调研,其他。营销活动:产品促销,功能推荐,运营活动。具体类别请参见[资讯营销类消息场景说明](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835#section171976503205)。 | 根据应用类别限制每日推送数量,具体要求参见[不同应用类别的推送数量上限要求](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-restriction-description-0000001361648361#section199311418515)。 | -| 服务与通讯类消息 | 社交通讯:即时聊天,音频、视频通话。服务提醒:订阅,出行,健康,工作事项提醒,帐号动态,订单&物流,财务,设备提醒,系统提示,邮件。具体类别请参见[服务与通讯类消息场景说明](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835#section13920133101416)。 | 无限制。 | - -#### 华为不同应用类别的推送数量上限要求 - -针对接入华为推送服务设备上的通知栏中的资讯营销类消息,将根据应用类别对每日推送数量进行上限管理。 - -| 二级分类 | 三级分类 | 单个应用每日每设备通知推送数量(单位:条) | -| :------------------ | :-------------------- | :---------------------- | -| 新闻阅读 | 新闻(需具备《互联网新闻信息服务许可证》) | 5 | -| 电子书、杂志、有声读书、动漫、幽默、体育、分类信息 | 2 | | -| 休闲益智 | 所有 | 2 | -| 经营策略 | 所有 | 2 | -| 体育竞技 | 所有 | 2 | -| 棋牌桌游 | 所有 | 2 | -| 动作射击 | 所有 | 2 | -| 角色扮演 | 所有 | 2 | -| 影音娱乐 | 所有 | 2 | -| 实用工具 | 所有 | 2 | -| 社交通讯 | 所有 | 2 | -| 教育 | 所有 | 2 | -| 新闻阅读 | 所有 | 2 | -| 拍摄美化 | 所有 | 2 | -| 美食 | 所有 | 2 | -| 出行导航 | 所有 | 2 | -| 旅游住宿 | 所有 | 2 | -| 购物比价 | 所有 | 2 | -| 商务 | 所有 | 2 | -| 儿童 | 所有 | 2 | -| 金融理财 | 所有 | 2 | -| 运动健康 | 所有 | 2 | -| 便捷生活 | 所有 | 2 | -| 汽车 | 所有 | 2 | -| 主题个性 | 所有 | 2 | - -详情请看[华为推送文档](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-restriction-description-0000001361648361)。 - -#### 华为推送速率QPS限制 - -华为推送对推送速度的分配,主要依据App在华为终端上的月活、App在华为应用市场上架时的应用类型这两个要素进行计算分配。 - -应用QPS=App在华为终端上MAU(Monthly Active User)×应用类别权重×整体分配系数(0.00072)。 - -QPS(Quantity per second):表示1秒可以发送的推送条数。 - -应用在华为终端上MAU查询路径:“华为开发者联盟 > 管理中心 > 应用服务 > AppGallery Connect > 我的项目 > 推送服务 > 推送报告 > 推送用户详情 > 30日活跃用户数” - -应用类别:指的是应用在应用市场上架时选择的应用二级分类,查询路径:“华为开发者联盟 > 管理中心 > 应用服务> AppGallery Connect > 我的应用 > 应用信息 > 应用分类 > 应用二级分类”。 - -应用类别权重列表: - -| 分组名称 | 应用分类 | 权重系数 | -| :--------- | :--------------------------------- | :------- | -| IM类 | 社交通讯 | 5 | -| 金融类 | 金融理财 | 5 | -| 新闻类 | 新闻阅读;资讯生活 | 4 | -| 内容类 | 图书阅读;影音娱乐;拍摄美化 | 3 | -| 电商类 | 购物比价 | 3 | -| 衣食住行类 | 便捷生活;出行导航;美食;旅游住宿 | 3 | -| 商务类 | 商务 | 3 | -| 游戏类 | 网络游戏;休闲益智;经营策略;棋牌 | 2 | -| 工具类 | 实用工具 | 1 | -| 运动健康类 | 医疗健康;运动健康 | 1 | -| 其他类 | 儿童;教育;主题个性;汽车 | 1 | -| Default | Default(未上架) | 1 | - -若您的应用通过QPS公式计算所得的值不足6000,将执行默认6000的QPS;同时,全网流量较高时,也会出现系统级流控(流控对应的状态码为HTTP 503)。 - -QPS计算规则只适用于中国大陆。 - -#### 华为Push消息长度限制 - -应用包名最大支持128字节,消息内容最大支持4K字节(不包括Push Token)。 - -### 华为消息分类标准 - -华为将根据消息分类方案对不同类别消息的提醒方式、消息样式进行差异化管理,具体如下: - -| 消息类型 | 定义 | 提醒方式 | 消息样式 | -| :--------- | :---------- | :------- | :------------------------------ | -| 服务与通讯 | 包括社交通讯类消息和服务提醒类消息。社交通讯,指用户间的聊天消息、通话等信息。服务提醒,指应用借助通知中心及时向用户传递重要通知提醒,通常用户对接收此类消息有预期。 | 锁屏、铃声、振动 | 文本+小图(可选)
![img](/images/instantpush/push_huawei_tinyimage1.png)| -| 资讯营销 | 包括资讯类消息和营销类消息,指的是运营人员向用户发送的活动信息、内容推荐、资讯等。 | 静默通知,仅在下拉通知栏时展示消息 | 文本+小图(可选)
![img](/images/instantpush/push_huawei_tinyimage2.png) | - -#### 华为消息分类方式 - -华为消息分类方式有两种,默认情况下,所有消息一律通过通知消息智能分类功能进行分类。如您希望消息分类能更精准地符合业务需要,您也可以申请自分类权益,我们将信任您所提供的分类信息,按照您提供的分类标准展示对应消息。 - -##### 消息智能分类 - -智能分类算法将根据您发送的内容等多个维度因素,自动将您的消息按照分类标准归类为服务与通讯类或者资讯营销类消息。 - -##### 消息自分类 - -华为推送服务接受开发者自分类权益的申请。当您申请成功后,允许开发者根据华为推送分类规范,自行对消息进行分类。 - -举例:具有消息自分类权益且申请了自分类消息类型IM消息,当您发送消息时携带category字段且赋值为“IM”,则该消息的提醒方式为锁屏+铃声+震动。 - -#### 华为自分类权益申请 - -自分类申请详情参见 [华为消息分类管理方案](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/message-classification-management-solution-0000001149358835-V5#ZH-CN_TOPIC_0000001149358835__section153801515616)。 - -- 若应用没有自分类权益,则应用的推送消息将通过智能分类进行自动归类。 -- 若应用有自分类权益,将信任开发者提供的分类信息,消息不经过智能分类。 - -#### 华为消息分类使用 - -消息分类的申请审核通过后,即可指定 importance 进行下发, 该参数在 options 可选参数的 third_party_channel 字段下。 - -| 关键字 | 类型 | 选项 | 含义 | 说明 | -| :--------- | :----- | :--- | :------ | :----------- | -| importance | string | 可选 | 华为通知栏消息智能分类 | 取值为”LOW”时,表示消息为资讯营销。取值为”NORMAL”时,表示消息为服务与通讯。 | -| category | string | 可选 | 华为厂商消息场景标识 | 为了适配华为手机厂商消息,完成[自分类权益申请](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835#section3410731125514) 后,用于标识消息类型,确定消息提醒方式,对特定类型消息加快发送。对应值及其说明参考 [category 值说明](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/https-send-api-0000001050986197#ZH-CN_TOPIC_0000001134031085__p5203378238)。若应用没有自分类权益,或应用有自分类权益但推送消息不携带 category 字段,则应用的推送消息将通过智能分类进行自动归类。若应用有自分类权益且推送消息携带category字段,将信任开发者提供的分类信息,消息不经过智能分类。 | - -## OPPO - -### 消息推送限制 - -#### 推送数量限制 - -目前OPPO PUSH推送数量限制的规则是: - -![img](/images/instantpush/push_oppo_quantityrestriction.png) - -通知栏推送测试权限与正式权限仅有推送数量上的差异,api推送环境都使用正式环境。 - -累计用户是指从接入OPPO PUSH的App客户端,用户安装并激活的累计用户量,去除已卸载用户数。 - -累计用户数在[OPPO推送运营平台](https://push.oppo.com/)可查询,每天会刷新。 - -目前私信处于公测阶段,需要申请才能开启私信通道,私信申请请参考[OPPO PUSH通道升级公测邀请](https://open.oppomobile.com/wiki/doc#id=10614) - -:::tip -OPPO推送服务将于2023年1月15日优化推送数量限制规则,对已申请正式权限的应用增加区分应用类别的推送频控限制。 -::: - -![img](/images/instantpush/push_oppo_singleuser.png) - -具体限制请参考[OPPO推送文档](https://open.oppomobile.com/new/developmentDoc/info?id=11210)。 - -#### 推送速率QPS限制 - -OPPO暂未对外公布详细推送速率限制。 - -#### PUSH消息长度限制 - -通知标题:50字符(中英文均以一个计算) - -通知内容:200字符(中英文均以一个计算) - -:::tip -超过限制则该条消息无法通过OPPO厂商通道发送,环信在线通道不受影响。 -::: - -### 消息分类标准 - -OPPO PUSH将消息分为私信消息和公信消息两类。私信消息是针对用户有一定关注度,且希望能及时接收的信息,如即时聊天信息、个人订单变化、快递通知、订阅内容更新、评论互动、会员积分变动等,与单个用户信息强相关的内容。 - -公信消息是针对用户关注度不高,且对于接收这类信息并无心理预期,如热点新闻、新品推广、平台公告、社区话题、有奖活动等,多用户普适性的内容。 - -| 类型 | 私信信道 | 公信信道 | -| :--------- | :--------------- | :----------------- | -| 推送数量限制 | 不限量 | 有公信类通道共享推送次数,当日达到推送量限制后,所有公信类通道将无法再推送消息; 推送限量:当累计用户数<50000时,按100000/日计算;当累计用户数≥50000时,累计用户数*2/日。 | -| 单设备推送条数限制 | 不限量 | 新闻类(三级分类为新闻类):5条/日 其他应用类型:2条/日 | -| 配置方式 | 客户端[适配通道](https://open.oppomobile.com/new/developmentDoc/info?id=11251)、并且邮件申请通过后,需要在[OPPO推送平台](https://push.oppo.com/)上登记该通道,并将通道对应属性设置为“私信” | 默认开通 | -| 服务端推送方法 | “[单点推送](https://open.oppomobile.com/new/developmentDoc/info?id=11238)”api(服务端SDK对应unicastNotification、unicastBatchNotification方法),channel_id带上私信通道的通道ID | “单点推送”和“广播推送”都支持。 | -| 消息类型限制 | 私信消息(通过私信模板限制) | 不限制,公信消息/私信消息均可。 | - -#### OPPO私信通道使用 - -1.[创建客户端自定义渠道](https://docs.jiguang.cn/jpush/client/Android/android_api#notificationchannel-配置),channel_id 须与OPPO 官网登记的通道 ID 一致。 - -2.API 推送。 - -channel_id 参数在 notification 的 android 字段下。 - -| 关键字 | 类型 | 选项 | 含义 | 说明 | -| :--------- | :----- | :--- | :------ | :------------ | -| channel_id | string | 可选 | android 通知 channel_id | 不超过1000字节,Android 8.0开始可以进行 [NotificationChannel 配置](https://docs.jiguang.cn/jpush/client/Android/android_api#notificationchannel-配置),这里根据 channel ID 来指定通知栏展示效果。 | - -## 小米 - -### 消息推送限制 - -小米推送消息限制分为每日推送数量限制,推送速率QPS限制和推送消息长度限制。 - -具体请参考小米官方文档[小米推送限制说明](https://dev.mi.com/console/doc/detail?pId=2086)。 - -#### 推送数量限制 - -![img](/images/instantpush/push_mi_pushrestriction.png) - -如果特殊情况需要额外提升推送量级,开发者可以向小米推送进行申诉。 - -申诉方法: - -发邮件至邮箱[mipush-permission@xiaomi.com](mailto:mipush-permission@xiaomi.com)。 - -邮件模板: - -主题:xxx应用申请增加普通消息发送量级 - -正文: - -应用名称: - -AppID: - -应用简介: - -申请的推送量级: - -申请原因: - -(1)推送场景的详细说明(必填) - -(2)用户因收不到推送的投诉(选填) - -(3)或者其他可以证明增加推送量级合理性的材料(选填)。 - -小米推送将在5个工作日内答复审核结果。 - -#### 推送速率QPS限制 - -##### 限制规则 - -小米推送对推送速率(QPS)的分配主要依据App的MIUI日联网设备数进行分级计算。 - -QPS:表示1秒可调用的请求数。1个请求里最多可以携带1000个目标设备。例如:3000 QPS时,1秒内最多可推送300万设备。 - -MIUI日联网设备数的查询路径:推送运营平台-推送统计-用户数据-数据详情 - -不同量级的MIUI日联网设备数分配不同的QPS: - -| MIUI日联网设备数 | QPS | -| :--------------- | :--- | -| ≥1000万 | 3000 | -| ≥500万且<1000万 | 2500 | -| ≥100万且<500万 | 2000 | -| ≥10万且<100万 | 1000 | -| <10万 | 500 | - -#### Push消息长度限制 - -通知标题:50字符(中英文字符均计算为1) - -通知内容:128字符(中英文字符均计算为1) - -:::tip -超过限制则该条消息无法通过小米厂商通道发送,环信在线通道不受影响。 -::: - -### 消息分类标准 - -小米推送将消息分为“**私信消息**”和“**公信消息**”两个类别,不同类别对应不同的权限,具体映射关系如下: - -| **消息类型** | **划分原则** | **推送内容** | **管控规则** | **提醒方式** | **申请方式** | -| :----------- | :------------- | :--------- | :------------ | :----------- | :------- | -| 私信消息 | 用户主动订阅、对收到此类消息有预期,或需要及时知道的消息等,如果错过可能会导致不良影响。 | 即时消息、个人账户、个人资产、个人订阅、个人日程、设备信息、订单及物流、工作信息。 | 每日推送数量无限制; 用户接收数量无限制。 | 响铃、振动 | 在推送运营平台申请,具体参见“[2. channel申请及接入方法](https://dev.mi.com/console/doc/detail?pId=2422#_2)”。 | -| 公信消息 | 用户对收到此类消息无预期,关注程度较低。 | 新闻资讯、内容资讯、生活资讯、关注推荐、算法推荐、平台活动、互动信息、其他消息。 | 严格限制每日推送、接收数量,具体限制规则请参见“[消息限制说明](https://dev.mi.com/console/doc/detail?pId=2086)”。 | 无 | | - -2023年2月1日起按照本新规中的消息分类正式运行。 - -小米重要级别消息申请 - -申请方式请参见小米官方文档 [channel 申请及接入方法](https://dev.mi.com/console/doc/detail?pId=2422#_2)。 - -#### 小米消息分类使用 - -channel_id 参数在 notification 的 android 字段下。 - -| 关键字 | 类型 | 选项 | 含义 | 说明 | -| :--------- | :----- | :--- | :-------- | :------ | -| channel_id | string | 可选 | android 通知 channel_id | 不超过1000字节,Android 8.0开始可以进行 [NotificationChannel 配置](https://docs.jiguang.cn/jpush/client/Android/android_api#notificationchannel-配置),这里根据 channel ID 来指定通知栏展示效果。 | \ No newline at end of file diff --git a/docs/push/push_androidvendor_statistics.md b/docs/push/push_androidvendor_statistics.md deleted file mode 100644 index 637a3eb1..00000000 --- a/docs/push/push_androidvendor_statistics.md +++ /dev/null @@ -1,180 +0,0 @@ -# Android 厂商统计 - -环信推送提供谷歌、小米、魅族、OPPO、vivo、华为厂商通道的送达、点击数据统计功能。 - -## 送达设置 - -### 1、魅族需要设置回调白名单才能实现相关功能。方法如下: - -#### 1.1、登陆魅族官方平台 - -登陆 [魅族开放平台](https://open.flyme.cn/),点击【Flyme 推送】。 - -![img](/images/instantpush/push_meizu_flymeconsole.png) - -#### 1.2、选择配置应用 - -选择您要设置的应用名称,点击【打开应用】。 - -![img](/images/instantpush/push_flyme_openapp.png) - -#### 1.3、设置回调地址 - -根据所在集群设置回调地址(配置 http) -格式为:`http://域名/orgname/appname/push/report/meizu`。 - -![img](/images/instantpush/push_flyme_callbackaddr.png) - -您可以在环信后台,**即时通讯** → **服务概览** 中查看当前 Appkey 的 Rest API 域名地址,仅支持填写 `easemob.com` 类型。 - -![img](/images/instantpush/push_domain_name.png) - -#### 1.4、开启送达回执 - -魅族平台设置完回执地址后,需要在环信开发者后台,**即时推送** → **配置证书** → **魅族** 配置中开启推送送达回执,才能获取到魅族通道送达数据。 - -### 2、华为需要进行推送回执配置才能实现相关功能。方法如下: - -#### 2.1、登陆华为官方平台 - -登陆 [华为消息推送平台](https://developer.huawei.com/consumer/cn/service/josp/agc/index.html#/),点击【我的项目】。 - -![img](/images/instantpush/push_huawei_console.png) - -#### 2.2、选择配置应用 - -选择您要设置的应用名称,点击【推送服务】,点击【配置】。 - -![img](/images/instantpush/push_huawei_config.png) - -#### 2.3、开通应用回执状态 - -开通回执状态 - -![img](/images/instantpush/push_huawei_callback.png) - -#### 2.4、测试并添加回执 - -填写回执配置,测试回执通过后进行提交。 - -![img](/images/instantpush/huawei_report_v1.png) - -如果您有多个回执地址,且环信回执地址并非默认选项,则需要指定回执配置ID,详情见 [华为配置推送通知receiptId ](push_notification_config.html#华为推送说明) - -![img](/images/instantpush/huawei_receipt_id.png) - -示例: - -```json -{ - "pushMessage":{ - "huawei":{ - "message":{ - "android":{ - "receiptId":"RCP78C959D4" - } - } - } - } -} -``` - -##### 2.4.1、回调地址 - -根据所在集群设置回调地址(配置 https,注意:华为只支持https地址配置) -格式为:`https://域名/orgname/appname/push/report/huawei` -您可以在环信后台,**即时通讯** > **服务概览** 中查看当前 Appkey 的 Rest API 域名地址,仅支持填写 `easemob.com` 类型。 - -![img](/images/instantpush/push_domain_name.png) - -### 3、FCM 客户端处理上报 - -继承`FirebaseMessagingService`的`Service`里去实现`handleIntent`方法,添加上报送达事件的代码 - -```java -public class EMFCMMSGService extends FirebaseMessagingService { - - @Override - public void handleIntent(@NonNull Intent intent) { - super.handleIntent(intent); - Bundle bundle = intent.getExtras(); - if(bundle != null){ - String push = bundle.getString("EPush"); - if(push != null){ - try { - String taskId = ""; - JSONObject pushJson = new JSONObject(push); - String provider = pushJson.optString("provider"); - JSONObject report = pushJson.optJSONObject("report"); - if(report != null){ - taskId = report.optString("task_id"); - } - - EMClient.getInstance().pushManager().asyncReportPushAction(taskId, provider, EMPushManager.EMPushAction.ARRIVE, new EMCallBack() {}); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - } - } -} -``` - -启动页的`onCreate`里添加上报点击事件的代码。 - -```java -Bundle bundle = getIntent().getExtras(); - if(bundle !=null){ - String push = bundle.getString("EPush"); - if(push != null){ - try { - String taskId = ""; - JSONObject pushJson = new JSONObject(push); - String provider = pushJson.optString("provider"); - JSONObject report = pushJson.optJSONObject("report"); - if(report != null){ - taskId = report.optString("task_id"); - } - EMClient.getInstance().pushManager().asyncReportPushAction(taskId, provider, EMPushManager.EMPushAction.CLICK, new EMCallBack() {}); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } -``` - -## 点击事件上报 - -厂商推送的点击事件上报,需要在 App 端调用 API 上报实现统计。 - -``` -//taskId 与 provider 需从推送数据里获取,如果获取 taskId 失败则传空字符串 -EMClient.getInstance().pushManager().asyncReportPushAction(taskId, provider, action, new EMCallBack(){}); -``` - -以小米推送为例,在厂商的点击回调里去解析上报点击事件。 - -```java -public void onNotificationMessageClicked(Context context, MiPushMessage message) { - - String content = message.getContent(); - try { - // JSON 结构为 {"EPush":{"provider":{"xxx"},"report":{"task_id":"xxx"}}} - JSONObject json = new JSONObject(content); - JSONObject pushJson = json.optJSONObject("EPush"); - String taskId = ""; - if(pushJson != null){ - String provider = pushJson.optString("provider"); - JSONObject reportJson = pushJson.optJSONObject("report"); - if(reportJson != null){ - taskId = reportJson.optString("task_id"); - } - - EMClient.getInstance().pushManager().asyncReportPushAction(taskId, provider, EMPushManager.EMPushAction.CLICK, new EMCallBack() {}); - } - } catch (JSONException e) { - e.printStackTrace(); - } -} -``` \ No newline at end of file diff --git a/docs/push/push_api_call_limitation.md b/docs/push/push_api_call_limitation.md deleted file mode 100644 index 081ac70f..00000000 --- a/docs/push/push_api_call_limitation.md +++ /dev/null @@ -1,28 +0,0 @@ -# 即时推送 RESTful API 调用频率限制 - -本文介绍即时推送 RESTful API 的调用频率限制,包括推送标签管理和发送推送通知相关的 API 的调用频率限制。 - - - -## 推送标签管理 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :----------- | :----- | :------------------- | :------------- | -| [创建推送标签](push_by_tag.html#创建推送标签) | POST | /{org_name}/{app_name}/push/label | 10 次/秒/App Key | -| [查询指定的推送标签](push_by_tag.html#查询指定的推送标签) | GET | /{org_name}/{app_name}/push/label/{labelname} | 10 次/秒/App Key | -| [分页查询推送标签](push_by_tag.html#分页查询推送标签) | GET | /{org_name}/{app_name}/push/label | 10 次/秒/App Key | -| [删除指定的推送标签](push_by_tag.html#删除指定的推送标签) | DELETE | /{org_name}/{app_name}/push/label/{labelname} | 10 次/秒/App Key | -| [在推送标签下添加用户](push_by_tag.html#在推送标签下添加用户) | POST | /{org_name}/{app_name}/push/label/{labelname}/user | 30 次/秒/App Key | -| [查询指定标签下的指定用户](push_by_tag.html#查询指定标签下的指定用户) | GET | /{org_name}/{app_name}/push/label/{labelname}/user/{username} | 30 次/秒/App Key | -| [分页查询指定标签下的用户](push_by_tag.html#分页查询指定标签下的用户) | GET | /{org_name}/{app_name}/push/label/{labelname}/user | 30 次/秒/App Key | -| [批量移出指定推送标签下的用户](push_by_tag.html#批量移出指定推送标签下的用户) | DELETE | /{org_name}/{app_name}/push/label/{labelname}/user | 30 次/秒/App Key | - -## 发送推送通知 - -| RESTful API 接口 |方法 | 接口 URL| 接口最高调用频率(默认值) | -| :----------- | :----- | :------------------- | :------------- | -| [以同步方式发送推送通知](push_send_notification.html#以同步方式发送推送通知) | POST | /{org_name}/{app_name}/push/sync/{target} | 1 次/秒/App Key | -| [以异步方式向单个用户发送推送通知](push_send_notification.html#以异步方式向单个用户发送推送通知) | POST | /{org_name}/{app_name}/push/sync/{target} | 200 次/秒/App Key | -| [以异步方式批量发送推送通知](push_send_notification.html#以异步方式批量发送推送通知) | POST | /{org_name}/{app_name}/push/single | 10 次/秒/App Key | -| [使用标签推送接口发送推送通知](push_send_notification.html#使用标签推送接口发送推送通知) | POST | /{org_name}/{app_name}/push/list/label | 10 次/秒/App Key | -| [创建全量推送任务](push_send_notification.html#创建全量推送任务) | POST | /{org_name}/{app_name}/push/task | 1 次/秒/App Key | \ No newline at end of file diff --git a/docs/push/push_apns_deliver_statistics.md b/docs/push/push_apns_deliver_statistics.md deleted file mode 100644 index d6b92a81..00000000 --- a/docs/push/push_apns_deliver_statistics.md +++ /dev/null @@ -1,99 +0,0 @@ -# APNs 送达统计 - -此文档是建立在已经集成了环信推送服务的基础上提供统计苹果远程推送 (APNs) 送达的功能。 - -你需要在应用里创建推送服务扩展(推送扩展服务仅支持 iOS 10 及以上版本),在推送扩展里导入环信扩展服务 SDK,调用对应的 API。 - -:::tip -APNs 的点击已在 SDK 内部实现,无需单独处理。 -::: - -## 1、推送服务扩展介绍 - -iOS 10 苹果增加了推送通知服务应用扩展(Notification Service Extension),用户可以在扩展基础上对远程的推送内容进行修改。 - -前提是推送时候在 `payload` 中必须设置 `mutable-content` 值为 1,否则推送扩展将不会被调用。 - -需要注意的是,一般系统会自动给你生成扩展应用的 `Bundle Identifier`,不做修改即可。如果修改了的话必须在主应用的 `Bundle Identifier` 基础上做添加,否则将会有错误。比如主应用的 `Bundle Identifier` 为 `com.xx.targetname`,那么扩展应用的 `Bundle Identifier` 应该为 `com.xx.targetname.yy`。 - -在创建推送服务扩展后系统默认给你创建了两个回调方法,使用 `didReceiveNotificationRequest:withContentHandler`:方法修改推送内容,系统会给你大约 30s 的时间处理这个推送,如果超过这个时间,系统将调 `serviceExtensionTimeWillExpire`方法,此时您必须立即向系统返回您所能返回的任何内容。如果从任何一个方法中调用完成处理程序失败,系统将显示通知的原始内容。 - -## 2、为应用创建推送服务扩展 - -- 点击 **Xcode**,选择 **File** > **New** > **Target**。 - -![img](/images/instantpush/push_xcode_target.png) - -- 在 **iOS** > **Application Extension** 下选中 **Notification Service Extension**,点击 **Next**。 - -![img](/images/instantpush/push_apns_notificationextension.png) - -- 为您的应用程序扩展指定名称和其他配置细节,点击完成。 - -![img](/images/instantpush/push_apns_targetconfi.png) - -- 创建完后在工程里会自动生成三个文件 (NotificationService.h、NotificationService.m、info.plist) 和扩展应用的 Target(工程名就是创建时候填的 Product Name)。 - -![img](/images/instantpush/push_apns_serviceext.png) - -## 3、推送服务扩展导入 SDK - -推送扩展 SDK 支持手动和 Pod 导入,您可以选择任意一种方式进行导入。 - -### 通过 Pod 导入 - -在集成环信推送服务时候,您为主工程已创建了 Podfile 文件,在此文件基础上,您可以为扩展添加 Pod 管理,在 Podfile 文件里指明对应的 target,再添加需要导入的 SDK 名称。 - -```pod -target 'EMPushServerExt' do - pod 'EMPushExtension' -end -``` - -然后在 Podfile 目录下,执行更新命令。 - -```pod -pod install --repo-update -``` - -### 手动导入 - -APNs 的送达统计 SDK 下载地址: - -[下载推送扩展SDK](https://downloadsdk.easemob.com/downloads/EMPushExtension0_1_0.zip) - -下载下来之后,将 **EMPushExtension.framework** 加入到应用扩展目录下即可。 - -![img](/images/instantpush/push_apns_extension_directory.png) - -## 4、SDK 使用 - -在 **NotificationService.m** 里引入头文件: - -```objectivec -#import -``` - -在系统提供处理推送的方法里调用 EMPushServiceExt 的两个方法,这两个方法必须都调用,且设置 Appkey的方法需要先调用。 - -```objectivec -- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { - self.contentHandler = contentHandler; - self.bestAttemptContent = [request.content mutableCopy]; - - // Modify the notification content here... - [EMPushServiceExt setAppkey:@"appkey from easemob"];//Appkey 必须和主应用中的 Appkey 一致 - [EMPushServiceExt receiveRemoteNotificationRequest:request completion:^(NSError * _Nonnull error) { - NSLog(@"EMPushServiceExt complete APNs delivery"); - self.contentHandler(self.bestAttemptContent); - }]; - self.contentHandler(self.bestAttemptContent); -} - -- (void)serviceExtensionTimeWillExpire { - // Called just before the extension will be terminated by the system. - // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. - - self.contentHandler(self.bestAttemptContent); -} -``` \ No newline at end of file diff --git a/docs/push/push_billing.md b/docs/push/push_billing.md deleted file mode 100644 index b5933252..00000000 --- a/docs/push/push_billing.md +++ /dev/null @@ -1,283 +0,0 @@ -# 计费说明 - -环信PUSH分为**免费版**与**专业版**(区分中国大陆境内、中国大陆境外)三个版本。产品版本、计费规则及功能详情如下所示。 - -## 1. 产品版本 - -| 项目 | 免费版 | 专业版(中国大陆境内) | 专业版(中国大陆境外) | -| -------- | ---------- | ---------- | ----------------------- | -| 适用场景 | 支持开发者实现轻量级推送应用服务的开发 | 支持产品启动规模级推送应用服务,随着规模升级按月峰值DAU阶梯计价 | 支持产品启动规模级推送应用服务,随着规模升级按月峰值DAU阶梯计价 | -| 计费模式 | 100 个注册用户免费使用,超过则按专业版计费 | 按照月峰值 DAU 计费,288元/1万 DAU(开通含1万DAU) | 按照月峰值 DAU 计费,388元/1万 DAU(开通含1万DAU) | - -## 2. 计费规则 - -### 2.1 计费周期 - -环信PUSH消息云每月5号出账单,对当月峰值DAU使用情况进行统计,根据消费情况从余额进行扣费,您可以前往 [费用中心](https://console.easemob.com/costMoneyCenter) 查看详细扣费信息。 - -### 2.2 欠费说明 - -余额不足时,环信PUSH将停服并发送通知邮件到注册邮箱,若您在停服后7天内未完成续费,环信PUSH将主动释放您在云上创建的应用,被释放的应用以及资源均不可恢复。 - -## 3. 功能详情 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
功 能功能描述免费版专业版(中国大陆境内)专业版(中国大陆境外)
基础功能应用管理无限制无限制无限制
用户数限制100根据用户规模阶梯收费根据用户规模阶梯收费
基础推送(通知&透传)
大文本/大图片
启动应用/打开链接/打开特定页面
全量用户推送5次/分钟
- 发送量:100次/天
5次/分钟
- 发送量:100次/天
5次/分钟
- 发送量:100次/天
指定用户推送600次/分钟,可扩展配置
- 发送量:不限
1200次/分钟,可扩展配置
- 发送量:不限
1200次/分钟,可扩展配置
- 发送量:不限
标签推送600次/分钟,可扩展配置
- 发送量:不限
1200次/分钟,可扩展配置
- 发送量:不限
1200次/分钟,可扩展配置
- 发送量:不限
– –自定义标签
– –用户当日设置标签次数无限制无限制无限制
– –标签运算
厂商通道(华为、小米、vivo、OPPO、魅族、APNs、FCM)
高级功能角标
自定义铃声
推送策略选择
– –环信通道优先,在线走环信,离线走厂商
– –只通过第三方厂商推送
– –在线或者离线都通过环信通道推送
– –厂商通道优先,失败时走环信通道
离线消息保存时长设置
定时推送
应用数据报表本月峰值DAU
注册用户总数
今日活跃用户数
今日新增用户数
数据与统计推送目标数
推送成功数
推送状态
厂商通道占比
送达率(环信、华为、小米、vivo、OPPO、魅族、APNs、FCM)
点击率(环信、华为、小米、vivo、OPPO、魅族、APNs、FCM)
demoAndroid、iOS端demo
技术支持产品咨询企业微信群
工单通道
系统上线与大促护航服务
专属支持微信群
专属服务经理支持
专属技术专家支持
客户支持5*8 小时7*12 小时7*12 小时
\ No newline at end of file diff --git a/docs/push/push_by_tag.md b/docs/push/push_by_tag.md deleted file mode 100644 index e881b669..00000000 --- a/docs/push/push_by_tag.md +++ /dev/null @@ -1,617 +0,0 @@ -# 推送标签管理 - -即时通讯服务支持通过设置标签自定义推送用户,实现精准推送。标签用于描述用户的生活习惯、兴趣爱好、行为特征等信息。对用户设置标签后,推送消息时,指定某一推送标签,即可向该标签下的用户发送消息。例如,可以为一些用户打上“时尚弄潮儿”标签后,可定期向该人群推送国内外潮流品牌的相关信息。 - -你可以通过环信即时通讯控制台创建和管理标签,也可以通过 REST API 进行标签管理。用户与标签是多对多的关系,即一个用户可以对应多个标签,一个标签也可以对应多个用户。 - -本文档主要介绍如何调用即时推送 REST API 实现创建及管理推送标签。调用以下方法前,请先参考 [接口频率限制](/product/limitation.html)了解即时通讯 RESTful API 的调用频率限制。 - -## 公共参数 - -### 请求参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :-------------------------------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。 | -| `username` | String | 是 | 用户 ID。 | - -### 响应参数 - -| 参数 | 类型 | 描述 | -| :---------- | :--- | :----------------------------------- | -| `timestamp` | Long | 响应的 Unix 时间戳,单位为毫秒。 | -| `duration` | Long | 从发送请求到响应的时长,单位为毫秒。 | - -## 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 Authorization 字段: - -Authorization:`Bearer ${YourAppToken}` - -为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 推荐使用 app token 的鉴权方式,详见 [使用 token 鉴权](/product/easemob_app_token.html)。 - -## 创建推送标签 - -为推送的目标用户添加标签,对用户进行分组,实现精细化推送。当前最多可创建 100 个推送标签。如需提升该上限,请联系商务。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/label -``` - -#### 路径参数 - -参数及说明详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型。请填 `application/json`。 | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :------------ | :----- | :----------------------------------------------------------- | :------- | -| `name` | String | 要创建的推送标签的名称,不能超过 64 个字符。支持以下字符集:
- 26 个小写英文字母 a-z
- 26 个大写英文字母 A-Z
- 10 个数字 0-9
- “_“,”-“,”.” 标签名称区分大小写,因此 `Aa` 和 `aa` 为两个标签名称 。
同一个 app 下,标签名称必须唯一。 | 是 | -| `description` | String | 推送标签的描述,不能超过 255 个字符。 | 否 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------------- | -| `data` | JSON | 推送标签的数据。 | -| `name` | String | 推送标签的名称。 | -| `description` | String | 推送标签的描述。 | -| `createdAt` | Long | 推送标签的创建时间。该时间为 Unix 时间戳,单位为毫秒。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X POST 'localhost/hx/hxdemo/push/label' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "name":"post-90s", - "description":"hah" -}' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1648720341157, - "data": { - "name": "post-90s", - "description": "hah", - "createdAt": 1648720341118 - }, - "duration": 13 -} -``` - -## 查询指定的推送标签 - -查询指定的推送标签。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/push/label/{labelname} -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :---------- | :----- | :----------------------- | :------- | -| `labelname` | String | 要查询的推送标签的名称。 | 是 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------------- | -| `data` | JSON | 推送标签的数据。 | -| `name` | String | 推送标签的名称。 | -| `description` | String | 推送标签的描述。 | -| `count` | Int | 该推送标签下的用户数量。 | -| `createdAt` | Long | 推送标签的创建时间。该时间为 Unix 时间戳,单位为毫秒。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码)了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X GET 'localhost/hx/hxdemo/push/label/90' \ --H 'Authorization: Bearer ' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1648720562644, - "data": { - "name": "90", - "description": "hah", - "count": 0, - "createdAt": 1648720341118 - }, - "duration": 0 -} -``` - -## 分页查询推送标签 - -分页查询推送标签。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/push/label -``` - -#### 路径参数 - -参数及说明详见 [公共参数](#公共参数)。 - -#### 查询参数 - -| 字段 | 类型 | 描述 | 是否必需 | -| :------- | :----- | :--------------------------------------------------------- | :------- | -| `limit` | Int | 每页显示的推送标签的数量,取值范围为 [1,100],默认为 `100`。 | 否 | -| `cursor` | String | 数据查询的起始位置。 | 否 | - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------------ | :----- | :----------------------------------------------------- | -| `data` | JSON | 推送标签的数据。 | -| `name` | String | 推送标签的名称。 | -| `description` | String | 推送标签的描述。 | -| `count` | Int | 该推送标签下的用户数量。 | -| `createdAt` | Long | 推送标签的创建时间。该时间为 Unix 时间戳,单位为毫秒。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X GET 'localhost/hx/hxdemo/push/label' \ --H 'Authorization: Bearer ' -``` - -### 响应示例 - -```json -{ - "timestamp": 1648720425599, - "data": [ - { - "name": "post-90s", - "description": "hah", - "count": 0, - "createdAt": 1648720341118 - }, - { - "name": "post-80s", - "description": "post-80s generation", - "count": 0, - "createdAt": 1647512525642 - } - ], - "duration": 1 -} -``` - -## 删除指定的推送标签 - -删除指定的推送标签。每次只能删除单个推送标签。 - -### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/push/label/{labelname} -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :---------- | :----- | :----------------------- | :------- | -| `labelname` | String | 要删除的推送标签的名称。 | 是 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----- | :--- | :----------------------- | -| `data` | JSON | 推送标签成功删除的结果。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X DELETE 'localhost/hx/hxdemo/push/label/post-90s' \ --H 'Authorization: Bearer ' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1648721097405, - "data": "success", - "duration": 0 -} -``` - -## 在推送标签下添加用户 - -为用户分配指定的推送标签。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/label/{labelname}/user -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :---------- | :----- | :--------------- | :------- | -| `labelname` | String | 推送标签的名称。 | 是 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型。请填 `application/json`。 | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :---------- | :--- | :------------------------------------------------- | :------- | -| `usernames` | List | 推送标签下的用户 ID 列表,最多可传 100 个用户 ID。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------- | :--- | :----------------------------------------------------------- | -| `data` | JSON | 用户添加结果。 | -| `success` | List | 列明成功添加的用户 ID。 | -| `fail` | JSON | 返回的用户添加失败的结果,为键值对格式,其中 key 为添加失败的用户 ID,value 为失败原因。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X POST 'localhost/hx/hxdemo/push/label/post-90s/user' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "usernames":["hx1","hx2"] -}' -``` - -### 响应示例 - -```json -{ - "timestamp": 1648721496345, - "data": { - "success": [ - "hx1", - "hx2" - ], - "fail": {} - }, - "duration": 18 -} -``` - -## 查询指定标签下的指定用户 - -查询推送标签是否存在指定用户。若存在,返回该用户的用户 ID 以及为该用户添加标签的时间;若不存在则不返回这些信息。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/push/label/{labelname}/user/{username} -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :---------- | :----- | :---------------- | :------- | -| `labelname` | String | 推送标签的名称。 | 是 | -| `username` | String | 要查询的用户 ID。 | 是 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型。请填 `application/json`。 | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--------- | :----- | :----------------------------------- | -| `data` | JSON | 用户数据。 | -| `username` | String | 要查询的用户 ID。 | -| `created` | Long | 添加用户的 Unix 时间戳,单位为毫秒。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X GET 'localhost/hx/hxdemo/push/label/post-90s/user/hx1' \ --H 'Authorization: Bearer ' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1648721589676, - "data": { - "username": "hx1", - "created": 1648721496324 - }, - "duration": 1 -} -``` - -## 分页查询指定标签下的用户 - -分页查询指定标签下包含的用户。 - -### HTTP 请求 - -```http -GET https://{host}/{org_name}/{app_name}/push/label/{labelname}/user -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :---------- | :----- | :--------------- | :------- | -| `labelname` | String | 推送标签的名称。 | 是 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -### 查询参数 - -| 字段 | 类型 | 描述 | 是否必需 | -| :------- | :----- | :--------------------------------------------------- | :------- | -| `limit` | String | 每次获取的用户数量,取值范围为 [1,100],默认为 100。 | 否 | -| `cursor` | String | 数据查询的起始位置。 | 否 | - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型。请填 `application/json`。 | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :--------- | :----- | :----------------------------------- | -| `cursor` | String | 下次查询的起始位置。 | -| `data` | JSON | 获得的用户的数据。 | -| `username` | String | 获得的该标签下的用户 ID。 | -| `created` | Long | 添加用户的 Unix 时间戳,单位为毫秒。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X GET 'localhost/hx/hxdemo/push/label/post-90s/user?limit=1' \ --H 'Authorization: Bearer ' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1648721736670, - "cursor": "ZWFzZW1vYjpwdXNoOmxhYmVsOmN1cnNvcjo5NTkxNTMwMDM4ODQxMzgwMjc", - "data": [ - { - "username": "hx1", - "created": 1648721496324 - } - ], - "duration": 1 -} -``` - -## 批量移出指定推送标签下的用户 - -一次移除指定推送标签下的单个或多个用户。 - -### HTTP 请求 - -```http -DELETE https://{host}/{org_name}/{app_name}/push/label/{labelname}/user -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :---------- | :----- | :--------------- | :------- | -| `labelname` | String | 推送标签的名称。 | 是 | - -其他参数及说明详见[公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型。请填 `application/json`。 | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :---------- | :--- | :------------------------------------------------- | :------- | -| `usernames` | List | 要移出标签的用户 ID 列表,最多可传 100 个用户 ID。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :-------- | :--- | :----------------------------------------------------------- | -| `data` | JSON | 用户移出标签的结果。 | -| `Success` | List | 被移出标签的用户 ID。 | -| `fail` | JSON | 返回的用户移出标签的结果,为键值对格式,其中 key 为移出失败的用户 ID,value 为失败原因。 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [错误码](#常见错误码) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X DELETE 'localhost/hx/hxdemo/push/label/post-90s/user' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "usernames":["hx1","hx2"] -}' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1648722018636, - "data": { - "success": [ - "hx1", - "hx2" - ], - "fail": {} - }, - "duration": 1 -} -``` - -## 常见错误码 - -调用推送标签管理相关的 REST API 时,若返回的 HTTP 状态码非 200,则请求失败,提示错误。本节列出这些接口的常见错误码。 -| HTTP 状态码 | 错误类型 | 错误提示 | 可能原因 | 处理建议 | -| :----------- | :--- | :------------- | :----------- | :----------- | -| 403 | ServiceNotOpenException | push service not open | 即时推送功能未开通 | 确认并开通即时推送功能。 | -| 403 | LimitException | limit request | 因为数量或其他限制导致请求失败 | 根据返回信息的限制原因处理。 | -| 400 | ResourceNotFoundException | push label not exists of XXX | 即时推送标签不存在 | 检查并修改,使用正确存在的标签名。 | -| 404 | 请求路径不存在 | url is invalid | 请求路径错误 | 检查并修改,使用正确的请求路径。 | -| 5xx | 服务器内部错误 | 任意 | 服务器在尝试处理请求时发生内部错误 | 联系环信技术支持。 | - -其他错误,你可以参考 [错误码](/document/server-side/error.html) 了解可能的原因。 \ No newline at end of file diff --git a/docs/push/push_certificate_config.md b/docs/push/push_certificate_config.md deleted file mode 100644 index 1de2c500..00000000 --- a/docs/push/push_certificate_config.md +++ /dev/null @@ -1,17 +0,0 @@ -## 证书配置 - -环信推送与IM使用相同的SDK,SDK下载地址:[下载页](https://www.easemob.com/download/im) - -Android端推送集成:[Android 推送集成](push_integration_process_android.html) - -iOS端推送集成:[iOS 推送集成](push_integration_process_ios.html) - -### 上传证书 - -进入即时推送页面,进入“配置证书”页面,点击“添加推送证书”进行厂商证书的添加。 - -![img](/images/instantpush/push_certificate_add.png) - -:::tip -Push与IM使用相同的SDK,证书配置可以通用。 -::: \ No newline at end of file diff --git a/docs/push/push_createnotification.md b/docs/push/push_createnotification.md deleted file mode 100644 index 40c302bb..00000000 --- a/docs/push/push_createnotification.md +++ /dev/null @@ -1,70 +0,0 @@ -## 创建推送 - -点击 **即时推送** 的 **创建推送** 页面,即可创建推送任务。 - -环信支持用户创建通知消息及透传消息。 - -- 通知消息:指定通知标题和内容后,由环信SDK自动处理后、在系统通知栏中以通知栏消息的形式展示,同时响铃或震动提醒用户。 -- 透传消息:即自定义消息,消息体格式客户可以自己定义。透传消息环信只传递数据,不做任何处理,客户端接收到透传消息后需要自己去做后续动作处理,如通知栏展示、弹框等。 - -![img](/images/instantpush/push_notification_create.png) - -### 通知消息 - -依次填写内容编辑、推送目标、推送设置的推送配置内容 - -#### 内容编辑: - -- 目标平台(默认选择):支持安卓、iOS 平台 -- 通知栏标题 -- 子标题:只有 iOS 支持 -- 通知内容 - -![img](/images/instantpush/push_notification_edit.png) - -#### 推送目标: - -- 全量用户 -- 指定用户:接收人以英文逗号分开,最多 1000 个接收人 -- 指定标签用户:支持最多选择3个标签,支持交集运算 - -![img](/images/instantpush/push_user_certain.png) - -![img](/images/instantpush/push_user_tagged.png) - -#### 推送设置: - -- 通知图标:支持环信通道 -- 展开样式:支持普通样式、大文本样式、大图片样式(iOS 暂不支持) -- 后续动作:Android 支持启动应用、打开链接、打开特定页面;iOS 环信通道支持启动应用、打开链接;APNs 仅支持启动应用 -- 附加字段 -- 推送时段:选择立即推送或者定时推送(例如 1 个小时之后,一个月之内) -- 离线消息保留时长:离线消息保留时长设置只适用厂商通道,环信通道离线消息保留时长默认7天 -- 通道策略:选择合适的推送发送策略 - - 环信通道优先,在线走环信,离线走厂商(默认策略) - - 只通过第三方厂商推送(失败后直接丢弃) - - 在线或者离线都通过环信通道推送 - - 厂商通道优先,失败时走环信通道 -- 角标数字:该角标为环信通道角标设置 - - 厂商通道仅支持华为 EMUI4.1 以上 - - APNS 仅支持不变和设置数字 - - 选择不变时,表示不改变角标数字(小米设备由于系统控制,无论选择环信通道还是厂商通道下发,默认角标 +1 的效果) -- 提醒方式:设置提醒方式,包含提示音和震动 - -![img](/images/instantpush/push_setting.png) - -另外,推送支持发送预览,Web界面会弹出推送预览界面,点击 **确认推送** 即可。 - -![img](/images/instantpush/push_preview.png) - -推送完成后,在 **推送任务** 推送任务界面查看推送结果 - -### 透传消息 - -透传消息受厂商限制,仅支持环信通道。 - -透传消息可以进行推送目标、推送时间、附加字段的设置。 - -![img](/images/instantpush/push_transparent_message.png) - -同样,透传消息支持 **发送预览** ,推送完成后,在 **推送任务** 推送任务界面查看推送结果。 \ No newline at end of file diff --git a/docs/push/push_createproduct_app.md b/docs/push/push_createproduct_app.md deleted file mode 100644 index 34284999..00000000 --- a/docs/push/push_createproduct_app.md +++ /dev/null @@ -1,58 +0,0 @@ -## 创建产品及应用 - -本文档主要指导您如何在环信推送控制台创建产品和应用,以及如何配置应用。 -创建推送前,需要先进行如下操作: - -![img](/images/instantpush/push_createproduct_app.png) - -### 1、创建环信应用 - -注册环信账号,并登录环信通讯云管理后台:[环信通讯云管理后台](https://console.easemob.com/user/login),点击【添加应用】,根据提示填写应用信息,创建您的第一个应用。 - -![img](/images/instantpush/push_create_app.png) - -### 2、开通PUSH服务 - -APP创建成功后,将显示至【应用列表】中,选中创建的APP,点击其【查看】按钮,为您的APP开通相应业务。 - -![img](/images/instantpush/push_view_app.jpg) - -左侧菜单栏为环信云支持的即时通讯、MQTT、短信服务、实时音视频以及PUSH等业务。 - -这里选中【即时推送】→【服务概览】,点击页面中【立即开通】按钮开通PUSH业务。 - -![img](/images/instantpush/push_enable.png) - -默认开通PUSH免费版,不收取任何费用,如需开通更高版本套餐,请咨询商务经理。 - -### 3、集成环信PUSH服务 - -#### 3.1 SDK下载 - -环信推送与IM使用相同的SDK,SDK下载地址:[SDK下载页](https://www.easemob.com/download/im) 。 - -![img](/images/instantpush/push_sdk_download.png) - -:::tip -环信IM用户可直接使用,无需进行移动端集成。 -::: - -#### 3.2 推送集成 - -详细Android 推送集成参考文档:[Android 推送集成](push_integration_process_android.html) -详细iOS SDK集成参考文档:[iOS SDK集成](push_integration_process_ios.html) - -### 4、配置推送证书 - -点击进入【配置证书】,点击【添加推送证书】进行厂商证书的添加。 -环信PUSH支持全平台系统下发,覆盖谷歌、华为、小米、魅族、OPPO、vivo等主流手机厂商通道,iOS双证书支持。 PUSH与IM使用相同的SDK,证书配置可以通用。 - -![img](/images/instantpush/push_add_certificate.png) - -### 5、绑定推送用户 - -未使用环信IM的用户,需要单独创建用户并进行用户体系集成。 -点击【应用概览】进入【用户认证】界面,点击【创建IM用户】可以在页面中添加用户,也可使用REST API进行用户配置。 -用户体系集成介绍参考文档:[用户体系集成](/document/server-side/account_system.html) - -![img](/images/instantpush/push_bind_user.png) diff --git a/docs/push/push_dynamics.md b/docs/push/push_dynamics.md deleted file mode 100644 index 47b70f6d..00000000 --- a/docs/push/push_dynamics.md +++ /dev/null @@ -1,52 +0,0 @@ -# 产品功能动态 - -本文介绍了每次发布涉及的新增功能、功能优化、重要问题修复及对应的文档,帮助您了解服务的发布动态。 - -## 2022-06-28 - -| 功能名称 | 功能描述 | 功能类型 | 相关文档 | -| -------------------- | ------------ | -------- | -------- | -| 标签推送支持标签运算 | 最多可选择三个标签,标签用户进行交集运算后进行推送 | 新增 | – | - -## 2022-06-08 - -| 功能名称 | 功能描述 | 功能类型 | 相关文档 | -| -------------------- | ------------------------------------------------------------ | -------- | -------- | -| 厂商通道的送达、统计 | 推送统计新增FCM、华为、VIVO厂商通道 魅族添加证书支持推送回执配置 | 新增 | – | - -## 2022-04-25 - -| 功能名称 | 功能描述 | 功能类型 | 相关文档 | -| -------- | ----------------- | -------- | ----------------------- | -| 标签管理 | 支持用户标签自定义,个性化用户属性,方便企业对客户精细化管理。 可以对标签进行创建标签、用户名绑定、用户名解绑、删除标签等操作。 | 新增 | https://docs-im.easemob.com/push/apppush/pushlabel | -| 标签推送 | 支持客户给自己的用户打标签,推送目标支持标签推送 | 新增 | – | -| 透传消息 | 透传消息不会展示到通知栏上,SDK 收到消息内容后透传给 App,需要 App 自行处理 透传消息受厂商限制,仅支持环信通道 | 新增 | – | -| 厂商通道的送达、统计 | 支持查询每条/每天推送任务在各个推送通道(环信、小米、VIVO、魅族、APNs)的发送数-到达数-点击数的转化情况 | 新增 | – | -| sdk关于vivo OPPO推送版本升级 | SDK 所依赖的 OPPO 推送(版本 2.1.0 更新到 版本 3.0.0)和 vivo 推送(版本 2.3.1 更新到 版本 3.0.0.4_484)的 SDK 版本升级 | 升级 | – | - -## 2022-03-15 - -| 功能名称 | 功能描述 | 功能类型 | 相关文档 | -| ---------- | --------------- | -------- | -------- | -| 后续动作设置 | Android支持启动应用、打开链接、打开特定页面 iOS环信通道支持启动应用、打开链接 APNS仅支持启动应用 | 新增 | – | -| 角标设置 | 该角标为环信通道角标设置 厂商通道仅支持华为EMUI4.1以上 APNS仅支持不变和设置数字 选择不变时,表示不改变角标数字(小米设备由于系统控制,无论选择环信通道还是厂商通道下发,默认角标+1的效果) | 新增 | – | -| 离线消息保存时长设置 | 离线消息保留时长只适用厂商通道 | 新增 | – | -| 定时推送 | 定时推送指可在未来某个特定的时间里下发通知消息 | 新增 | – | -| 创建任务显示优化 | 独立的创建推送页面,内容编辑、推送目标、推送设置的独立配置 | 优化 | – | -| 推送预览 | 支持推送任务的发送前预览检查,提升用户体验 | 优化 | – | - -## 2021-10-29 - -| 功能名称 | 功能描述 | 功能类型 | 相关文档 | -| ---------------- | ------------------------------------------------------------ | -------- | -------- | -| push在线推送功能 | 新增环信在线推送通道补充厂商通道推送,支持推送通道策略选择 | 新增 | – | -| 展开样式 | Android支持普通样式、大文本样式、大图片样式 iOS支持普通样式、大文本样式 | 优化 | – | -| 消息提示 | 推送消息支持提示音、震动的选择 | 新增 | – | -| 推送统计 | 在线推送支持送达率、点击率的统计 | 新增 | – | - -## 2021-05-24 - -| 功能名称 | 功能描述 | 功能类型 | 相关文档 | -| ---------------- | ------------------- | -------- | -------- | -| 厂商离线推送功能 | 覆盖谷歌、华为、小米、魅族、OPPO、vivo等主流手机厂商通道,iOS双证书支持 | 新增 | – | -| 推送数据统计 | 1、支持查看各个通道的推送成功数、推送失败数,了解此次推送的成功率; 2、查看推送厂商通道占比 | 新增 | – | \ No newline at end of file diff --git a/docs/push/push_dynamics_android.md b/docs/push/push_dynamics_android.md deleted file mode 100644 index b124573b..00000000 --- a/docs/push/push_dynamics_android.md +++ /dev/null @@ -1,7 +0,0 @@ -# Android SDK 发布动态 - -本文介绍了Android SDK每次发布涉及的新增功能、功能优化、重要问题修复及对应的文档,帮助您了解服务的发布动态。 - -## 2022-07-21 - -全新的SDK:全面重构,将核心通信模块做了更好的封装;简化了接口,接口更清晰,集成更容易。 \ No newline at end of file diff --git a/docs/push/push_dynamics_ios.md b/docs/push/push_dynamics_ios.md deleted file mode 100644 index b2d0d534..00000000 --- a/docs/push/push_dynamics_ios.md +++ /dev/null @@ -1,7 +0,0 @@ -# iOS SDK 发布动态 - -本文介绍了iOS SDK每次发布涉及的新增功能、功能优化、重要问题修复及对应的文档,帮助您了解服务的发布动态。 - -## 2022-07-21 - -全新的SDK:全面重构,将核心通信模块做了更好的封装;简化了接口,接口更清晰,集成更容易。 \ No newline at end of file diff --git a/docs/push/push_global_deployment.md b/docs/push/push_global_deployment.md deleted file mode 100644 index 3a2727ee..00000000 --- a/docs/push/push_global_deployment.md +++ /dev/null @@ -1,15 +0,0 @@ -## 全球化部署 - -随着移动应用国际化趋势日益增长,终端设备的基础属性采集以及运营数据的存储需要符合所在地域的数据保护条例。为此,我们推出符合欧盟《一般数据保护条例》(General Data Protection Regulation,GDPR)规范的全球化部署服务,可实现全球化集群部署、数据存储、合规营销等。 - -### 当申请开通地域 - -为满足不同客户的业务需求,环信在多地部署了数据中心。环信推送目前在国内有国内1区一个集群,境外有新加坡2区、美东1区、法兰克福1区三个集群,不同集群之间数据完全隔离,您可在创建应用时选择**所在地**和**数据中心**。 - -| 服务接入点 | 服务可用范围 | 数据存储地点 | -| ----------- | ------------ | ------------ | -| 国内1区 | 中国大陆 | 北京 | -| 新加坡2区 | 港澳台及境外 | 新加坡 | -| 美东1区 | 港澳台及境外 | 美东 | -| 法兰克福1区 | 港澳台及境外 | 法兰克福 | - diff --git a/docs/push/push_integration_note_android.md b/docs/push/push_integration_note_android.md deleted file mode 100644 index a2212428..00000000 --- a/docs/push/push_integration_note_android.md +++ /dev/null @@ -1,60 +0,0 @@ -# Android 推送集成 - -本文档为IM SDK中关于推送功能的集成说明。 - -## 1、Android SDK 集成 - -环信推送与环信 IM 使用相同的 SDK,你可以参考 IM 文档导入和集成 SDK, 然后注册登录。 - -SDK 导入:[Android SDK 导入](/document/android/quickstart.html#_2-集成-sdk) - -注册登录:[注册登录](/document/android/login.html#用户注册) - -**手机权限** - -需在手机设置允许弹出推送消息通知栏。 - -## 2、在线推送集成 - -### 通知消息 - -通知消息的通知栏提示由 SDK 封装,只需调用对应的 REST API 推送,SDK 收到会弹出对应的通知栏提示。 点击通知栏会根据跳转事件执行对应的操作,如需自己实现点击跳转,可在项目里继承 `EMNotificationIntentReceiver`,重写 `onNotificationClick` 获取 `EMNotificationMessage`,实现自己的跳转逻辑。 - -### 透传消息 - -SDK 收到透传消息时不做处理,需在项目中继承 `EMNotificationIntentReceiver`,重写 `onNotifyMessageArrived` 获取 `EMNotificationMessage`,判断属性 `needNotification` 是 `false`,获取 `extra` 再做处理(`needNotification` 是 `false`,表示是透传消息)。 - -`EMNotificationIntentReceiver` 继承 `EMNotificationIntentReceiver` 实现的 `receiver` 参考: - -``` -public class EasemobReceiver extends EMNotificationIntentReceiver { -@Override -public void onNotifyMessageArrived(Context context, EMNotificationMessage notificationMessage) { - if(!notificationMessage.isNeedNotification()) - { - String params = notificationMessage.getExtras(); // 判断是透传消息,获取附加字段去处理。 - } -} - -@Override -public void onNotificationClick(Context context, EMNotificationMessage notificationMessage) -{ -// 实现自己的通知点击跳转逻辑。 -} -} -``` - -项目清单里配置继承 `EMNotificationIntentReceiver` 实现的 `receiver`: - -``` - - - - - - -``` - -## 3、离线推送集成 - -离线推送需参考环信 IM 的[第三方推送集成](/document/harmonyos/push/push_overview.html),集成各个厂商的推送(如不需要离线推送,可忽略)。 \ No newline at end of file diff --git a/docs/push/push_integration_note_ios.md b/docs/push/push_integration_note_ios.md deleted file mode 100644 index 6e4890d7..00000000 --- a/docs/push/push_integration_note_ios.md +++ /dev/null @@ -1,256 +0,0 @@ -# iOS 推送集成 - -本文档为IM SDK中关于推送功能的集成说明。 - -## iOS SDK 使用须知 - -使用 SDK 之前,你需先创建应用,获取应用的唯一标识 App Key,请参见[创建应用](/product/enable_and_configure_IM.html#创建应用)。 - -环信推送分为在线推送和远程推送,远程推送时通过 APNS 下发,所以你需要配置应用对应的证书,请参见[APNS 推送配置](/document/ios/push/push_apns.html#上传推送证书)。 - -## 集成 SDK - -环信 SDK 支持 pod 方式导入和手动导入两种方式,任选其一即可,下面分别介绍这两种导入方式。 - -**注意** - -自 3.8.7 版本开始,SDK 只支持 iOS 10 及以上版本。 - -### Pod 导入 SDK - -推荐使用 CocoaPods 集成环信 SDK。CocoaPods 提供了一个简单的依赖管理系统,避免手动导入产生的错误(首先需要确认已经安装了 Cocoapods,如果没有安装过 Cocoapods,请参考[安装使用指南](https://www.cnblogs.com/wangluochong/p/5567082.html)。 - -```pod -sudo gem install cocoapods -pod setup -``` - -在 Xcode 项目的根目录下,新建一个空文件,命名为 `Podfile`,向此文件添加以下行: - -```pod -pod 'HyphenateChat' -``` - -在 `Podfile` 目录下,执行以下指令: - -```pod -pod install --repo-update -``` - -执行 `pod install` 后,打开工程目录,找到 `.xcworkspace` 文件运行即可。 - -### 手动导入 - -[下载环信 demo](https://www.easemob.com/download/demo)。 - -开发者最开始集成,如果选择手动导入文件集成的方式,只需要向工程中添 HyphenateChat 就可以,下面会介绍具体的集成方式。 - -demo 中的 SDK 文件夹为 **Hyphenate SDK**,将 SDK 文件夹拖入到工程中,并勾选截图中标注的三项。 - -![img](/images/instantpush/push_iossdk_import.png) - -### 设置工程属性 - -在 Xcode 中,向 **General > Embedded Binaries** 中添加依赖库。 - -:::tip -将**Do Not Embed** 改成**Embed & Sign**。 -::: - -![img](/images/instantpush/push_ios_projectpropertysetting.png) - -## SDK 基础功能 - -环信推送和环信 IM 使用相同的 SDK,使用功能都需要初始化 SDK 并进行登录操作。 - -### 初始化 SDK - -第 1 步:引入相关头文件 `#import `。 - -第 2 步:在工程的 AppDelegate 中的以下方法中,调用 SDK 对应方法。 - -```objectivec -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - //AppKey:注册的 AppKey,详细见下面注释。 - //apnsCertName:推送证书名(不需要加后缀),详细见下面注释。 - EMOptions *options = [EMOptions optionsWithAppkey:@"easemob-demo#easeim"]; - options.apnsCertName = @"EaseIM_APNS_Developer"; - [[EMClient sharedClient] initializeSDKWithOptions:options]; - - return YES; -} - -// APP 进入后台。 -- (void)applicationDidEnterBackground:(UIApplication *)application -{ - [[EMClient sharedClient] applicationDidEnterBackground:application]; -} - -// APP 将要从后台返回。 -- (void)applicationWillEnterForeground:(UIApplication *)application -{ - [[EMClient sharedClient] applicationWillEnterForeground:application]; -} -``` - -调用的 SDK 接口参数解释如下: -- App Key: 区别 APP 的标识,请参考[开发者注册及管理后台](https://docs-im.easemob.com/im/quickstart/guide/experience#注册并创建应用)。 -- apnsCertName: iOS 中推送证书名称,请参考[制作与上传推送证书](https://docs-im.easemob.com/im/ios/apns/deploy)。 - -### SDK 登录流程 - -登录:调用 SDK 的登录接口进行的操作。建议使用异步登录方法,防止网络不好的情况下,出现卡 UI 主线程的情况出现。 - -```objectivec -[[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111" completion:^(NSString *aUsername, EMError *aError) { - if (!aError) { - NSLog(@"登录成功"); - } else { - NSLog(@"登录失败的原因---%@", aError.errorDescription); - } -}]; -``` - -有关更多注册登录等基础功能,请参考[iOS SDK基础功能](https://docs-im.easemob.com/im/ios/sdk/basic)。 - -## SDK 推送集成 - -##### 1.注册开启推送通知 - -```objectivec -if (NSClassFromString(@"UNUserNotificationCenter")) { - //注册推送,用于 iOS 10 及以上版本。 - [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError *error) { - if (granted) { - dispatch_async(dispatch_get_main_queue(), ^{ - [application registerForRemoteNotifications]; - }); - } - }]; - return; - } - - if([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { - //iOS 8 至 iOS 10 推送样式设置。 - UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; - UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil]; - [application registerUserNotificationSettings:settings]; - } - - if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) { - //注册推送,用于 iOS 8 及以上版本。 - [application registerForRemoteNotifications]; - } else { - //注册推送,用于 iOS 8 之前版本。 - UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert; - [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes]; - } -``` - -##### 2.将获得的 deviceToken 传到 SDK - -:::tip -如果是 iOS 13 及以上的系统,请将 SDK 更新至 v3.6.4 或以上版本。 -::: - -```objectivec -// 将获得的 deviceToken 传给 SDK。 -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken -{ - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[EMClient sharedClient] bindDeviceToken:deviceToken]; - }); -} -``` - -3.开启环信推送处理 - -```objectivec -[[EMLocalNotificationManager sharedManager] launchWithDelegate:self]; -``` - -##### 4.处理代理 - -如果你需要推送相关信息,可以通过实现代理获取,环信提供的代理如下: - -方式一 - -实现以下两个代理,通过 completionHandler 您可以更改通知方式: - -```objectivec -- (void)emuserNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler -{ - NSDictionary *userInfo = notification.request.content.userInfo; - if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { - NSLog(@"APNS userInfo : %@ ",userInfo); - }else{ - NSLog(@"EaseMob userInfo : %@ \n ext : %@",userInfo,userInfo[@"ext"]); - } - completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);//通知方式 可选 badge,sound,alert 如果实现了这个代理方法,则必须有 completionHandler 回调。 -} - -- (void)emuserNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler -{ - NSDictionary *userInfo = response.notification.request.content.userInfo; - if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { - NSLog(@"APNS userInfo : %@ \n ",userInfo); - }else{ - NSLog(@"EaseMob userInfo : %@ \n ext : %@",userInfo,userInfo[@"ext"]); - } - completionHandler();//如果实现了这个代理方法 ,则必须有 ''%%completionHandler%%'' 回调。 -} -``` - -方式二 - -通过下面代理获取推送相关信息: - -```objectivec -//如果需要获取数据,只实现这一个代理方法即可。 -- (void)emGetNotificationMessage:(UNNotification *)notification state:(EMNotificationState)state -{ - NSDictionary *userInfo = notification.request.content.userInfo; - if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { - //APNS 推送。 - NSLog(@"APNS userInfo : %@ \n ",userInfo); - }else{ - //本地推送。 - NSLog(@"userInfo : %@ \n ext : %@",userInfo,userInfo[@"ext"]); - } - - if (state == EMDidReceiveNotificationResponse) { - //打开通知 可通过扩展字段自己实现跳转。 - }else{ - //展示通知。 - } -} -``` - -推送通知透传消息获取 - -```objectivec -//当应用收到环信推送透传消息时,此方法会被调用。 -- (void)emDidReceivePushSilentMessage:(NSDictionary *)messageDic -{ - NSLog(@"emDidReceivePushSilentMessage : %@",messageDic); -} -``` - -##### 5.进阶 - -iOS 的本地通知管理模块 `UNUserNotificationCenter` 是单例,一个 App 中只能有一个实例。如果在启用 SDK 在线推送后,App 又重写了 `[UNUserNotificationCenter currentNotificationCenter].delegate`,会将 SDK 中的 delegate 覆盖,此时,需要在 App 实现的 `UNUserNotificationCenterDelegate` 中调用 SDK 的相关处理,过程如下: - -```objectivec -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler -{ - [[EMLocalNotificationManager sharedManager] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler]; -} - -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler -{ - [[EMLocalNotificationManager sharedManager] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; -} -``` - -环信推送和 IM 使用相同的 SDK,可以查看 IMSDK [更多推送功能](https://docs-im.easemob.com/im/ios/apns/offline)。 \ No newline at end of file diff --git a/docs/push/push_integration_process_android.md b/docs/push/push_integration_process_android.md deleted file mode 100644 index 03daeace..00000000 --- a/docs/push/push_integration_process_android.md +++ /dev/null @@ -1,141 +0,0 @@ -# Push Android SDK 集成 - -Push Android SDK 支持使用 mavenCentral 自动集成和手动集成。 - -## 使用 mavenCentral 自动集成 - -1. 首先在你的项目根目录 `build.gradle` 文件里配置 `mavenCentral`。 - -```gradle -buildscript { - repositories { - jcenter() - mavenCentral() - } - ...... -} - -allprojects { - repositories { - jcenter() - mavenCentral() - } -} -``` - -1. 在你的 module 的 `build.gradle` 中添加依赖。 - -```gradle -dependencies { -...... - -implementation 'io.hyphenate:hyphenate-push:1.0.0' -} -``` - -## 手动集成 - -1. [下载 push sdk 压缩包](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/android-push-sdk-1.0.0.zip)。 -2. 解压之后将,将 jar 包和 so 文件放入项目里。 - -### 配置APPKEY - -需在AndroidManifest.xml里配置AppKey - -``` - - //org#app替换为申请的AppKey -``` - -### 初始化 - -```java -EMPushClientOptions options = new EMPushClientOptions(); -//启用厂商推送,参考 IM 文档集成厂商推送。启用推送 API 如下: -EMPushConfig.Builder builder = new EMPushConfig.Builder(context); -builder.enableFCM(senderId); -builder.enableHWPush(); -builder.enableMiPush(appId, appKey); -builder.enableMeiZuPush(appId, appKey); -builder.enableOppoPush(appKey, appSecret); -builder.enableVivoPush(); -options.setEMPushConfig(builder.build()); - -EMPushClient.getInstance().init(this, options); -``` - -### 注册、登录和注销用户 - -注册模式分两种,开放注册和授权注册。只有开放注册时,才可以客户端注册。 - -强烈建议开发者通过后台调用 REST 接口注册环信用户 ID,不建议使用客户端注册。 - -1. 注册用户。 - -```java -//注册失败会抛出 HyphenateException。 -EMPushClient.getInstance().registerWithUsername(username, pwd);//同步方法,需在子线程里执行 -``` - -1. 注册连接状态监听。 - -```java -EMPushClient.getInstance().addConnectionListener{ - @Override - public void onConnected() { - - } - - @Override - public void onDisconnected(int error) { - - } -} -``` - -1. 登录连接服务器 - -```java -EMPushClient.getInstance().connectWithUsername(username, password, new EMCallBack(){}); -``` - -1. 注销登录 - -```java -EMPushClient.getInstance().disconnect(true, new EMCallBack(){}); -``` - -## 点击事件上报 - -厂商推送的点击事件上报,需要在 App 端调用 API 上报实现统计。 - -```java -//taskId 与 provider 需从推送数据里获取,如果获取 taskId 失败则传空字符串 -EMPushClient.getInstance().reportPushAction(taskId, provider, action, new EMCallBack(){}); -``` - -以小米推送为例,在厂商的点击回调里去解析上报点击事件。 - -```java -public void onNotificationMessageClicked(Context context, MiPushMessage message) { - - String content = message.getContent(); - try { - // JSON 结构为 {"EPush":{"provider":{"xxx"},"report":{"task_id":"xxx"}}} - JSONObject json = new JSONObject(content); - JSONObject pushJson = json.optJSONObject("EPush"); - String taskId = ""; - if(pushJson != null){ - String provider = pushJson.optString("provider"); - JSONObject reportJson = pushJson.optJSONObject("report"); - if(reportJson != null){ - taskId = reportJson.optString("task_id"); - } - - EMPushClient.getInstance().reportPushAction(taskId, provider, EMPushManager.EMPushAction.CLICK, new EMCallBack() {}); - } - } catch (JSONException e) { - e.printStackTrace(); - } -} -``` \ No newline at end of file diff --git a/docs/push/push_integration_process_ios.md b/docs/push/push_integration_process_ios.md deleted file mode 100644 index 992178fd..00000000 --- a/docs/push/push_integration_process_ios.md +++ /dev/null @@ -1,125 +0,0 @@ -# 环信 EMPush iOS 集成 - -本文介绍如何集成环信推送 EMPush iOS SDK。 - -## 前提条件 - -系统版本要求: - -EMPush 支持 iOS 10.0 及以上系统版本。 - -## 集成 EMPush iOS SDK - -EMPush iOS SDK 支持使用 pod 集成或本地集成。 - -### 一、导入 iOS EMPush SDK - -#### 安装 Cocoapods 工具 - -1. 开始前确保你已安装 Cocoapods。参考 [Getting Started with CocoaPods](https://guides.cocoapods.org/using/getting-started.html#getting-started) 安装说明。 -2. 在终端里进入项目根目录,并运行 `pod init` 命令。项目文件夹下会生成 `Podfile` 文件。 - -#### pod 方式集成 EMPush - -1. 打开 `Podfile` 文件,添加 EPush 依赖。 - -注意将 `ProjectName` 替换为你的 target 名称。 - -```pod -platform :ios, '11.0' - -# Import CocoaPods sources -source 'https://github.com/CocoaPods/Specs.git' - -target 'ProjectName' do - pod 'EPush' -end -``` - -2. 在终端 Terminal cd 到 `podfile` 文件所在目录,执行如下命令集成 SDK。 - -```pod -pod install -``` - -3. 成功安装后,Terminal 中会显示 `Pod installation complete!`。此时项目文件夹下会生成一个 `xcworkspace` 文件。 - -4. 打开新生成的 `xcworkspace` 文件运行项目。 - -#### 本地集成 - -##### 手动导入 EMPush iOS SDK - -1. 下载最新版的 [EMpush iOS SDK](https://download-sdk.oss-cn-beijing.aliyuncs.com/downloads/EMPush_iOS/EMPush_1_0_0.zip) 并解压。 -2. 复制 SDK 包中的 `EMPush.framework` 至项目路径。 -3. 打开 Xcode,进入 **TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content**菜单。 -4. 点击 **+ > Add Other… > Add Files** 添加对应动态库,并确保添加的动态库 **Embed** 属性设置为 **Embed & Sign**。 - -添加完成后,项目会自动链接所需系统库。 - -### 二、初始化 - -#### 1. 引入头文件 - -```objectivec -#import -``` - -#### 2. 初始化 EMPush - -```objectivec -EMPushClientOptions *option = [EMPushClientOptions optionsWithAppkey:@"appkey"]; -option.enableConsoleLog = YES; -option.isAutoLogin = YES; -option.apnsCertName = @"apnsname"; -[EMPushClient initializeSDKWithOptions:option launchDelegate:self completion:^(EMError *aError) { - }]; -``` - -#### 3. 注册 - -注册模式分两种,开放注册和授权注册。只有开放注册时,才可以客户端注册。 - -强烈建议开发者通过后台调用 REST 接口去注册环信 ID,不建议使用客户端注册。 - -```objectivec -[EMPushClient registerWithUsername:@"name" password:@"pswd" completion:^(NSString *aUsername, EMError *aError) { - if (!aError) { - // 注册完成。 - } else { - // 注册失败,aError 包含错误原因。 - } - }]; -``` - -#### 4. 连接服务器 - -```objectivec -[EMPushClient connectWithUsername:name password:pswd completion:^(NSString *aUsername, EMError *aError) { - if (!aError) { - // 连接到服务器。 - } else { - // 连接服务器失败,aError 包含错误原因。 - } - }]; -``` - -#### 5. 断开服务器连接 - -```objectivec -[EMPushClient disConnect:YES completion:^(EMError *aError) { - if (!aError) { - // 断开服务器连接。 - } else { - // 断开连接有错误,aError 包含错误原因。 - } - }]; -``` - -#### 6. 添加登录状态代理 - -添加代理的类必须实现 `EMClientDelegate`,进行代理实现。 - -```objectivec -[EMPushClient addConnectDelegate:self delegateQueue:nil]; -``` \ No newline at end of file diff --git a/docs/push/push_notification_config.md b/docs/push/push_notification_config.md deleted file mode 100644 index 0f970a83..00000000 --- a/docs/push/push_notification_config.md +++ /dev/null @@ -1,711 +0,0 @@ -# 配置推送通知 - -本文主要介绍推送通知的结构和字段,建议按需配置。推送通知包含环信提供的基本推送配置以及各厂商的推送配置,默认情况下,后者优先级较高,会覆盖前者。 - -以下为推送通知的结构: - -```json -{ - "title": "环信推送服务", - "content": "你好,欢迎使用环信推送服务", - "subTitle": "环信", - "config": { - "clickAction": { - "url": "https://www.easemob.com" - } - }, - "easemob": { - "style": 2, - "iconUrl": "https://www.easemob.com/statics/common/images/logo.png?20211109", - "bigPicture": "https://www.easemob.com/statics/images/push/case1@2x.png", - "sound": 1, - "vibrate": 1 - }, - "huawei": { - "message": { - "android": { - "category": "IM", - "targetUserType": 1 # 配置华为推送消息为测试类型,可突破分类限制,仅供测试推送收发使用。 - } - } - }, - "honor": { - "androidConfig": { - "androidNotification": { - "importance": "NORMAL" - } - } - }, - "xiaomi": { - "channelId": "{{xiaomi_channel_id}}" # 配置对应平台的通道ID - }, - "oppo": { - "channelId": "{{oppo_channel_id}}" # 配置对应平台的通道ID - }, - "vivo": { - "classification": 1, - "category": "IM" - }, - "apns": { - "contentAvailable": true, - "mutableContent": true - }, - "fcmV1": { - "androidConfig": { - "androidNotification": { - "image": "https://www.easemob.com/statics/common/images/logo.png?20211109" - } - } - }, - "harmonyOS":{ - "title":"鸿蒙推送", - "body":"欢迎测试环信鸿蒙推送", - "image":"https://www.easemob.com/statics/common/images/logo.png?20211109" - } - -} -``` - -环信通道推送通知示例如下: - -![img](/images/instantpush/easemob_example.png) - -FCM 通道推送通知示例如下: - -![img](/images/instantpush/fcm_example.png) - -## 基本推送配置 - -| 字段 | 类型 | 描述 | 支持平台 | 是否必需 | -| :------------------- | :----- | :----------------------------------------------------------- | :------------ | :------- | -| `title` | String | 通知栏展示的通知标题,默认为“您有一条新消息”。该字段长度不能超过 32 个字符(一个汉字相当于两个字符)。 | iOS & Android | 是 | -| `subTitle` | String | 通知栏展示的通知副标题。该字段长度不能超过 10 个字符。 | iOS | 否 | -| `content` | String | 通知栏展示的通知内容。默认为“请及时查看”。该字段长度不能超过 100 个字符(一个汉字相当于两个字符)。 | iOS & Android | 是 | -| `ext` | Object | 推送自定义扩展信息,为自定义 key-value 键值对。键值对个数不能超过 10 且长度不能超过 1024 个字符。 | iOS & Android | 否 | -| `config` | Object | 与用户点击通知相关的操作。以及角标的配置,包含 `clickAction` 和 `badge` 字段。 | iOS & Android | 否 | -| `config.clickAction` | Object | 在通知栏中点击触发的动作,均为字符串类型:
- `url`:打开自定义的 URL;
- `action`:打开应用的指定页面;
- `activity`:打开应用包名或 Activity 组件路径。若不传该字段,默认打开应用的首页。
环信 iOS 推送通道只支持设置为 `url`。 | Android | 否 | -| `config.badge` | Object | 推送角标,包含以下三个字段:
- `addNum`:整型,表示推送通知到达设备时,角标数字累加的值。
- `setNum`:整型,表示推送通知到达设备时,角标数字显示的值。
- `activity`:字符串类型,入口类(华为角标需要配置)。 | Android | 否 | - -## 各厂商推送配置 - -| 字段 | 类型 | 描述 | 是否必需 | -| :-------- | :----- | :----------------------------- | :------- | -| `easemob` | Object | 环信推送 | 否 | -| `apns` | Object | Apple 推送通知服务(APNs) | 否 | -| `fcm` | Object | 谷歌 Firebase 云消息传递 (FCM) | 否 | -| `fcmV1` | Object | 谷歌 Firebase 云消息传递 (FCM) V1 | 否 | -| `xiaomi` | Object | 小米推送。 | 否 | -| `vivo` | Object | vivo 推送。 | 否 | -| `oppo` | Object | OPPO 推送。 | 否 | -| `meizu` | Object | 魅族推送特性。 | 否 | -| `huawei` | Object | 华为推送特性。 | 否 | -| `honor` | Object | 荣耀推送特性。 | 否 | - -### Easemob 推送说明 - -下面为包含大图片的通知的代码示例,你可以按实际需求配置: - -```json -{ - "title": "通知栏显示的通知标题", - "content": "通知栏展示的通知内容", - "subTitle": "通知栏显示的通知副标题", - "iconUrl": "https://docs-im.easemob.com/lib/tpl/bootstrap3_ori/images/logo.png", - "needNotification": true, - "badge": { - "setNum": 0, - "addNum": 1, - "activity": "com.hyphenate.easeim.section.me.activity.AboutHxActivity" - }, - "operation": { - "type": "2", - "openUrl": "https://www.baidu.com/", - "openAction": "com.hyphenate.easeim.section.me.activity.OfflinePushSettingsActivity" - }, - "channelId": "chat", - "channelName": "消息", - "channelLevel": 3, - "autoCancel": 1, - "expiresTime": 1650859482843, - "sound": 0, - "vibrate": 0, - "style": 2, - "bigTxt": "大文本内容", - "bigPicture": "https://docs-im.easemob.com/lib/tpl/bootstrap3_ori/images/logo.png", - "id": 056734579 -} -``` - -推送字段说明如下表所示: - -| 字段 | 类型 | 描述 | 支持平台 | -| :----------------- | :------ | :----------------------------------------------------------- | :------------ | -| `title` | String | 通知栏展示的通知标题。 | iOS & Android | -| `content` | String | 通知栏展示的通知内容。 | iOS & Android | -| `subTitle` | String | 通知栏展示的通知副标题。 | iOS | -| `iconUrl` | String | 推送图标的 URL。 | iOS & Android | -| `needNotification` | boolean | 是否弹出通知:
- (默认)`true`:通知消息;
- `false`:透传消息。 | iOS & Android | -| `badge` | Object | 推送角标。详见 [基本推送配置](#基本推送配置)中的角标说明。 | iOS & Android | -| `operation` | Object | 在通知栏中点击触发的动作。 | iOS & Android | -| `operation.type` | Int | 在通知栏中点击触发的动作类型。
- (默认)`0`:启动应用。
- `1`:打开自定义的 URL。需设置 `openUrl` 字段为自定义的 URL,若不设置,点击无效果。
- `2`:打开应用的指定页面。需设置 `openAction` 为打开的应用页面的地址。若不设置,点击无效果。
环信 iOS 推送通道只支持启动应用和打开自定义 URL,因此只能设置为 `0` 和 `1`。| iOS & Android | -| `channelId` | String | 通知渠道 ID,默认为 `chat`。客户端渠道存在则通知。若客户端渠道不存在,则结合 channelName,channelLevel 创建新通道。 | Android | -| `channelName` | String | 通知渠道名称,默认为 `消息`。只有第一次创建通道时使用。 | Android | -| `channelLevel` | Int | 通知级别,只有第一次创建通道时使用。
- `0`:最低;
- `3`:默认;
- `4`:高。 | Android | -| `autoCancel` | Int | 点击通知后是否自动关闭通知栏。
- `0`:否;
- (默认)`1`:是。 | Android | -| `expiresTime` | Long | 通知展示过期的 Unix 时间戳,单位为毫秒,例如 `1650859482843` 表示的时间为 2022-04-25 12:04:42。
计算公式:当前时间戳 + 保留时间。 | iOS & Android | -| `sound` | Int | 声音提醒。
- (默认)`0`:无声音;
- `1`:声音提醒。 | iOS & Android | -| `vibrate` | Int | 振动提醒。
- (默认)`0`:无振动;
- `1`:振动提醒。 | iOS & Android | -| `style` | Int | 展示样式。
-(默认)`0`:普通样式;
- `1`:大文本样式;
- `2`:大图片样式。 | iOS & Android | -| `bigTxt` | String | 大文本内容。该字段仅在 `style` 为 `1` 时需要设置。 | iOS & Android | -| `bigPicture` | String | 大图片 URL。该字段仅在 `style` 为 `2` 时需要设置。 | Android | -| `id` | Long | 通知 ID。默认值为随机数。当 ID 相同时,新通知的内容会覆盖之前的通知。 | iOS & Android | - -### APNs 推送说明 - -| 字段 | 类型 | 描述 | -| :----------------- | :----- | :----------------------------------------------------------- | -| `invalidationTime` | Int | 推送过期时间间隔,单位为毫秒。 | -| `priority` | Int | 通知的优先级。
- `5`:发送通知时会考虑设备电量;
- `10`:立即发送通知。 | -| `pushType` | String | 推送展示类型。在 iOS 13 或 watchOS 6 以上设备支持,只能为 “background” 或 “alert”,默认为 “alert”。 | -| `collapseId` | String | 用于将多个通知合并为用户的单个通知的标识符。 | -| `apnsId` | String | 通知的唯一标识。 | -| `badge` | Int | 应用的图标上方显示的角标数字。 | -| `sound` | String | 设备收到通知时要播放的铃声:
- 设置的铃声最多为 30 秒。若超过该时间,系统会启用默认铃声 `default`;
- 铃声文件只支持 `aiff`、`wav` 和 `caf` 格式,例如 `test.caf`。
- 铃声文件必须放在 app 的 `/Library/Sounds` 目录中。 | -| `mutableContent` | Bool | 是否向推送中增加 `mutable-content` 字段开启 APNs 通知扩展。
- `true`:是;
- `false`:否。 | -| `contentAvailable` | Bool | 是否配置后台更新通知。开启后系统会在后台唤醒您的应用程序,并将通知传递。
- `true`:是;
- `false`:否。 | -| `categoryName` | String | 通知的类型。 | -| `threadId` | String | 通知分组标识符,在应用中唯一。 | -| `title` | String | 通知的标题。 | -| `subTitle` | String | 通知的副标题。 | -| `content` | String | 通知的正文内容。 | -| `titleLocKey` | String | 用于将标题字符串进行本地化的键。 | -| `titleLocArgs` | List | 字符串的数组,用于替换标题字符串中的变量。 | -| `subTitleLocKey` | String | 用于将副标题字符串进行本地化的键。 | -| `subTitleLocArgs` | List | 字符串的数组,用于替换副标题字符串中的变量。 | -| `bodyLocKey` | String | 用于将消息文本进行本地化的键。 | -| `bodyLocArgs` | List | 字符串的数组,用于替换消息文本中的变量。 | -| `ext` | Object | 自定义推送扩展信息。 | -| `launchImage` | String | 要显示的启动图像文件的名称。 | -| `interruptionLevel` | String | 中断等级,详见 [管理通知](https://developer.apple.com/design/human-interface-guidelines/managing-notifications)。
- `ACTIVE`:系统立即显示通知,点亮屏幕,并可播放声音。
- `CRITICAL`:系统立即显示通知,点亮屏幕,并绕过静音开关播放声音。
- `PASSIVE`:系统将通知添加到通知列表中,但不点亮屏幕或播放声音。
- `TIME_SENSITIVE`:系统立即显示通知,点亮屏幕,播放声音,并突破系统通知控制。 | -| `liveActivityEvent` | String | 实时活动,详见[使用 ActivityKit 推送通知启动和更新实时活动](https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications)。
- `START` :开始
- `UPDATE`:更新
- `END`:结束 | -| `timestamp` | Long | 实时活动时间戳。协助始终显示最新的 ActivityKit 推送更新。 | -| `dismissalDate` | Long | 实时活动通知的解除时间戳。
默认情况下,实时活动在结束后会在锁定屏幕上显示长达四个小时,可以自行定义实时窗口自动解除时间。 | -| `staleDate` | Long | 实时活动数据有效期时间戳。
在某些情况下(例如进入没有网络连接的区域),可能无法使用新信息更新实时活动,从而导致其显示过时的数据。若要提供最佳的用户体验并让用户知道实时活动显示过时的信息,请在可选字段中添加此时间戳,以提供系统将实时活动视为过时的时间。每次更新时,都可以携带数据有效期时间戳。 | -| `attributesType` | String | 实时活动动态数据类型。 | -| `attributes` | Object | 实时活动动态数据。| -| `contentState` | Object | 实时活动动态数据结构和内容。| - -### FCM 推送说明 - -| 字段 | 类型 | 描述 | -| :---------------------- | :----- | :----------------------------------------------------------- | -| `condition` | String | 用于确定消息目标的逻辑条件表达式。 | -| `collapseKey` | String | 指定一组可折叠的消息(例如,含有 collapse_key: “Updates Available”),以便当恢复传送时只发送最后一条消息。这是为了避免当设备恢复在线状态或变为活跃状态时重复发送过多相同的消息。 | -| `priority` | String | 消息的优先级,即“normal”(普通)和“high”(高)。在 Apple 平台中,这些值对应于 APNs 优先级中的 5 和 10。 | -| `timeToLive` | String | 设备离线后消息在 FCM 存储空间中保留的时长(以秒为单位)。支持的最长存留时间为 4 周,默认值为 4 周。 | -| `dryRun` | Bool | 是否为测试消息。
- `true`:是。开发者可在不实际发送消息的情况下对请求进行测试。
- `false`:否。 | -| `restrictedPackageName` | String | 应用的软件包名称,其注册令牌必须匹配才能接收消息。 | -| `data` | Object | 自定义推送扩展信息。 | -| `notification` | Object | 用户可见的预定义通知载荷键值对,详见 [FCM 推送通知的字段](#fcm-推送通知的字段) | - -#### FCM 推送通知的字段 - -| 字段 | 类型 | 描述 | -| :----------------- | :----- | :----------------------------------------------------------- | -| `title` | String | 通知栏中展示的通知的标题。 | -| `body` | String | 通知栏中展示的通知的内容。 | -| `androidChannelId` | String | 通知的渠道 ID。
- 应用必须使用此渠道 ID 创建一个渠道,才能收到包含此渠道 ID 的所有通知。
- 如果你不在请求中发送该渠道 ID,或者应用尚未创建所提供的渠道 ID,则 FCM 将使用应用清单文件中指定的渠道 ID。 | -| `icon` | String | 通知图标。 | -| `sound` | String | 设备收到通知时要播放的声音,例如 ring.mp3。声音文件必须放在 app 的 /res/raw/ 目录中。 | -| `tag` | String | 用于替换抽屉式通知栏中现有通知的标识符。 | -| `color` | String | 通知的图标颜色。 | -| `clickAction` | String | 与用户点击通知相关的操作。点击通知时,将会启动带有匹配 intent 过滤器的 Activity。 | -| `titleLocKey` | String | 应用的字符串资源中标题字符串的键,用于将标题文字本地化为用户当前的本地化设置语言。 | -| `titleLocArgs` | List | 将用于替换 `title_loc_key`(用来将标题文字本地化为用户当前的本地化设置语言)中的格式说明符的变量字符串值。 | -| `bodyLocKey` | String | 应用的字符串资源中正文字符串的键,用于将正文文字本地化为用户当前的本地化设置语言。 | -| `bodyLocArgs` | List | 将用于替换 `body_loc_key`(用来将正文文字本地化为用户当前的本地化设置语言)中的格式说明符的变量字符串值。 | - -### FCM V1 推送说明 - -| 字段 | 类型 | 描述 | -| :-------------- | :----- | :----------------------------------------------------------- | -| `type` | Enum | FCM 推送通知类型:`BOTH`、`DATA` 和 `NOTIFICATION`。不同的推送通知类型对应不同的默认选项。详见[在 Android 应用中接收消息](https://firebase.google.cn/docs/cloud-messaging/android/receive)。 | -| `data` | Object | 自定义推送扩展,为键值对格式,例如 `{"k1":"v1", "k2":"v2"}`。 | -| `notification` | Object | 自定义推送内容,详见 [FCM V1 推送通知的字段](#fcm-v1-推送通知的字段)。 | -| `androidConfig` | Object | Android 推送配置,详见 [Android 推送配置](#android-推送配置)。 | -| `webPushConfig` | Object | Web 推送配置,详见 [Web 推送配置](#web-推送配置)。 | -| `apnsConfig` | Object | APNs 推送配置,详见 [APNs 推送配置](#apns-推送配置)。 | -| `options` | Object | 自定义推送配置选项,为键值对格式,例如,{"k1":"v1", "k2":"v2"}。 | -| `condition` | String | 发送推送消息的条件。| - -#### FCM V1 推送通知的字段 - -| 字段 | 类型 | 描述 | -| :------ | :----- | :-------------------------------------------- | -| `title` | String | 推送标题。 | -| `body` | String | 推送内容。 | -| `image` | String | 显示在通知中的图片的 URL。图片不能超过 1 MB。 | - -#### Android 推送配置 - -| 字段 | 类型 | 描述 | -| :-------------------- | :----- | :----------------------------------------------------------- | -| `collapseKey` | String | 消息折叠标识,以便在可以恢复传递时仅发送最后一条消息。在任何指定时间内最多允许使用 4 个不同的折叠键。 | -| `priority` | String | 消息优先级:
- `NORMAL`:普通。
- `HIGH`:高。| -| `ttl` | String | 离线保留时长,默认为 4 周。该参数值的单位为秒,最多可精确到小数点后九位,以 `s` 结尾,例如 `3.5s`。 | -| `androidNotification` | Object | 安卓推送通知。详见 [Android 推送通知的字段](#android-推送通知的字段)。 | -| `directBootOk` | Bool | 如果设置为 `true`,当设备处于直接启动模式时,消息将被允许传送到应用程序。详见[支持直接启动模式](https://developer.android.google.cn/training/articles/direct-boot?hl=zh-cn)。 | - -#### Android 推送通知的字段 - -| 字段 | 类型 | 描述 | -| :------------- | :----- | :--------------------------------------------- | -| `title` | String | 推送标题,覆盖 [FCM V1 推送通知的字段](#fcm-v1-推送通知的字段)中的 `title` 字段。 | -| `body` | String | 推送内容,覆盖 [FCM V1 推送通知的字段](#fcm-v1-推送通知的字段)中的 `body` 字段。 | -| `icon` | String | 通知的图标。默认为应用图标。 | -| `color` | String | 通知的图标颜色,以 #rrggbb 格式表示。 | -| `sound` | String | 通知铃声,声音文件必须位于 /res/raw/。 | -| `tag` | String | 替换标识,如果通知栏已存在相同标识的通知则替换 | -| `image` | String | 显示的图像的 URL,覆盖 [FCM V1 推送通知的字段](#fcm-v1-推送通知的字段)中的 `image` 字段。 | -| `clickAction` | String | 用户点击通知操作。 | -| `bodyLocKey` | String | 推送内容本地化键。 | -| `bodyLocArgs` | Array | 推送内容本地化参数。 | -| `titleLocKey` | String | 推送标题本地化参数。 | -| `titleLocArgs` | Array | 推送标题本地化参数。 | -| `channelId` | String | 通道 ID。 | - -#### Web 推送配置 - -| 字段 | 类型 | 描述 | -| :------------- | :----- | :----------------------------------------------------------- | -| `headers` | Object | web push 协议中定义的 HTTP 标头,例如,`{ "k1": "v1", "k2": "v2"}`。 | -| `notification` | Object | 推送内容, 详见 [FCM V1 推送通知的字段](#fcm-v1-推送通知的字段)。 | - -#### APNs 推送配置 - -| 字段 | 类型 | 描述 | -| :-------- | :----- | :----------------------------------------------------------- | -| `headers` | Object | Apple 推送通知服务中定义的 HTTP 请求标头。详见 [APNs 请求标头](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns)了解支持的标头,例如,`{ "apns-push-type": "alert", "apns-priority": "10"}`。 | -| `payload` | Object | 作为 JSON 对象的 APNs 负载,包括 `aps` 字典和自定义负载。详见[有效负载密钥参考](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification)。例如,`{"aps":{"alert":{"title":"环信推送提醒","subtitle":"环信","body":"欢迎使用环信即时推送服务"}},"EPush":"{}"}`。 | - -### 小米推送说明 - -自定义通道和跳转。 - -```json -{ - "title":"你好,欢迎使用环信", - "content":"你好", - "channelId":"easemob-test", - "notifyEffect":3, - "webUri":"http://www.easemob.com" -} -``` - -推送字段说明: - -| 字段 | 类型 | 描述 | -| :----------------------- | :----- | :----------------------------------------------------------- | -| `title` | String | 通知栏中展示的通知的标题。 该字段长度不能超过 50 字符(一个汉字等于一个字符)。 | -| `description` | String | 通知栏中展示的通知的内容。该字段长度不能超过 128 字符(一个汉字等于一个字符)。 | -| `restrictedPackageNames` | String | 应用包名。 | -| `passThrough` | Int | 是否弹出通知:
- `0`:通知;
- `1`:透传消息。 | -| `payload` | Object | 通知的内容。 | -| `notifyType` | Int | 通知方式。
- `-1`:默认全部;
- `1`:使用默认提示音提示;
- `2`:使用默认振动提示;
- `4`:使用默认 led 灯光提示。 | -| `timeToLive` | Long | 离线保留时长(单位为毫秒)。 | -| `timeToSend` | Long | 定时发送消息。用自 1970 年 1 月 1 日以来 00:00:00.0 UTC 时间表示。 | -| `notifyId` | Int | 相同 notify_id 的通知栏消息会覆盖之前。 | -| `sound` | String | 铃声,例:`"android.resource://" + PACKAGENAME + "/raw/shaking"` | -| `ticker` | String | 开启通知消息在状态栏滚动显示。 | -| `notifyForeground` | String | 开启或关闭 app 在前台时的通知弹出。
- `0`:开启;
- `1`:关闭。 | -| `notifyEffect` | String | 预定义通知栏消息的点击行为。通过设置 `extra.notify_effect` 的值以得到不同的预定义点击行为。
- `1`:通知栏点击后打开 app 的 Launcher Activity;
- `2`:通知栏点击后打开 app 的任一 Activity(intentUri);
- `3`:通知栏点击后打开网页(webUri)。 | -| `intentUri` | String | 当前 app 的组件。当 `notifyEffect` 为 2 时,该参数值的格式为 “intent:#Intent;action=xxxx;end”。 | -| `webUri` | String | 网页。 | -| `flowControl` | Int | 控制是否需要进行平缓发送。 | -| `jobkey` | String | 消息聚合,相同 jobkey 的消息只展示第一条。 | -| `callbackUrl` | String | 回调地址。 | -| `callbackParam` | String | 回调参数。 | -| `callbackType` | Int | 回调类型:
- `1`:送达;
- `2`:点击;
- `3`:送达或点击;
- `16`:设备无效;
- `32`:禁用 PUSH;
- `64`:不符合过滤条件;
- `128`:推送超限;
- `1024`:TTL 过期。 | -| `locale` | String | 可以接收消息的设备的语言范围,用逗号分隔。 | -| `localeNotIn` | String | 不可以接收消息的设备的语言范围,用逗号分隔。 | -| `model` | String | 可以收到消息的设备的机型/品牌/价格范围。 | -| `modelNotIn` | String | 不可以收到消息的设备的机型/品牌/价格范围。 | -| `appVersion` | String | 可以接收消息的 app 版本号。 | -| `appVersionNotIn` | String | 不可以接收消息的 app 版本号。 | -| `connpt` | String | 特定的网络环境下才能接收到消息。目前仅支持指定 ”wifi”。 | -| `onlySendOnce` | String | 值为 `1`时表示消息仅在设备在线时发送一次,不缓存离线消息进行多次下发。 | -| `channelId` | String | [通知类别的 ID。](https://dev.mi.com/console/doc/detail?pId=1163#_11) | - -### vivo 推送说明 - -系统消息,回执和打开网页。 - -```json -{ - "classification": 1, - "extra": { - "callback": "http://www.easemob.com/callback", - "callbackParam": "test push callback" - }, - "skipContent": "http://www.easemob.com", - "skipType": 2 - } -``` - -推送字段说明: - -| 字段 | 类型 | 描述 | -| :---------------- | :----- | :----------------------------------------------------------- | -| `title` | String | 通知栏中展示的通知的标题。该字段长度不能超过 40 字符(一个汉字等于两个字符)。 | -| `content` | String | 通知栏中展示的通知的内容。 该字段长度不能超过 100 字符(一个汉字等于两个字符)。 | -| `notifyType` | Int | 通知类型。
- `1`:无;
- `2`:响铃;
- `3`:振动;
- `4`:响铃和振动。 | -| `timeToLive` | Int | 消息保留时长(单位:秒)。 | -| `skipType` | Int | 点击跳转类型。
- `1`:打开APP首页;
- `2`:打开链接;
- `3`:自定义;
- `4`:打开 app 内指定页面。 | -| `skipContent` | String | 跳转内容。跳转类型为 2 时,跳转内容最大 1000 个字符。跳转类型为 4 时,跳转内容的格式为 “intent:#Intent;component=应用包名/activity类路径;end”。 | -| `networkType` | Int | 网络方式。
- (默认)`-1`:不限;
- `1`:Wi-Fi 下发送。 | -| `classification` | Int | 消息类型。
- `0`:运营类消息;
- `1`:系统类消息。 在环信控制台的 vivo 推送的**添加推送证书**对话框中也可以配置该消息类型,但这里的优先级高于控制台的配置。 | -| `clientCustomMap` | Object | 客户端自定义键值对。 | -| `requestId` | String | 用户请求唯一标识,长度限制为 64 字符。 | -| `pushMode` | Int | 推送模式。
- (默认)`0`:正式推送;
- `1`:测试推送。 | -| `extra` | Object | [推送回调](#vivo-推送回调)。 | -| `category` | String | 二级分类,字段的值详见[二级分类标准 中category说明](https://dev.vivo.com.cn/documentCenter/doc/359)。 1. 填写`category` 后,可以不设置 `classification` 参数,但若设置 `classification`,需保证 `category` 与 `classification` 是正确对应关系,否则推送失败。 2. 该参数请按照消息分类规则填写,且必须大写;若传入无效的值,则推送失败。 | -| `notifyId` | Int | 通知 ID,即通知的唯一标识。若多个消息的通知 ID 相同,到达设备的新消息会覆盖旧消息显示在设备通知栏中。取值范围为:1-2147483647。 | -| `profileId` | String| 关联终端设备登录用户标识,最大长度为 64 字符。| -| `sendOnline` | Bool| 是否在线直推,设置为 `true` 表示是在线直推,`false` 表示非直推。在线直推功能推送时在设备在线下发一次,设备离线直接丢弃。| - -#### vivo 推送回调 - -| 字段 | 类型 | 描述 | -| :-------------- | :----- | :------------------------------- | -| `callback` | String | 回调 URL, 长度限制为 128 字符。 | -| `callbackParam` | String | 回调参数,长度限制为 64 字符。 | - -### OPPO 推送说明 - -标题和跳转: - -```json -{ - "title":"你好,欢迎使用环信推送", - "subTitle":"你好", - "content":"你好先生", - "channelId":"easemob-channel", - "clickActionType":2, - "clickActionUrl":"http://www.easemob.com" -} -``` - -推送字段说明: - -| 字段 | 类型 | 描述 | -| :-------------------- | :----- | :----------------------------------------------------------- | -| `title` | String | 通知栏中展示的通知的标题。该字段长度不能超过 32 字符(一个汉字等于一个字符)。 | -| `subTitle` | String | 通知栏中展示的通知的副标题。 | -| `content` | String | 推送显示内容。 该字段长度不能超过 200 字符(一个汉字等于一个字符)。 | -| `channelId` | String | 通道 ID。 | -| `appMessageId` | String | 同一 message id 只推一次。 | -| `style` | Int | 通知栏样式。
- `1`:标准;
- `2`:长文本;
- `3`:大图。 | -| `clickActionType` | Int | 点击动作类型。
- `0`:启动应用;
- `1`:打开应用内页(activity的intent action);
- `2`:打开网页;
- `4`:打开应用内页(activity);
- `5`:Intent scheme URL。 | -| `clickActionActivity` | String | 应用内页地址【`click_action_type` 为 `1` 或 `4` 时必填,长度限制为 500 字符】 | -| `clickActionUrl` | String | 网页地址【`click_action_type` 为 `2` 与 `5` 时必填,长度限制为 500 字符】 | -| `actionParameters` | Object | 动作参数,打开应用内页或网页时传递给应用或网页。 | -| `offLine` | Bool | 是否进离线消息。
- `true`:是;
- `false`:否。 | -| `offLineTtl` | Int | 离线消息保存时长 (单位为秒) 。 | -| `timeZone` | String | 时区(GMT+08:00)。 | -| `callBackUrl` | String | 回调地址。 | -| `callBackParameter` | String | 回调参数。 | -| `showTtl` | Int | 限时展示(秒) 。 | -| `notifyId` | Int | 通知显示时的唯一标识,实现新的消息覆盖上一条消息功能。 | - -### 魅族推送说明 - -| 字段 | 类型 | 描述 | -| :-------------------- | :----- | :----------------------------------------------------------- | -| `title` | String | 通知栏中展示的通知的标题。该字段长度不能超过 32 字符(一个汉字等于一个字符)。 | -| `content` | String | 通知栏中展示的通知的内容。该字段长度不能超过 100 字符(一个汉字等于一个字符)。 | -| `noticeExpandType` | Int | 展开方式。
- `0`:禁用;
- `1`:文本。 | -| `noticeExpandContent` | String | 展开内容。`noticeExpandType` 为 `1` 时,即为文本时,必填。 | -| `clickType` | Int | 点击动作。
- `0`:打开应用;
- `1`:打开应用页面;
- `2`:打开 H5 地址;
- `3`:应用客户端自定义。 | -| `url` | String | H5 页面地址。 | -| `parameters` | Object | 参数。 | -| `activity` | String | 应用页面地址。 | -| `customAttribute` | String | 应用客户端自定义内容。 | -| `isOffLine` | Bool | 是否进离线消息。
- `true`:是;
- `false`:否。 | -| `validTime` | Int | 有效时长(小时)。 | -| `isSuspend` | Bool | 是否通知栏悬浮窗显示。
- `true`:是;
- `false`:否。 | -| `isClearNoticeBar` | Bool | 是否可清除通知栏。
- `true`:是;
- `false`:否。 | -| `isFixDisplay` | Bool | 是否定时展示。
- `true`:是;
- `false`:否。 | -| `fixStartDisplayDate` | date | 定时展示开始时间。 | -| `fixEndDisplayDate` | date | 定时展示结束时间。 | -| `vibrate` | Bool | 通知方式:是否振动。
- `true`:是;
- `false`:否。 | -| `lights` | Bool | 通知方式:是否闪光。
- `true`:是;
- `false`:否。 | -| `sound` | Bool | 通知方式:是否有声音。
- `true`:是;
- `false`:否。 | -| `notifyKey` | String | 分组合并推送的 key,凡是带有此 key 的通知栏消息只会显示最后到达的一条。 | -| `callback` | String | 回调 URL, 长度限制 128 字符。 | -| `callbackParam` | String | 回调参数,长度限制 64 字符。 | -| `callbackType` | String | int(可选字段),回执类型。
- `1`:送达回执;
- `2`:点击回执;
- (默认)`3`:送达与点击回执。 | - -### 华为推送说明 - -华为自定义铃声样例: - -```json -{ - "message":{ - "android":{ - "notification":{ - "title":"wx1994发来新消息3", - "body":"联系人发来新消息", - "channelId":"hyphenate_offline_push_notification", - "defaultSound":false, - "sound":"/raw/ring", - "importance":"NORMAL" - } - } - } -} -``` - -| 字段 | 类型 | 描述 | -| :------------- | :----- | :----------------------------------------------------------- | -| `validateOnly` | Bool | 是否为测试消息,实际不会下发。
- `true`:是;
- `false`:否。 | -| `message` | Object | 推送消息内容。 | -| `review` | Object | 第三方审核机构审核结果,具体请参考华为官网[Review](https://developer.huawei.com/consumer/cn/doc/development/HMS-References/push-sendapi#Review)的定义。 | - -#### 推送消息结构体 - -| 字段 | 类型 | 描述 | -| :------------- | :----- | :----------------------------------------------------------- | -| `data` | Object | 自定义消息负载。 | -| `notification` | Object | [通知栏消息内容](#通知栏消息内容)。 | -| `android` | Object | [安卓消息推送控制参数](#安卓消息推送控制参数)。 | - -##### 通知栏消息内容 - -| 字段 | 类型 | 描述 | -| :------ | :----- | :------------------------------------- | -| `title` | String | 通知栏消息的标题。 | -| `body` | String | 通知栏消息的内容。 | -| `image` | String | 用户自定义的通知栏消息右侧大图标 URL。 | - -##### 安卓消息推送控制参数 - -| 字段 | 类型 | 描述 | -| :------------------ | :----- | :----------------------------------------------------------- | -| `collapseKey` | Int | 离线消息缓存分组标识。 | -| `urgency` | String | 透传消息投递优先级。 | -| `category` | String | 用于重要优先级的透传消息发送场景标识。 | -| `ttl` | String | 消息缓存时间(单位为秒)。 | -| `biTag` | String | 批量任务消息标识。 | -| `fastAppTargetType` | Int | 快应用发送透传消息时,指定小程序的模式类型。
- `1`:开发态;
- (默认)`2`:生产态。 | -| `data` | String | 自定义消息负载,此处如果设置了 data,则会覆盖 `message.data` 字段。 | -| `notification` | Object | [安卓通知栏消息结构体](#安卓通知栏消息结构体)。 | -| `receiptId` | String| 输入一个唯一的回执 ID 指定本次下行消息的回执地址及配置,该回执 ID 可以在回执参数配置中查看。| -| `targetUserType` | Int |
- `0`:普通消息(默认值);
- `1`:测试消息。每个应用每日可发送该测试消息 500 条且不受每日单设备推送数量上限要求。| - -##### 安卓通知栏消息结构体 - -| 字段 | 类型 | 描述 | -| :------------------ | :----- | :----------------------------------------------------------- | -| `title` | String | 安卓通知栏消息标题。 | -| `body` | String | 安卓通知栏消息内容。 | -| `icon` | String | 自定义通知栏左侧小图标,本地的 /res/raw/,支持的文件格式目前包括 png、jpg。 | -| `color` | String | 自定义通知栏按钮颜色。 | -| `sound` | String | 自定义消息通知铃声,在新创建渠道时有效,此处设置的铃声文件必须存放在应用的/res/raw路径下,例如设置为“/raw/shake”,对应应用本地的/res/raw/shake.xxx文件,支持的文件格式包括mp3、wav、mpeg等,如果不设置使用默认系统铃声。注意:由于铃声是通知渠道的属性,因此铃声仅在渠道创建时有效,渠道创建后,即使设置自定义铃声也不会播放,而使用创建渠道时设置的铃声。 | -| `defaultSound` | Bool | 默认铃声控制开关。
- `true`:打开;
- `false`:关闭。 | -| `tag` | String | 消息标签,同一应用下使用同一个消息标签的消息会相互覆盖,只展示最新的一条。 | -| `clickAction` | Object | [消息点击行为](#自定义消息点击行为)。 | -| `bodyLocKey` | String | 通知显示本地化。 | -| `bodyLocArgs` | List | | -| `titleLocKey` | String | 标题本地化 key。 | -| `titleLocArgs` | List | | -| `multiLangKey` | List | 消息国际化多语言参数。 | -| `channelId` | String | 通道 ID。 | -| `notifySummary` | String | 安卓通知栏消息简要描述。 | -| `image` | String | 自定义的安卓通知栏消息右侧大图标 URL。 | -| `style` | Int | 通知栏样式:
- `0`:默认样式;
- `1`:大文本样式;
- `3`:Inbox样式。 | -| `bigTitle` | String | 安卓通知栏消息大文本标题。 | -| `bigBody` | String | 安卓通知栏消息大文本内容。 | -| `autoClear` | Int | 消息展示时长,超过后自动清除,单位为毫秒。 | -| `notifyId` | Int | 每条消息在通知显示时的唯一标识。实现新的通知栏消息覆盖老的。 | -| `group` | String | 消息分组,将同一组的消息只显示 1 条。 | -| `badge` | Object | [安卓通知消息角标控制](#自定义角标)。 | -| `autoCancel` | Bool | 安卓通知栏消息保持标识,在点击通知栏消息后,消息是否不显示在通知栏。
- `true`:是;
- `false`:否。 | -| `when` | String | 消息的排序时间,安卓通知栏消息根据这个值将消息排序,同时这个时间在通知栏上显示。样例:2014-10-02T15:01:23.045123456Z | -| `importance` | String | Android通知消息分类,决定用户设备消息通知行为,取值如下:
- `LOW`:资讯营销类消息;
- `NORMAL`:服务与通讯类消息。 | -| `useDefaultVibrate` | Bool | 是否使用系统默认振动模式控制开关。
- `true`:是;
- `false`:否。 | -| `useDefaultLight` | Bool | 是否使用默认呼吸灯模式控制开关。
- `true`:是;
- `false`:否。 | -| `vibrateConfig` | String | 安卓自定义通知消息振动模式,每个数组元素按照 “[0-9]+|[0-9]+[sS]|[0-9]+[.][0-9]{1,9}|[0-9]+[.][0-9]{1,9}[sS]“ 格式,取值样例 [“3.5S”,”2S”,“1S”,“1.5S”],数组元素最多支持 10 个,每个元素数值整数大于 0 小于等于 60。 | -| `visibility` | String | 安卓通知栏消息可见性,取值如下:
- `VISIBILITY_UNSPECIFIED`:未指定 `visibility`,效果等同于设置了 `PRIVATE`。
- `PUBLIC`:锁屏时收到通知栏消息,显示消息内容。
- `SECRET`:锁屏时收到通知栏消息,不提示收到通知消息。
- `PRIVATE`:设置了锁屏密码,**锁屏通知**(导航:**设置**--**通知中心**)选择**隐藏通知内容**时收到通知消息,不显示消息内容。
取值说明请参考[锁屏不展示通知内容](https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/push-other#h1-1576835261364)。 | -| `lightSettings` | Object | [自定义呼吸灯模式](#自定义呼吸灯模式)。 | -| `foregroundShow` | Bool | 设备应用在前台时通知栏消息是否前台展示开关。
- `true`:是;
- `false`:否。 | -| `inboxContent` | List | 当 style 为 `3` 时,Inbox 样式的内容(必选),支持最大 5 条内容,每条最大长度 1024 字符。展示效果请参考[Inbox 样式](https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/push-other#inbox_style)章节。 | -| `buttons` | List | [通知栏消息动作按钮](#通知栏消息动作按钮),最多设置 3 个。 | - -##### 通知栏消息动作按钮 - -| 字段 | 类型 | 描述 | -| :----------- | :----- | :----------------------------------------------------------- | -| `name` | String | 按钮名称,必填,最大长度 40 字符。 | -| `actionType` | Int | 按钮动作类型。
- `0`:打开应用首页;
- `1`:打开应用自定义页面;
- `2`:打开指定的网页;
- `3`:清除通知; - `4`:分享功能。 | -| `intentType` | Int | 打开自定义页面的方式:
- `0`:设置通过**intent**打开应用自定义页面;
- `1`:设置通过**action** 打开应用自定义页面;当 `action_type` 为 `1` 时,该字段必填。 | -| `intent` | String | 当 `action_type` 为 `1`,此字段按照 `intent_type` 字段设置应用页面的 uri 或者 action. | -| `data` | String | 最大长度 1024 字符。
- 当字段 `action_type` 为 `0` 或 `1` 时,该字段用于在点击按钮后给应用透传数据,选填,格式必须为 key-value 形式:{“key1”:“value1”,“key2”:“value2”,…}。
- 当 `action_type` 为 `4` 时,此字段必选,为分享的内容。 | - -##### 自定义角标 - -| 字段 | 类型 | 描述 | -| :----------- | :----- | :----------------------------------------------------------- | -| `addNum` | Int | 角标累加数字,大于 0 小于 100 的正整数。 | -| `badgeClass` | String | 应用包名+应用入口 Activity 类名。样例:`com.huawei.codelabpush.MainActivity`。 | -| `setNum` | Int | 角标设置数字,大于等于 0 小于 100 的整数。 | - -##### 自定义消息点击行为 - -| 字段 | 类型 | 描述 | -| :------- | :----- | :----------------------------------------------------------- | -| `type` | Int | 消息点击行为类型。
- `1`:用户自定义点击行为;
- `2`:点击后打开特定 url;
- `3`:点击后打开应用 App。 | -| `intent` | String | 自定义页面中 intent 的实现,当 `type` 为 `1` 时,字段 `intent` 和 `action` 至少二选一。 | -| `url` | String | 设置打开特定 URL,URL 使用的协议必须是 HTTPS 协议。 | -| `action` | String | 设置通过 action 打开应用自定义页面。 | - -##### 自定义呼吸灯模式 - -| 字段 | 类型 | 描述 | -| :----------------- | :----- | :----------------------------------------------------------- | -| `color` | Object | [呼吸灯颜色](#呼吸灯颜色)。 | -| `lightOnDuration` | String | 呼吸灯点亮时间间隔,格式按照 “|[sS]|.|.[sS]”。 | -| `lightOffDuration` | String | 呼吸灯熄灭时间间隔,格式按照 “|[sS]|.|.[sS]”。 | - -##### 呼吸灯颜色 - -| 字段 | 类型 | 描述 | -| :------ | :---- | :------------------------------------------------------ | -| `alpha` | Float | RGB 颜色中的 alpha 设置,默认值为 `1`,取值范围 [0,1]。 | -| `red` | Float | RGB 颜色中的 red 设置,默认值为 `0`,取值范围 [0,1]。 | -| `green` | Float | RGB 颜色中的 green 设置,默认值为 `0`,取值范围 [0,1]。 | -| `blue` | Float | RGB 颜色中的 blue 设置,默认值为 `0`,取值范围 [0,1]。 | - -### 荣耀推送说明 - -```json -{ - "data":{ - "key1":"value1" - }, - "androidConfig":{ - "androidNotification":{ - "title":"honor", - "body":"body", - "clickAction":{ - "type":2, - "url":"https://wwww.easemob.com" - }, - "badgeNotification":{ - "setNum":1, - "badgeClass":"com.hyphenate.chatdemo.section.login.activity.SplashActivity" - } - } - } -} -``` - -#### 推送通知结构体 - -| 字段 | 类型 | 描述 | -| :-------------- | :----- | :----------------------------------------------------------- | -| `data` | Object | 自定义消息负载,为 key-value 格式。 | -| `androidConfig` | Object | [Android消息推送控制参数](#android-消息推送控制参数)。 | - -#### Android消息推送控制参数 - -| 字段 | 类型 | 描述 | -| :-------------------- | :----- | :----------------------------------------------------------- | -| `ttl` | String | 消息缓存时间,单位为秒。 | -| `biTag` | String | 批量任务消息标识,消息回执时会返回给应用服务器。 | -| `data` | String | 自定义消息负载。若设置了该字段,则会覆盖[上层的 data 字段](#推送通知结构体)。 | -| `androidNotification` | Object | [Android 通知栏消息结构体](#android-通知栏消息结构体)。 | - -#### Android通知栏消息结构体 - -| 参数 | 类型 | 描述 | -| :------------------ | :----- | :----------------------------------------------------------- | -| `title` | String | 安卓通知栏消息标题。 | -| `body` | String | 安卓通知栏消息内容。 | -| `clickAction` | Object | [消息点击动作](#通知栏消息单击动作)。 | -| `image` | String | 自定义通知栏消息右侧大图标 URL。 | -| `style` | Int | 通知栏样式:
- `0`:默认样式;
- `1`:大文本样式。 | -| `bigTitle` | String | 大文本标题,当 `style` 为 `1` 时必选。 | -| `bigBody` | String | 大文本内容,当 `style` 为 `1` 时必选。 | -| `importance` | String | Android 通知消息分类,对不同类别消息的默认展示方式、消息样式进行差异化管理:
- `LOW`:资讯营销类消息,包括内容资讯消息和活动营销消息。
- `NORMAL`:服务与通讯类消息,包括社交通讯消息和服务提醒消息。 | -| `when` | String | 通知栏消息的到达时间,为 UTC 时间戳,,例如 2014-10-02T15:01:23.045123456Z。 | -| `buttons` | List | [通知栏消息动作按钮](#通知栏消息行为按钮),最多可设置 3 个。例如,“buttons”:[{“name”:“打开应用”,“actionType”:“1”}]。 | -| `badgeNotification` | Object | [角标控制](#角标控制)。 | -| `notifyId` | Int | 每条消息在通知显示时的唯一标识。新的消息的标识会覆盖上一条消息的标识。 | - -#### 通知栏消息单击动作 - -| 参数 | 是否必选 | 参数类型 | 描述 | -| :------- | :------- | :------- | :----------------------------------------------------------- | -| `type` | 是 | Int | 消息点击行为类型:
- `1`:打开应用自定义页面。
- `2`:点击后打开特定 URL。
- (默认)`3`:点击后打开应用首页。 | -| `intent` | 否 | String | 通过 `intent` 打开应用自定义页面。若 `type` 为 `1`,`intent` 和 `action` 参数至少二选一。 | -| `url` | 否 | String | 设置打开特定 URL,URL 使用的协议必须是 HTTPS 协议。 | -| `action` | 否 | String | 通过 `action` 打开应用自定义页面。 | - -#### 通知栏消息行为按钮 - -| 参数 | 是否必选 | 参数类型 | 描述 | -| :----------- | :------- | :------- | :----------------------------------------------------------- | -| `name` | 是 | String | 按钮名称,最大长度为 40 个字符。 | -| `actionType` | 是 | Int | 按钮动作类型:
- `0`:打开应用首页;
- `1`:打开应用自定义页面;
- `2`:打开指定的页面。 | -| `intentType` | 否 | Int | 打开自定义页面的方式:
- `0`:设置通过 `intent` 打开应用自定义页面;
- `1`:设置通过 `action` 打开应用自定义页面。 当 `actionType` 为 `1` 时,该字段必填。 | -| `intent` | 否 | String |
- 若 `actionType` 为 `1`,按照 `intentType` 字段设置应用页面的 URL 或 `action`。具体设置方式参见打开应用自定义页面。
- 若 `actionType` 为 `2`,此字段设置打开指定网页的 URL,URL 使用的协议必须是 HTTPS 协议,例如,https://example.com/image.png。 | -| `data` | 否 | String | 最大长度为 1024 个字符。 若 `actionType` 为 `0` 或 `1`,该参数用于在点击按钮后给应用透传数据,格式必须为 key-value 形式,例如 {“key1”:“value1”,“key2”:“value2”,…}。 | - -#### 角标控制 - -| 参数 | 是否必选 | 参数类型 | 描述 | -| :----------- | :------- | :------- | :----------------------------------------------------------- | -| `addNum` | 否 | Int | 应用角标累加数字非应用角标实际显示数字,为大于 `0` 小于 `100` 的整数。 | -| `badgeClass` | 是 | String | 应用入口 Activity 类全路径。 例如,com.example.test.MainActivity。 | -| `setNum` | 否 | Int | 角标设置数字,大于等于 `0` 小于 `100` 的整数。如果 `setNum` 与 `addNum` 同时存在时,以 `setNum` 为准。 | - -### 鸿蒙推送说明 - -多行文本推送示例: - -```json -{ - "title": "鸿蒙推送", - "body": "欢迎测试环信鸿蒙推送", - "style": 3, - "inboxContent": [ - "1. 环信通知", - "2. Hello world" - ] -} -``` -推送字段说明如下: - -| 字段 | 类型 | 描述 | -| :-------------- | :----------- | :----------------------------------------------------------- | -| `pushType` | Integer | 推送消息类型:
- (默认)`0`:Alert 消息(通知消息、授权订阅消息)
- `1`:卡片刷新消息
- `2`:通知扩展消息
- `6`:后台消息
- `7`:实况窗更新消息
- `10`:VoIP 呼叫消息 | -| `isTestMessage` | Boolean | 是否是测试消息。 | -| `receiptId` | String | 回执 ID。 | -| `category` | String | 消息分类,默认 `IM`。 | -| `title` | String | 推送通知标题。 | -| `body` | String | 推送通知内容。 | -| `image` | String | 通知右侧大图标 URL,必须是 HTTPS 协议。支持类型 png、jpg、jpeg、heif、gif、bmp。 图片长宽建议小于 128x128 像素,若超过49152 像素,则图片不展示。 | -| `style` | Integer | 通知样式:
- (默认)`0`:普通通知
- `1`:大文本样式
- `3`:多行文本样式 | -| `bigTitle` | String | 大文本标题,当 `style` 为 `1` 时必选。 | -| `bigBody` | String | 大文本内容,当 `style` 为 `1` 时必选。 | -| `inboxContent` | List | 多行文本样式的内容,当 `style` 为 `3` 时,本字段必填,最多支持 3 条内容。
样例:"inboxContent": ["1.content1","2.content2","3.content3"]。 | -| `notifyId` | Integer | 唯一标识,相同覆盖。 | -| `addNum` | Integer | 自增。 | -| `setNum` | Integer | 覆盖,优先级高于 `addNum`。 | -| `actionType` | Integer | 点击行为:
- (默认)`0`:打开应用首页。
- `1`:打开应用自定义页面。 | -| `action` | String | 应用内置页面 `ability` 对应的 `action`。 | -| `uri` | String | 应用内置页面 `ability` 对应的 `uri`。 | -| `data` | Object | 自定义扩展参数。 | -| `payload` | Object | 更多推送类型载体,见[请求体结构说明-场景化消息](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/push-scenariozed-api-request-struct-V5#section25212233520) 注意:推送消息类型非0时使用。 | - diff --git a/docs/push/push_overview.md b/docs/push/push_overview.md deleted file mode 100644 index 334b397f..00000000 --- a/docs/push/push_overview.md +++ /dev/null @@ -1,50 +0,0 @@ -# 产品概述 - -环信即时推送平台,定位于为开发者提供低延时、高送达、高并发、不侵犯用户个人数据的即时推送服务。有效提升活跃度,增加用户粘性,实现业务增长。 - -## 1、应用场景 - -**系统消息通知** -当APP用户相关状态或者系统功能状态变化时候(如好友添加通知、外卖到达通知、预约成功通知等),需要及时告知用户,促使用户完成特定操作,提升用户体验。 - -**活动促销营销** -产品推广和营销活动(如游戏活动、618电商节、双十一等),通过对目标用户进行定向通知栏消息,吸引用户消费,从而提升最终营销活动转化效果。 - -**运营促活推送** -针对不同类型、不同活跃周期的用户,需要进行不同的运营推送促活,如对新用户推送产品引导、对流失用户召回,通过定向主动地进行消息推送,提升次日留存,最终实现活跃用户的增长。 - -**社交互动通知** -通常即时通讯服务中天然具备社交属性,人与人沟通产生的分享、点赞、抢红包行为出现时,针对未打开应用的用户进行推送提醒,能有效提升用户互动频次,增强社交愉悦感。 - -**内容订阅推送** -内容、资讯、视频类 App 需要对读者主动推送用户关注的内容或者热点资讯,可以帮助用户快速获取最新、最热门的信息,同时提升 App 打开率,增加内容消费度,提升用户活跃。 - -## 2、产品功能 - -**多通道厂商下发** -覆盖谷歌、华为、小米、魅族、OPPO、vivo等主流手机厂商通道,iOS双证书支持,合力提升全平台消息送达率,省时省心。 - -**多维度推送统计** -便捷易用的后台界面,无需自行开发,即可完成创建推送、用户管理、推送查看、数据分析全套推送服务,有效提升活跃度,增加用户粘性,实现业务增长。 - -**便捷灵活开放平台** -提供REST接口发送推送,满足灵活使用的需求,轻松实现业务自动触发推送。 - -## 3、产品特性 - -**集成便捷** -集成一套 IM SDK 即可支持即时通讯能力,以及推送运营能力。 - -**极速、稳定、可靠的服务性能** -低延时、高送达、高并发,毫秒级触达目标用户,在线消息保证99.99%送达率; -私有二进制通信协议实现数据传输的全程加密,确保通信安全。 - -**数据安全合规** -环信推送服务聚焦于提供专业的推送服务,SDK 不采集任何用户隐私数据,致力于做干净的推送工具,符合工信部数据隐私协议,让您不再为数据隐私安全发愁。 - -**专业技术支持** -有专业的技术支持团队,及时响应客户的需求和问题。 - -## 4、发送流程 - -[![img](https://docs-im.easemob.com/_media/playground/push/apppush/%E6%8E%A8%E9%80%81%E6%B5%81%E7%A8%8B%E5%9B%BE.png?w=800&tok=99b90d)](https://docs-im.easemob.com/_detail/playground/push/apppush/推送流程图.png?id=push%3Aapppush%3Aintroducton) \ No newline at end of file diff --git a/docs/push/push_send_notification.md b/docs/push/push_send_notification.md deleted file mode 100644 index cc44aa2f..00000000 --- a/docs/push/push_send_notification.md +++ /dev/null @@ -1,503 +0,0 @@ -# 发送推送通知 - -利用 REST 接口可通过以下三种方式使用即时推送服务: -- 使用单接口批量发送推送通知。 -- 通过接口组合发送推送通知,即先创建推送通知,然后创建全量推送任务或者创建列表推送任务。 -- 通过推送标签发送推送通知。 - -**注意:推送任务最多 3 个同时进行,否则接口调用时会报错!** - -**全量推送和列表推送均会创建任务,而推送任务的创建是有时间限制的,推送任务数限制如下:** -- 五分钟内限制创建任务数为 3,可配置;5 分钟内最多可创建 3 个任务。如果超过该任务数,请联系商务。 -- 全量推送创建任务后,限制数增加1,未开始执行的也记录; -- 标签/列表推送创建任务后,限制数加1,执行完成后,限制数减1; -- 所有限制均为 5 分钟,后续可以继续创建。 - -## 公共参数 - -### 请求参数 - -| 参数 | 类型 | 是否必需 | 描述 | -| :--------- | :----- | :------- | :-------------------------------------------------- | -| `host` | String | 是 | 环信即时通讯 IM 分配的用于访问 RESTful API 的域名。 | -| `org_name` | String | 是 | 环信即时通讯 IM 为每个公司(组织)分配的唯一标识。 | -| `app_name` | String | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。 | -| `username` | String | 是 | 用户 ID。 | - -### 响应参数 - -| 参数 | 类型 | 描述| -| :---------- | :--- |:--- | -| `timestamp` | Long | Unix 时间戳,单位为毫秒。 | -| `duration` | Int | 从发送请求到响应的时长,单位为毫秒。| - -## 认证方式 - -环信即时通讯 RESTful API 要求 Bearer HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入如下 Authorization 字段: - -Authorization:`Bearer ${YourAppToken}` - -为提高项目的安全性,环信使用 Token(动态密钥)对即将登录即时通讯系统的用户进行鉴权。即时通讯 RESTful API 推荐使用 app token 的鉴权方式,详见 [使用 app token 鉴权](/document/server-side/easemob_app_token.html)。 - -## 以同步方式发送推送通知 - -调用该接口以同步方式推送消息时,环信或第三方推送厂商在推送消息后,会将推送结果发送给环信服务器。服务器根据收到的推送结果判断推送状态。 - -该接口调用频率默认为 1 次/秒。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/sync/{target} -``` - -#### 路径参数 - -| 参数 | 类型 | 描述 | 是否必需 | -| :------- | :----- | :---------------------- | :------- | -| `target` | String | 接收推送通知的用户 ID。 | 是 | - -其他参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型:`application/json` | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :------------ | :--- | :----------------------------------------------------------- | :------- | -| `strategy` | Int | 推送策略:
-`0`:第三方厂商通道优先,失败时走环信通道。
- `1`:只走环信通道:若用户在线,则直接推送;若用户离线,消息会保留一段时间(视购买的套餐包而定),等用户上线后向其推送消息。若用户在超过消息存储期限时仍为上线,则丢弃消息。
-(默认)`2`:只走第三方厂商通道:若用户离线,消息保留时间视不同厂商而定。若推送失败,直接丢弃推送消息。
- `3`:在线走环信通道,离线走第三方厂商通道。如果厂商推送失败,则等待用户上线后通过环信通道下发。
- `4`:只走环信通道且只推在线用户。离线用户收不到推送通知。 | 否 | -| `pushMessage` | JSON | 推送通知。关于通知内容,请查看 [配置推送通知](push_notification_config.html)。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :---------------- | :----- | :----------------------------------------------------------- | -| `data` | Object | 推送结果。服务器根据推送结果判断推送状态。 | -| `data.pushStatus` | String | 推送状态:
- `SUCCESS`:推送成功;
- `FAIL`:推送失败,即非服务端导致的错误,例如 `bad device token`,表示移动端传给服务端的 device token 错误,对应推送厂商不接受。
- `ERROR`:推送异常,即服务端导致错误,例如连接超时或读写超时。 | -| `data.data` | Object | 绑定推送信息对应平台返回的推送结果数据。 | -| `data.desc` | String | 推送失败描述信息。 | - -其他参数及说明详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST 'http://XXXX/XXXX/XXXX/push/sync/test1' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "strategy": 3, - "pushMessage": { - "title": "环信推送", - "content": "你好,欢迎使用环信推送服务", - "sub_title": "环信" - } -}' -``` - -#### 响应示例 - -1. 推送成功的示例如下: - -```json -{ - "timestamp": 1689154498019, - "data": [ - { - "pushStatus": "SUCCESS", - "data": { - "code": 200, - "data": { - "expireTokens": [], - "sendResult": true, - "requestId": "104410638-fd96648b6bb4344bc4f5e29b158fdb07", - "failTokens": [], - "msgCode": 200 - }, - "message": "Success" - } - } - ], - "duration": 2 -} -``` - -2. 走厂商通道时,因未绑定推送信息导致推送失败的响应示例如下: - -```json -{ - "timestamp": 1689154624797, - "data": [ - { - "pushStatus": "FAIL", - "desc": "no push binding" - } - ], - "duration": 0 -} -``` - -3. 走厂商通道时,因接收推送通知的用户 ID 不存在导致推送失败的响应示例如下: - -```json -{ - "timestamp": 1689154534352, - "data": [ - { - "pushStatus": "FAIL", - "desc": "appUser not exists" - } - ], - "duration": 0 -} -``` - -## 以异步方式向单个用户发送推送通知 - -调用该接口以异步方式向单个用户发送推送通知。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/async/{target} -``` - -#### 路径参数 - -| 字段 | 类型 | 描述 | 是否必需 | -| :------------ | :--- | :------------------------ | :------- | -| `target` | String | 接收推送通知的用户 ID。 | 是 | - -其它参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :------------------ | :------- | -| `Content-Type` | String | 内容类型:`application/json` | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :------------ | :--- | :------------------------ | :------- | -| `strategy` | Int | 推送策略:
-`0`:第三方厂商通道优先,失败时走环信通道。
- `1`:只走环信通道:若用户在线,则直接推送;若用户离线,消息会保留一段时间(视购买的套餐包而定),等用户上线后向其推送消息。若用户在超过消息存储期限时仍为上线,则丢弃消息。
-(默认)`2`:只走第三方厂商通道:若用户离线,消息保留时间视不同厂商而定。若推送失败,直接丢弃推送消息。
- `3`:在线走环信通道,离线走第三方厂商通道。如果厂商推送失败,则等待用户上线后通过环信通道下发。
- `4`:只走环信通道且只推在线用户。离线用户收不到推送通知。 | 否 | -| `pushMessage` | JSON | 推送通知。关于通知内容,请查看 [配置推送通知](push_notification_config.html)。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----------- | :----- | :--------------------------------------- | -| `data` | Object | 异步推送的结果,即成功或失败。 | -| `data.data` | String | 推送通知的内容。 | -| `data.pushStatus` | String | 推送状态:`ASYNC_SUCCESS` 表示推送成功。 | -| `data.desc` | String | 推送结果的相关描述。 | - -其他参数及说明详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST 'http://XXXX/XXXX/XXXX/push/async/test1' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "strategy": 3, - "pushMessage": { - "title": "环信推送", - "content": "你好,欢迎使用环信推送服务", - "sub_title": "环信" - } -}' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1723512536934, - "data": [ - { - "pushStatus": "ASYNC_SUCCESS", - "data": "", - "desc": "success" - } - ], - "duration": 7 -} -``` - -## 以异步方式批量发送推送通知 - -调用该接口以异步方式为指定的单个或多个用户进行消息推送。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/single -``` - -#### 路径参数 - -参数及描述详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :------------------ | :------- | -| `Content-Type` | String | 内容类型:`application/json` | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :------------ | :--- | :------------------------ | :------- | -| `targets` | List | 推送的目标用户 ID。最多可传 100 个。 | 是 | -| `strategy` | Int | 推送策略:
-`0`:第三方厂商通道优先,失败时走环信通道。
- `1`:只走环信通道:若用户在线,则直接推送;若用户离线,消息会保留一段时间(视购买的套餐包而定),等用户上线后向其推送消息。若用户在超过消息存储期限时仍为上线,则丢弃消息。
-(默认)`2`:只走第三方厂商通道:若用户离线,消息保留时间视不同厂商而定。若推送失败,直接丢弃推送消息。
- `3`:在线走环信通道,离线走第三方厂商通道。如果厂商推送失败,则等待用户上线后通过环信通道下发。
- `4`:只走环信通道且只推在线用户。离线用户收不到推送通知。 | 否 | -| `pushMessage` | JSON | 推送通知。关于通知内容,请查看 [配置推送通知](push_notification_config.html)。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :----------- | :----- | :--------------------------------------- | -| `data` | Object | 异步推送的结果,即成功或失败。 | -| `id` | String | 推送的目标用户 ID。 | -| `pushStatus` | String | 推送状态:`ASYNC_SUCCESS` 表示推送成功。 | -| `desc` | String | 推送结果的相关描述。 | - -其他参数及说明详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST 'http://localhost:8099/easemob-demo/testy/push/single' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "targets": [ - "test2" - ], - "pushMessage": { - "title": "Hello", - "subTitle": "Hello", - "content": "Hello", - "vivo": { - - } - } -}' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1619506344007, - "data": [ - { - "id": "test2", - "pushStatus": "ASYNC_SUCCESS", - "desc": "async success." - } - ], - "duration": 14 -} -``` - -## 使用标签推送接口发送推送通知 - -向单个标签内的所有用户推送通知。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/list/label -``` - -#### 路径参数 - -参数及说明详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------------------------------------------- | :------- | -| `Content-Type` | String | 内容类型:`application/json` | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 类型 | 描述 | 是否必需 | -| :------------ | :--- | :----------------------------------------------------------- | :------- | -| `targets` | List | 标签名称。只支持传入单个标签名称。 | 是 | -| `startDate` | String | 推送任务开始时间,格式: yyyy-MM-dd HH:mm:ss,例如 2024-01-01 12:00:00。1. 定时时间只能是 1 小时之后,30 天之内。
2. 定时时间时区判定为服务器所在时区。如果跨服务器时区调用请注意计算准确时间。
| 否 | -| `strategy` | Int | 推送策略:
-`0`:第三方厂商通道优先,失败时走环信通道。
- `1`:只走环信通道:若用户在线,则直接推送;若用户离线,消息会保留一段时间(视购买的套餐包而定),等用户上线后向其推送消息。若用户在超过消息存储期限时仍为上线,则丢弃消息。
-(默认)`2`:只走第三方厂商通道:若用户离线,消息保留时间视不同厂商而定。若推送失败,直接丢弃推送消息。
- `3`:在线走环信通道,离线走第三方厂商通道。如果厂商推送失败,则等待用户上线后通过环信通道下发。
- `4`:只走环信通道且只推在线用户。离线用户收不到推送通知。 | 否 | -| `pushMessage` | JSON | 推送通知。关于通知的内容,请参考[配置推送通知](push_notification_config.html)。 | 是 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 字段 | 类型 | 描述 | -| :------- | :----- | :------------- | -| `data` | Object | 推送任务数据。 | -| `taskId` | Long | 推送任务 ID。 | - -其他参数及说明详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -L -X POST 'http://a1.easemob.com/easemob/easeim/push/list/label' \ --H 'Authorization: Bearer ' \ --H 'Content-Type: application/json' \ --d '{ - "targets": [ - "post-90s" - ], - "strategy": 2, - "pushMessage": { - "title": "Easemob PUSH", - "content": "Welcome to Easemob Push Service", - "sub_title": "Easemob" - } -}' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1650859482843, - "data": { - "taskId": 968120369184112182 - }, - "duration": 0 -} -``` - -## 创建全量推送任务 - -每次调用该接口,服务端会创建一个推送任务,生成推送任务 ID,用于推送任务的数据统计。 - -### HTTP 请求 - -```http -POST https://{host}/{org_name}/{app_name}/push/task -``` - -#### 路径参数 - -参数及说明详见 [公共参数](#公共参数)。 - -#### 请求 header - -| 参数 | 类型 | 描述 | 是否必需 | -| :-------------- | :----- | :----------------------- | :------- | -| `Content-Type` | String | 内容类型:`application/json`。 | 是 | -| `Authorization` | String | `Bearer ${YourAppToken}` Bearer 是固定字符,后面加英文空格,再加上获取到的 app token 的值。 | 是 | - -#### 请求 body - -| 字段 | 是否必需 | 类型 | 备注 | -| :------------ | :------- | :------ | :----------- | -| `startDate` | 否 | String | 推送任务开始时间,格式: yyyy-MM-dd HH:mm:ss,例如 2024-01-01 12:00:00。1. 设置的时间必须为当前时间的 1 小时之后,30 天之内。例如,如果当前时间为 2024-09-01 00:00:00,你设置的时间必须是 2024-09-01 01:00:00 及之后的时间,而且不能超过 2024-10-01 01:00:00。
2. 设置的时间的时区默认为服务器所在时区。如果跨服务器时区调用,请注意计算准确时间。
| -| `strategy` | 否 | integer | 推送策略:
-`0`:第三方厂商通道优先,失败时走环信通道。
- `1`:只走环信通道:若用户在线,则直接推送;若用户离线,消息会保留一段时间(视购买的套餐包而定),等用户上线后向其推送消息。若用户在超过消息存储期限时仍为上线,则丢弃消息。
-(默认)`2`:只走第三方厂商通道:若用户离线,消息保留时间视不同厂商而定。若推送失败,直接丢弃推送消息。
- `3`:在线走环信通道,离线走第三方厂商通道。如果厂商推送失败,则等待用户上线后通过环信通道下发。
- `4`:只走环信通道且只推在线用户。离线用户收不到推送通知。| -| `pushMessage` | 是 | JSON | 推送通知。 | - -### HTTP 响应 - -#### 响应 body - -如果返回的 HTTP 状态码为 `200`,表示请求成功,响应包体中包含以下字段: - -| 参数 | 类型 | 说明 | -| :----- | :--- | :--------------- | -| `data` | Long | 推送任务 ID(后续相关推送结果都是基于任务的,需要保存)。 | - -其他参数及说明详见 [公共参数](#公共参数)。 - -如果返回的 HTTP 状态码非 `200`,表示请求失败。你可以参考 [响应状态码](/document/server-side/error.html) 了解可能的原因。 - -### 示例 - -#### 请求示例 - -```shell -将 替换为你在服务端生成的 App Token -curl -X POST 'http://localhost:8099/easemob-demo/testy/push/task' \ --H 'Content-Type: application/json' \ --H 'Authorization: Bearer ' \ --d '{ - "pushMessage": { - "title": "Hello1234", - "subTitle": "Hello", - "content": "Hello", - "vivo": {} - } -}' -``` - -#### 响应示例 - -```json -{ - "timestamp": 1618817591755, - "data": 833726937301309957, - "duration": 1 -} -``` - -## 常见错误码 - -调用发送推送通知相关的 REST API 时,若返回的 HTTP 状态码非 200,则请求失败,提示错误。本节列出这些接口的常见错误码。 - -| HTTP 状态码 | 错误类型 | 错误提示 | 可能原因 | 处理建议 | -| :----------- | :--- | :------------- | :----------- | :----------- | -| 403 | ServiceNotOpenException | push service not open | 即时推送功能未开通 | 确认并开通即时推送功能。 | -| 403 | LimitException | limit request | 因为数量或其他限制导致请求失败 | 根据返回信息的限制原因处理。 | -| 400 | MessageException | bad_request | 推送消息配置错误 | 检查并修改,使用正确的推送消息体。 | -| 400 | IllegalArgumentException | 任意 | 推送参数配置错误 | 检查并修改,使用正确的对应参数。 | -| 404 | 请求路径不存在 | url is invalid | 请求路径错误 | 检查并修改,使用正确的请求路径。 | -| 5xx | 服务器内部错误 | 任意 | 服务器在尝试处理请求时发生内部错误 | 联系环信技术支持。 | - -其他错误,你可以参考 [错误码](/document/server-side/error.html) 了解可能的原因。 \ No newline at end of file diff --git a/docs/push/push_statistics.md b/docs/push/push_statistics.md deleted file mode 100644 index 10bec268..00000000 --- a/docs/push/push_statistics.md +++ /dev/null @@ -1,22 +0,0 @@ -## 数据统计 - -点击 **即时推送** 的 **数据统计** 页面,可以看到推送的数据统计。 - -环信即时推送平台提供推送信息、推送成功率、推送厂商占比、推送指标等信息。 - -环信 PUSH 提供按天统计的推送详情: - -- 推送成功数、推送失败数、推送未知数 - - 推送失败的原因包含不具备推送条件(如未配置证书、没有绑定设备)以及厂商返回失败(如 bad device token、通道限额等原因) - - 推送未知的原因为环信服务器端未知异常 -- 推送成功率 -- 推送厂商通道占比 - -![img](/images/instantpush/push_statistics_1.png) - -环信 PUSH 提供一定时间段的推送数据及推送指标统计详情: - -- 推送数量:各个通道(全部、环信在线通道、谷歌、华为、小米、魅族、OPPO、VIVO、APNs)的推送详情:推送成功数、推送失败数、推送未知数 -- 推送指标:全部通道(包含环信在线通道、小米、魅族、VIVO、APNS)、环信在线通道、小米、魅族、VIVO、APNS 通道的发送数、送达数、点击数 - -![img](/images/instantpush/push_statistics_2.png) diff --git a/docs/push/push_tag_mgmt.md b/docs/push/push_tag_mgmt.md deleted file mode 100644 index 28113577..00000000 --- a/docs/push/push_tag_mgmt.md +++ /dev/null @@ -1,37 +0,0 @@ -# 标签管理 - -环信即时推送平台支持用户标签自定义,个性化用户属性,方便企业对客户精细化管理。 可以对标签进行创建标签、用户名绑定、用户名解绑、删除标签等操作。 - -![img](/images/instantpush/push_tag_mgmt.png) - -## 创建标签 - -点击 **创建标签** 即可创建标签。 - -- 标签名称:最多支持 20 个字符,支持中英文 -- 标签描述:最多支持 100 个字符 - -![img](/images/instantpush/push_tag_create.png) - -## 用户名绑定标签 - -点击 **用户名绑定** 为标签创建用户,用户名绑定支持手动输入以及文件上传两种方式。 - -- 手动输入:最多填写 100 个用户名,每行代表一个用户,可多次上传 -- 文件上传:支持 csv 格式,单个文件不能超过 2 MB,文件最多 2 万行(超过 2 万行只读取前 2 万数据),可多次上传。 - -**注意:每个标签的用户数上线为 2 万,需要增加标签的用户数可联系商务。** - -![img](/images/instantpush/push_bindtaguser_manual.png) - -![img](/images/instantpush/push_bindtaguser_fileupload.png) - -## 用户名解绑 - -点击 **用户名解绑** 为标签解绑用户,可以选择单个用户进行解绑,也可以选择多个用户进行批量解绑。 - -![img](/images/instantpush/push_tag_unbinduser.png) - -## 删除 - -当标签下没有用户时,标签可以删除。 \ No newline at end of file diff --git a/docs/push/push_task.md b/docs/push/push_task.md deleted file mode 100644 index 326f3b1c..00000000 --- a/docs/push/push_task.md +++ /dev/null @@ -1,19 +0,0 @@ -## 推送任务 - -**推送任务** 页面用于查看历史推送的统计详情。 - -![img](/images/instantpush/push_task_list.png) - -点击 **查看** 可查询具体每个任务的下发状态,每当推送状态变更,环信PUSH都会有相应记录,用户每次更新网页可得到当前实时的推送结果展示。 - -环信PUSH提供的统计维度包括: - -- 推送成功数、推送失败数、推送未知数 - - 推送失败的原因包含不具备推送条件(如未配置证书、没有绑定设备)以及厂商返回失败(如bad device token、通道限额等原因) - - 推送未知的原因为环信服务器端未知异常 -- 数据详情:各个通道(环信在线通道、谷歌、华为、小米、魅族、OPPO、vivo、APNS)的推送详情:推送成功数、推送总数 - - 支持查看各个通道的推送成功数、推送失败数、推送未知数 -- 推送成功率 -- 本次推送涉及到的通道(在线通道、苹果、小米、VIVO、魅族)的送达数、送达率、点击数、点击率 - -![img](/images/instantpush/push_task_statistics.png) \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/README.md b/docs/uikit/chatroomuikit/README.md deleted file mode 100644 index 18796e85..00000000 --- a/docs/uikit/chatroomuikit/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 聊天室 UIKit ---- diff --git a/docs/uikit/chatroomuikit/android/design_guide.md b/docs/uikit/chatroomuikit/android/design_guide.md deleted file mode 100644 index e82556bf..00000000 --- a/docs/uikit/chatroomuikit/android/design_guide.md +++ /dev/null @@ -1,705 +0,0 @@ -# 直播聊天室人机交互界面工具包设计指南 (V1.0.0) - - - -![img](/images/uikit/chatroomdesign/crukcover_ease.png) - -## 0.总的设计原则 - -### 0.1.功能与行为上确保通用、普遍、一般 - -### 0.2.风格上易于自定义 - -### 0.3.在业务形态上尽量不替用户做决定 - -## 1.全局样式(Style) - -### 1.1.UIkit 色彩规范 - -#### 1.1.1.颜色配置说明: - -##### 1.1.1.1.颜色类(Color Class) - -一般颜色类分为八类: -主题色(Theme Color):Primary、 Secondary、Error 三类; -渐变主题色(Primary Gradient)一类(含 8 种); -透明色(Alpha Color):On Light、On Dark 两类; -中性色(Neutral Colors):Neutral、Neutral Special 两类; - -##### 1.1.1.2.颜色模式(Hsla Model) - -颜色模式为比较直观的 hsla 模式: -整个模型是一个圆柱体,圆柱体底面周长划分为 360°,对应不同的色相(Hue); -圆柱体的半径为饱和度(Saturation),圆心为 0(最灰),半径值为 100(最艳); -圆柱体的高为亮度(Lightness),起始点为 0(纯黑色),中心点是 50(标准色,),结束点为 100(纯白色)。 - -##### 1.1.1.3.模型概览: - -![img](/images/uikit/chatroomdesign/cruk1113.png) - -#### 1.1.2.三种主题色(Theme Color)的色彩规范: - -##### 1.1.2.1.关于用户可配项(Hue value): - -用户可设定颜色类的可配项 Hue(0-360)为任意数值,修改后每类颜色的色相会发生变化,以贴合用户场景所需要的主题颜色。 -Hue 值(0-360)与色相的对应关系大致如以下图示所例: - -![img](/images/uikit/chatroomdesign/cruk11211.png) - -用户可依据自身产品的品牌色指定色相数值(Hue),从而确认主题色 Primary(主要用于 UI 组件中关键操作与重要文本展示,如推荐的 action、高亮显示的文本等),以及用于积极提示的 Secondary,和表示警示提示的 Error。 - -![img](/images/uikit/chatroomdesign/cruk11212.png) - -##### 1.1.2.2.关于饱和度(Saturation value): - -饱和度(Saturation)不开放给用户设置,三种主题色 Primary、 Secondary、Error 默认饱和度为 100%,Neutral 默认为 8%,Neutral Special 默认为 36% - -![img](/images/uikit/chatroomdesign/cruk1122.png) - -##### 1.1.2.3.关于亮度级别(Lightness level): - -亮度(Lightness)百分比用户不可随意设置,每个颜色类提供:0(0%) / 1(10%) / 2(20%) / 3(30%) / 4(40%) / 5(50%) / 6(60%) / 7(70%) / 8(80%) / 9(90%) / 95(95%) / 98(98%) / 100(100%)十三个级别供用户可选; - -![img](/images/uikit/chatroomdesign/cruk1123.png) - -##### 1.1.2.4.示例: - -如指定主题色 Primary 色相(Hue)为 203,成功色 Secondary 色相(Hue)为 155,警示色 Error 色相(Hue)为 350,则会生成如下 39 种主题色可供用户在指定 UI 件块(View)颜色时使用: - -![img](/images/uikit/chatroomdesign/cruk1124.png) - -其中,主题色 Primary 的 L5 为亮色模式下的基色(Key Color),L6 为暗色模式下的基色(Key Color)。所有的颜色体系都是依照基色生成。 - -#### 1.1.3.关于渐变主题色(Primary Gradient)的规范: - -渐变主题色是由 Primary 色派生出的渐变色,为线性渐变(Linear Gradient),渐变方向依图示坐标系分为 8 类: - -![img](/images/uikit/chatroomdesign/cruk113.png) - -##### 1.1.3.1.关于渐变色的起始色(Start Color): - -渐变色中 Start Color 规则和 Primary 类的色值保持一致; - -![img](/images/uikit/chatroomdesign/cruk1131.png) - -##### 1.1.3.2.关于渐变色的结束色(End Color): - -End Color 用户可配置色相(Hue),亮度以 0(20%) / 1(30%) / 2(40%) / 3(50%) / 4(60%) / 5(70%) / 6(75%) / 7(80%) / 8(85%) / 9(90%) / 95(95%) / 98(98%) / 100(100%)(对应 Primary 的 13 级亮度梯度值)为固定梯度值 - -以下以 Hue:233 为例,按照 End Color 颜色公式依旧得到 13 级颜色: - -![img](/images/uikit/chatroomdesign/cruk11321.png) - -起始色和结束色结合,得到相应的渐变结果 - -![img](/images/uikit/chatroomdesign/cruk11322.png) - -##### 1.1.3.3.关于渐变主题色可配项(End Color Hue Value): - -用户仅可配置渐变色中 End Color 的色相(Hue)以达成与用户业务场景符合的渐变颜色效果; - -##### 1.1.3.4.举个例子吧: - -用户设置 End Color Hue = 233,选择渐变方向为“↓”,则可得到如下效果: - -![img](/images/uikit/chatroomdesign/cruk11341.png) - -如使用渐变主题色,那么它将替代掉所有应用于背景色的 Primary 色 - -![img](/images/uikit/chatroomdesign/cruk11342.png) - -但一般不替代 UI 件块的前景色,因为没有什么意义,且有干扰文字阅读的可能性 - -![img](/images/uikit/chatroomdesign/cruk11343.png) - -#### 1.1.4.关于透明色(Alpha)的规范: - -##### 1.1.4.1.透明色(Alpha Color): - -在本案内带有透明度的组件仅有弹幕消息背景色、礼物消息背景色、模态背景色、轻提示背景色四种,应用范围有限,所以单独定义两个特殊的颜色类用于以上四种组件:Alpha onlight(hsl0, 0%, 0%) 和 Alpha ondark(hsl0, 0%, 100%),Alpha 值被指定为 0(0.0) / 1(0.1) / 2(0.2) / 3(0.3) / 4(0.4) / 5(0.5) / 6(0.6) / 7(0.7) / 8(0.8) / 9(0.9) / 95(0.95) / 98(0.98) / 100(1.0) 十三个梯度值,共 26 种颜色用例,以调整组件的背景色透明度。 - -![img](/images/uikit/chatroomdesign/cruk1141.png) - -Alpha onlight 和 Alpha ondark 均为默认值,无任何可配置项。 - -### 1.1.5.关于中性色(Neutral Colors): - -#### 1.1.5.1.中性色(Neutral) - -中性色(Neutral)仅有一个可配项:色相(Hue),饱和度(Saturation)固定值为 8,亮度级别(Lightness level)也和主题色相同,分为 0(0%) / 1(10%) / 2(20%) / 3(30%) / 4(40%) / 5(50%) / 6(60%) / 7(70%) / 8(80%) / 9(90%) / 95(95%) / 98(98%) / 100(100%)十三个级别供用户可选; - -![img](/images/uikit/chatroomdesign/cruk1151.png) - -Neutral 和 Primary 的默认 Hue 值(色相)相同,也建议用户设置和主题色相同的 Hue 值已达成主题颜色和无彩色系的配套。但这仅仅是建议; - -#### 1.1.5.2.示例: - -如指定主题色 Primary 色相(Hue)为 203,饱和度(Saturation)固定值为 100%,中性色(Neutral)则也指定色相(Hue)为 203,饱和度(Saturation)固定值为 8%,则得到以下色列可供用户选择使用: - -![img](/images/uikit/chatroomdesign/cruk11521.png) - -其中,L98 为亮色模式下背景色的主色,L1 为亮色模式下前景色的主色;L1 为暗色模式下背景色的主色,L98 为暗色模式下前景色的主色。 - -![img](/images/uikit/chatroomdesign/cruk11522.png) - -### 1.1.6.关于特殊中性色(Neutral Special): - -特殊中性色 Neutral Special 主要用于级别低于 Primary 和 Secondary 的强调信息,如当前页面状态、消息发送者的昵称等。 -Neutral Special 和 Primary 的默认 Hue 值(色相)类似,为近似色,也建议用户设置和主题色近似的 Hue 值已达成主题色和无彩色系的配套。但这仅仅是建议; - -![img](/images/uikit/chatroomdesign/cruk116a.png) - -![img](/images/uikit/chatroomdesign/cruk116b.png) - -#### 1.1.6.1.示例: - -如指定主题色 Primary 色相(Hue)为 203,特殊中性色(Neutral)通过相似色原理(正负 30 度内)指定色相(Hue)为 220,饱和度(Saturation)固定值为 36%,则得到以下色列可供用户选择使用: - -![img](/images/uikit/chatroomdesign/cruk1161.png) - -## 1.2.主题 - -本期主题分为 2 种,每种分明亮(Light mode)和黑暗(Dark)两类。 - -### 1.2.1.圆润主题 - -组件一般采用较大的圆角,柔和轻盈 - -![img](/images/uikit/chatroomdesign/cruk121.png) - -### 1.2.2.硬朗主题 - -组件一般避免比较大的圆,硬朗实在 - -![img](/images/uikit/chatroomdesign/cruk122.png) - -以上两种主题可通过应用渐变主题色(Primary Gradient)得到两外两种渐变色主题。 -至于业务相关的主题,如“社交”、“游戏”、“教育”、“商务”等主题分类,因违反本案的最基本设计原则“在业务形态上尽量不替用户做决定”,所以不在本期考虑范围内。 - -## 1.3.图标(Icon) - -### 1.3.1.图标模板(Template) - -图标参照 Material Icon Font 的模板 ,以 24 为基本栅格,须在安全区域(20x20 的中心区域)内绘制,基本描边控制为 1.5 栅格。 - -![img](/images/uikit/chatroomdesign/cruk131.png) - -### 1.3.2 图标命名(Name) - -为防止将图标语意固定,icon 命名需要尽力避免定义操作行为,而是以“看见什么就是什么“进行命名,方便相同图标在不同操作行为下的复用。 -如 - -![img](/images/uikit/chatroomdesign/cruk132.png) - -## 1.4.字体(Typography) - -### 1.4.1.字族(Font Family) - -#### 1.4.1.1.iOS 字族 - -默认 SF Pro 为基本西文(拉丁字母、希腊字母、西里尔字母等)字体; -默认 SF Arabic、SF Hebrew 等为基本右向左(Dextral-sinistral)文字字体; -默认苹方(PingFang SC、TC、HK)为中文(简体中文、繁体中文、香港繁体中文)字体; - -#### 1.4.1.2.Android 字族 - -默认 Roboto 为基本西文(拉丁字母、希腊字母、西里尔字母等)字体; -默认 Noto Sans Arabic、Noto Sans Hebrew 等为基本右向左(Dextral-sinistral)文字字体; -默认思源黑体(Noto Sans SC、TC、HK)为中文(简体中文、繁体中文、香港繁体中文)字体; - -#### 1.4.1.3.Web 字族 - -默认 Roboto 为基本西文(拉丁字母、希腊字母、西里尔字母等)字体; -默认 Noto Sans Arabic、Noto Sans Hebrew 等为基本右向左(Dextral-sinistral)文字字体; -默认思源黑体(Noto Sans SC、TC、HK)为中文(简体中文、繁体中文、香港繁体中文)字体; - -### 1.4.2.字号(Font Size) - -#### 1.4.2.1.最小字号 - -移动端最小字号为:11;web 端最小字号为:12 - -#### 1.4.2.2.字号规则 - -除移动端最小字号外,字号以 2 为梯度递增: -11,12,14,16,18,20 - -### 1.4.3.字重(Font Weight) - -字重分为标准(Regular, 400)、中等(Medium,510)、加粗(semibold,590)三种; -在一些跨平台框架中,如遇不支持设置非百位整数字重,则取近似值百位整数; -如字族没有 semibold,则以 bold 替换。 - -### 1.4.4.行高(Line height) - -行高依照以下固定值(字号/行高): -11/14,12/16,14/20,16/22,18/26,20/28。 - -### 1.4.5.字体角色(Font Role) - -字体角色分为 3 类: -大标题 Headline、标题 Title、标签 Label、正文 Body -需要注意的是,这些角色只是推荐的角色指示,并不具有完全的指定性,具体使用什么角色的字体需依照所使用的组件的实际情况(组件内信息的层级重要性,越重要的越大越重)而使用。 - -### 1.4.6.字体 Token - -依照依照 4.1-4.5 规则,设定以下西文字体排版 token, - - - -简体中文字体 token 示意 - - - -## 1.5.效果(Effects) - -所应用的效果主要分为两种:背景模糊(Background Blur)和阴影(Shadow) - -### 1.5.1.背景模糊(Background Blur) - -背景模糊主要应用于组件背景色使用 Alpha color 时,如组件背景色的透明度会造成组件前后层级干扰的话,则推荐使用背景模糊解决,比如: - -![img](/images/uikit/chatroomdesign/cruk151.png) - -也应用于模态显示的弹出层的背景虚化; -背景模糊的模糊半径值默认为 20 - -``` -/* bg_blur_modal */ backdrop-filter: blur(20); -``` - -### 1.5.2.阴影(Shadow) - -阴影应用于弹窗(Alert)、浮层(pop)、抽屉(Drawer)等,为区分层级,凸显聚焦的组件。 - -#### 1.5.2.1.阴影型号(Size) - -阴影分为小(small)、中(medium)、大(Large)三种型号,应用于不同尺寸的组件中,总体原则为:越小的组件越推荐使用小的阴影、反之越大的组件推荐使用大的阴影;圆角越小的组件越推荐使用小的阴影、反之亦然。 - -#### 1.5.2.2.阴影 token - -为保证阴影效果自然柔和,每个阴影都有两层不同偏移、不同模糊度、不同透明度的值。同时针对亮色/暗色模式有两套不同颜色的阴影。 - -**Shadow on Light:** - -``` -/* shadow/onlight/large */ -box-shadow: x0 y24 blur36 color(Neutral3) Alpha0.15, x8 y0 blur24 color(Neutral1) Alpha0.1 - -/* shadow/onlight/medium */ -box-shadow: x0 y4 blur4 color(Neutral3) Alpha0.15, x2 y0 blur8 color(Neutral1) Alpha0.1 - -/* shadow/onlight/small */ -box-shadow: x0 y1 blur3 color(Neutral3) Alpha0.15, x1 y0 blur2 color(Neutral1) Alpha0.1 -``` - -![img](/images/uikit/chatroomdesign/cruk1522a.png) - -**Shadow on Dark:** - -``` -/* shadow/onlight/large */ -box-shadow: x0 y24 blur36 color(Neutral4) Alpha0.15, x8 y0 blur24 color(Neutral1) Alpha0.1 - -/* shadow/onlight/medium */ -box-shadow: x0 y4 blur4 color(Neutral4) Alpha0.15, x2 y0 blur8 color(Neutral1) Alpha0.1 - -/* shadow/onlight/small */ -box-shadow: x0 y1 blur3 color(Neutral4) Alpha0.15, x1 y0 blur2 color(Neutral1) Alpha0.1 -``` - -![img](/images/uikit/chatroomdesign/cruk1522b.png) - -## 1.6.圆角(Radius) - -### 1.6.1.一般圆角 - -一般圆角分为 None(r=0)、Extra Small(r=4)、Small(r=8)、Medium(r=12)、Large(r=16)、Extra Large(r=½ Height)六个枚举值, -一般情况下组件的四个圆角为同一值 - -![img](/images/uikit/chatroomdesign/cruk161.png) - -#### 1.6.1.1.Extra Small(r=4) - -通常适用于如下组件 -Button(Small Radius) -Input(Small Radius) -Float(Small Radius) -Message Bubble(Small Radius) -Avatar(Small Radius) -Popover -Global Broadcast(Small Radius) - -#### 1.6.1.2.Small(r=8) - -通常适用于如下组件 -Alert(Small Radius) -Drawer(Small Radius) - -#### 1.6.1.3.Medium(r=12) - -通常适用于如下组件 -本案暂不涉及 - -#### 1.6.1.4.Large(r=16) - -通常适用于如下组件 -Input Area(Large Radius) -Alert(Large Radius) -Drawer(Large Radius) -Float(Large Radius) - -#### 1.6.1.5. Extra Large(r=½ Height) - -通常适用于如下组件 -Input Area(Large Radius) -Alert(Large Radius) -Drawer(Large Radius) -Message Bubble(Large Radius) - -### 1.6.2.特殊圆角 - -特殊圆角应用于有背景色的 IM 聊天消息组件: -Message Bubble(Large Radius) - - - -本案不涉及。 - -# 2.基础组件(Widgets) - -## 2.1.按钮组件(Button) - -按钮组件分为普通按钮、文本按钮、图标按钮三种,每种包含的状态有 Enabled、Hovered(限 web 端) 、Pressed、Loading、Pressed 五种状态,同时分为大、中、小三种按钮尺寸以贴合不同容器的使用。 - -### 2.1.1.普通按钮(Normal) - -普通按钮分主要操作(Primary)和次要操作(Secondary)两种类型。 - -#### 2.1.1.1.主要操作(Primary) - -主要操作用于推荐行为,一般背景色为主题色(Primary5\Primary6)或者渐变主题色,被禁用时置灰显示,圆角可配,依据需要可增加左侧或右侧 icon - -![img](/images/uikit/chatroomdesign/cruk2111.png) - -#### 2.1.1.2.次要操作(Secondary) - -次要操作用于辅助主要操作,一般不单独出现,一般背景色为亮色(Neutral98)或者暗色(Neutral1),同时有描边,被禁用时置灰显示,圆角可配 -依据需要可增加左侧或右侧 icon - -![img](/images/uikit/chatroomdesign/cruk2112.png) - -### 2.1.2.文字按钮(Text) - -文字按钮仅有前景色,也分为主要操作和次要操作,一般用于更频繁的常规操作(如表单填写的下一步、取消,消息的显示、隐藏等)或者在页面有普通按钮(主要操作)时作为更次一级操作出现 - -![img](/images/uikit/chatroomdesign/cruk212.png) - -### 2.1.3.图标按钮(Icon) - -图标按钮为组件位置局促又必须出现按钮时的补充形式,如输入条的键盘切换、顶部条的更多操作、表单填写时的推荐操作、输入框的清空和下拉操作等。 - -![img](/images/uikit/chatroomdesign/cruk213.png) - -需要注意的是,在 web 端,如非特殊说明,图标按钮必须搭配 Popover 使用,以交代清楚按钮的具体操作行为。如: - -![img](/images/uikit/chatroomdesign/cruk213b.png) - -## 2.2.输入框组件(Input) - -输入框为需要输入较少文字时使用的组件。 -也按照所放组件的大小分为大中小三种尺寸可配项,样式上,背景色和描边颜色可开关,圆角可配,状态上分为失焦未填写、失焦填写、聚焦未填写、聚焦填写、禁用填写、禁用未填写六种。 - - - -## 2.3.输入域组件(Input Area) - -输入框为需要输入较多文字时使用的组件。 -在用于输入器的文本输入,和表单中、发布内容时需要填写较多文本时使用,样式上,背景色和描边颜色可开关,圆角可配,可显示最大输入字符数分数。状态上分为失焦未填写、失焦填写、聚焦未填写、聚焦填写、禁用填写、禁用未填写六种。 - - - -## 2.4.头像组件(Avatar) - -头像组件是一类信息数据展示的组件,如用户、某个操作项的头像展示,常放置于个人信息页、与用户相关的列表项中 -头像圆角有两个枚举值:Extra Small(r=4)、Extra Large(r=½ Height)以配合不同主题的使用 -头像的尺寸可以依据所属组件的大小自由配置,但需要注意的是,头像的比例永远是 1:1 - -### 2.4.1.图片头像 - -能读取用户头像信息时展示图片头像。 - -![img](/images/uikit/chatroomdesign/cruk241.png) - -### 2.4.2.字符头像 - -用户未上传头像时显示字符头像,字符头像分为单字符和双字符两种 - -![img](/images/uikit/chatroomdesign/cruk242.png) - -### 2.4.3.组合头像 - -组合头像用于用户未上传数据时的群组聊天自动生成头像 -本案不涉及 - -![img](/images/uikit/chatroomdesign/cruk243.png) - -### 2.4.4.图标头像 - -图标头像用于获取不到用户头像信息的空状态以及表单单项有 icon 时的头像。 - -![img](/images/uikit/chatroomdesign/cruk244.png) - -### 2.4.5.头像徽章 - -头像可配置徽章(Badge)以体现用户的在离线等状态,徽章位置分两种:右下和右上 -本案不涉及 - - - - -## 2.5.操作表单(Action Sheet) - -操作表单是以模态形式展示的多操作项表单,单个操作项分为 Enabled、Pressed、Disabled、Destructive 四种状态,以及 Cancel 特殊类型。同时可配置是否显示 icon、是否有分割线(stroke) -此组件仅限移动端 - - - -## 2.6.浮层菜单(PopMenu) - -浮层菜单是以浮层形式展示的多操作项菜单,单个操作项分为 Enabled、Hovered、Pressed、Focused、Disabled、Destructive 六种状态,同时可配置是否显示 icon、是否有字段 2(Body),样式上可配置单项圆角、是否有分割线(Stroke)。 -此组件仅限 web 端 - -![img](/images/uikit/chatroomdesign/cruk26.png) - -## 2.7.弹窗通知(Alert) - -弹窗通知是一类模态提示,会提示用户正在进行的操作所需的关键信息,如警告等,或需要用户填写关键信息(通过输入框),需用户做出主要操作或次要操作。 -内容上,description 可配、输入框可配、操作项支持最多三个。 -样式上,弹窗的圆角可配,需要注意的是,组件内部的输入框和操作按钮圆角需要同弹窗按钮的圆角适配,以达成风格的一致性。 - -![img](/images/uikit/chatroomdesign/cruk27.png) - -## 2.8.浮层提示(Popover) - -浮层提示为 web 端的非常驻提示信息。仅在鼠标 Hoverd 相关组件时展示,最多支持两个字段(Title 和 Subtitle),因为是浮层提示,背景色需和底色有极大反差,具体表现为:亮色模式上用深色(Neutral1)、暗色模式上用亮色(Neutral98) -且依据需提示内容在页面上的实际位置,分为 10 个方向(上左、上、上右、右上、右、右下、下右、下、下左、左下、左、左上)。 - -![img](/images/uikit/chatroomdesign/cruk28.png) - -## 2.9.表情符号(Emoji) - -### 2.9.1.Twemoji [↗](https://github.com/twitter/twemoji) - -表情使用开源可免费商用的 Twemoji 作为基本表情,默认提供 52 个表情作为内置的表情,用户可根据自己的产品规划从 twemoji 提供的 3,245 个表情中进行替换增减; - -![img](/images/uikit/chatroomdesign/cruk291.png) - -### 2.9.2.表情模版(Emoji Template) - -如用户需替换 Twemoji,或者需要自己创作表情,需依照以下模板进行替换或绘制; - -![img](/images/uikit/chatroomdesign/cruk292.png) - -### 2.9.3.表情组件状态(State) - -表情组件的状态分为以下 4 种: -启用 Enabled、悬停 Hovered(仅限 web 端)、按下 Pressed、聚焦 Focused(本案不涉及) -悬停时,背景色递增一级;按下时,背景色递减一级;聚焦时,背景色转换为 Key Color。 - -![img](/images/uikit/chatroomdesign/cruk293.png) - -# 3.业务组件(Components) - -## 3.1.消息组件(Message) - -本案支持发送文本(含 Emoji)、语音(本期不涉及)、礼物消息、全局广播等消息类型 -样式上所有的配置项都是为要保障消息文本的可阅读性。 - -### 3.1.1.文本消息(Text Message) - -文本消息为用户发送的文字消息展示样式 -样式可配项有:背景色(Alpha0-100)、前景色(Neutral0-100)、圆角、字体的大小(Body Large、Body Medium、Body small)、消息气泡的 Pedding -可增减的显示内容项有:Label、Badge、Avatar,Title 和 Description 为必要内容,显示内容的顺序是不可修改的。 - - - -### 3.1.2.语音消息(Audio Message) - -本期不涉及 - -### 3.1.3.礼物消息(Gift Message) - -礼物消息依据国内国外使用场景的不同,分为两种样式 - -#### 3.1.3.1.非常驻礼物消息样式 - -为国内直播场景常见的样式,可设为 Large、Small 两个尺寸, -默认驻留时间为 3 秒(可配置),事件并发时排队展示,可同时最多展示 2 条礼物消息 - - - -消息气泡的样式可配项有:背景色、前景色、头像圆角(需要注意的是,消息背景圆角和头像圆角配套以达成风格的一致)、背景模糊(防止在语聊房场景下组件重叠带来的阅读困难)。 - -#### 3.1.3.2.常驻礼物消息样式 - - - -样式可配项和信息可配项与文本消息相同,只是增加了消息末尾的贴纸展示。 - -### 3.1.4.消息列(Massage List) - -为消息按照时间顺序组合后浮动在直播流上的组件样式,依据国内外用户习惯不同,分为两类样式 - -#### 3.1.4.1.礼物消息和文本消息分开展示的样式 - - - -此组件默认消息之间的间距为 4(用户可自行配置),文本消息区域整体高度占屏幕比例用户可自行配置。礼物非常驻消息一直显示在区域顶侧。消息列右侧需留出给用户放置自定义消息组件的区域,所以此处消息的左右间距不可配置,固定左侧 16,右侧 78。 - -#### 3.1.4.2.礼物消息和文本消息合并展示的样式 - - - -此组件默认消息之间的间距为 4(用户可自行配置),文本消息区域整体高度占屏幕比例用户可自行配置。消息列右侧需留出给用户放置自定义消息组件的区域,所以此处消息的左右间距不可配置,固定左侧 16,右侧 78。 - -### 3.1.5.消息操作(Message Action) - - - -长按消息弹起 action sheet 显示消息相关操作项,操作列表顶部标题栏显示所操作消息的详情。 - -#### 3.1.5.1.消息的举报表单(Report From) - -举报表单为消息操作的次级别页面,提供选择举报原因的单选项,选项数目可增减,选择后可提交举报。 - - - -### 3.1.6.全局广播(Global Message) - -全局广播为超级管理员发送的所有直播间同时可见的非常驻消息,分为三种类型(具体类型需开发者自行定义)通过左侧图标和背景色示以区分。样式的可配项有:圆角、背景色、前景色,信息展示的可配项有左侧 icon(有或无),以及用户可以在自定义广播类型时修改 icon 资源图。消息仅支持单排显示,广播内容超过一屏显示范围为字幕滚动展示,滚动速率可配。 - - - -此消息在移动端一般出现在视频流的顶部;在 web 端出现在聊天窗的顶部,为浮层展示。 - - - -## 3.2.底部条(Footer Bar) - -底部条为移动端的底部操作项展示区域 -样式上的可配项支持背景色、前景色、圆角、图标可替换,是否添加背景模糊效果 -发送消息 action 为必要项,礼物消息 action 为可选项,另最多支持 4 个用户可定义的 action。 - - - -## 3.3.输入条(Input Bar)和语音发送器(Audio Input) - -输入条为键入文本、发送语音和扩展消息的组件。在移动端点击底部条的发送消息操作触发,和键盘搭配使用;在 web 端为在消息窗内底部常驻显示。 -样式上,输入条支持配置分割线、内部的输入框和按钮支持圆角配置 - -### 3.3.1.文本输入条(Input Bar) - -#### 3.3.1.1.移动端文本输入条(Input Bar) - -移动端文本输入条包含文字输入和至多 4 个的键盘切换操作(包括表情键盘、发送语音两个可配项以及另外两个用户可自定义项),可选配文本或者图标形式的发送按钮。 - - - -文本输入条内的文本输入区域为输入区域组件,当单行文本放不下时,文字可在输入区域内折行,对应的输入区域会累积行高,至多支持 4 行文本区域,输入文本超过 4 行后,文本分页展示,用户可滚动查看所键入的文本。 - - - -样式上支持配置分割线(Stroke)、内部输入区域和发送按钮的圆角、描边(Stroke)、前/背景色。 - - - -#### 3.3.1.2.网页端文本输入条(Input Bar) - -网页端文本输入条包含文字输入和至多 4 个的键盘切换操作(包括表情键盘、发送语音、发送礼物三个可配项以及另外一个用户可自定义项),可选配图标形式的发送按钮。 - - - -文本输入条内的文本输入区域为输入区域组件,当单行文本放不下时,文字可在输入区域内折行,对应的输入区域会累积行高,至多支持 4 行文本区域,输入文本超过 4 行后,文本分页展示,用户可滚动查看所键入的文本。 - - - -### 3.3.2.语音发送器(Audio Input) - -本期不涉及 - -## 3.4.表情键盘(Emoji Pick) - -表情键盘是发送 app 内自建表情的键盘,内容上支持表情个数的增减,底部发送和退格按钮支持修改圆角。同时应满足接入第三方表情/贴纸库。 - -![img](/images/uikit/chatroomdesign/cruk34.png) - -本键盘不同于系统自带的 emoji 输入键盘,通过此组件输入的 emoji 不会同步为系统的 emoji,而是在任何平台同一 app 内均显示 app 内自建的表情符号。为满足版权方面的法律要求,请勿使用非申明开源可免费商用的表情符号(不限资源图或者源码)在 App 中(如:集成苹果表情符号在自己的 app 内,这样或许会导致 App 无法上架苹果应用商店) - -## 3.5.贴纸键盘(Stickers Pick) - -### 3.5.1.单个贴纸(Sticker) - -单个贴纸用以展示单个礼物消息样式,展示的信息有:礼物图片、礼物名称(Title)、礼物价值(Subtitle)。 -礼物图片未读到时显示默认图,礼物价值可配置价值图标。 -单个贴纸状态有 Enabled、Disabled(主要用于慢速发送,需要用户自行实现)、Focused 三种,Focused 时显示发送按钮。 - - - -### 3.5.2.贴纸键盘(Stickers Pick) - -贴纸键盘在本案内主要应用于发送礼物消息。内容上支持礼物类别(横向滑动切换礼物类别)/类别内礼物个数(上下滑动查看更多礼物)的增减。 - - - -## 3.6.成员列表(Member List) - -### 3.6.1.列表筛选(Tab) - -成员列表顶部支持成员类别筛选,可通过点击 tab 或者左右滑动整个列表切换,至少支持一个 tab, tab 超过四个时支持左右滑动 - - - -### 3.6.2.搜索条(Search Bar) - -搜索条一般位于列表顶端,分为 Enabled n‘ unfilled、Enabled n‘ filled、Focused n‘ unfilled、Focused n‘ filled 四种状态,依据所在列表组件性质的不同可配置左侧返回按钮和右侧 action 按钮,样式上可配置分割线、输入框圆角大小、输入框背景色和描边的增减。 - -![img](/images/uikit/chatroomdesign/cruk362.png) - -### 3.6.3.成员列表项(Member Item) - -列表项展示当前成员信息,可展示的信息有徽章(Badge)、头像(Avatar)、用户名(Title)、用户详情(Subtitle),用户名为必要项,其他信息可配置。列表项目右侧支持 action btn,同时列表项支持点击/长按等事件 - - - -样式上,列表项可配置分割线(Stroke),头像支持圆角可配。 - - - -### 3.6.4.列表(Member List) - -将 3.6.1.-3.6.3.组合起来即为整个列表项 - -#### 3.6.4.1.列表整体加载 - - - -#### 3.6.4.2.空列表 - - - -#### 3.6.4.3.列表拉取失败 - - - -#### 3.6.4.4.列表上滑加载 - - - -#### 3.6.4.5.列表展开全屏 - - - -# 4.UI 设计资源 - -设计资源详见 [figma 链接](https://www.figma.com/community/file/1322495388317476706/chatroom-uikit)。 diff --git a/docs/uikit/chatroomuikit/android/roomfeature_common.md b/docs/uikit/chatroomuikit/android/roomfeature_common.md deleted file mode 100644 index b571fdef..00000000 --- a/docs/uikit/chatroomuikit/android/roomfeature_common.md +++ /dev/null @@ -1,111 +0,0 @@ -# ChatroomUIKit 通用特性 - - - -## 创建聊天室 - -ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的 REST API 创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - - - - -## 离开聊天室 - -ChatroomUIKit 提供离开聊天室功能。聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - - - - - - - - - - -## 解散聊天室 - -ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的 REST API 解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - - - - -## 发送弹幕 - -用户在聊天室中向其他成员发送文字和表情的消息。发送消息在聊天室中是沟通和交流的基本行为,它使参与者能够分享信息、表达观点、提问、分享内容或与其他人建立联系。 - -在 UIKit 中,用户通过点击输入框,触发键盘以编辑文本信息,也可以通过点击表情按钮切换键盘,编辑表情信息,然后点击**发送**按钮发送消息。 - -用户可以根据业务需要选择显示或隐藏消息发送时间(HH:MM 格式)、用户标识和用户头像。 - - - - - -## 打赏 - -用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持的行为。当用户认为某个用户或内容值得赞赏时,可以选择打赏的方式给予对方代表着特定金额的虚拟礼物。 - -打赏不仅可以作为对其他用户的鼓励和支持,对于主播和直播平台而言,打赏也成为主要收入来源之一。 - -在 UIKit 中,默认提供了 12 种不同的虚拟礼物。同时,用户可以自定义虚拟礼物的样式、名称和金额。 - - - - - -## 全局广播 - -全局广播即向 App 内所有聊天室中的所有用户发送消息或通知,可用于传达重要信息、公告、提醒或紧急通知等。 - -全局广播通常会使用明显的标识或格式以区别于普通聊天消息,确保用户能够快速识别全局广播。 - -你也可以[调用 REST API 发送聊天室全局广播消息](/document/server-side/message_chatroom.html#发送聊天室全局广播消息)。 - -在 UIKit 中,用户可以自定义全局广播的标识以及发送内容。全局广播消息的默认展示策略如下: - -- 若内容未超过一屏宽,无需滚动,停留 3 秒后消失; -- 若内容超过一屏宽,则需要滚动,先停留 2 秒展示开头部分,然后以每秒 10 个字符的速度进行滚动,滚动完成后再停留 2 秒。 -- 若同时有多条全局广播消息,则按消息发送的时间顺序播放,一条消息滚动完成后再播放下一条。 - - - - - -## 未读消息数 - -聊天室未读消息数指在一个聊天室中用户尚未读取的消息数量。在 UIKit 中,当用户滑动屏幕回看消息时,消息区域定位将会变更,此时产生的新消息会被标记为未读消息。同时,在消息区域的右下方会出现未读消息按钮。该按钮展示未读消息数,用户点击后直接定位到最新消息位置(通常为消息区域的最底部),确保不错过未读信息。 - -若未读消息的数量不超过 99,则未读消息数显示实际的数量,若达到 100 及以上则显示 99+。 - - - - - -## 已禁言列表 - -记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。被禁言的成员无法在聊天室中发送消息,但仍留在聊天室,可以查看消息。 - -在 UIKit 中,默认通过点击聊天室界面右上角的成员按钮,触发已禁言列表。用户在列表中查看聊天室被禁言的所有成员,包括成员的身份、头像和昵称,同时可以通过点击成员右端的管理功能按钮,触发解除禁言选项,实现取消禁言的操作。 - - - - - - -## 暗黑模式 - -暗黑模式是一种界面设计选择,旨在提供更低对比度和更多暗色调的视觉外观。用户可以根据需要启用或禁用暗黑模式,以实现最佳的使用体验。 - -UIKit 支持暗黑模式的一键切换。UIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 - - - - - - - - - diff --git a/docs/uikit/chatroomuikit/android/roomfeature_member.md b/docs/uikit/chatroomuikit/android/roomfeature_member.md deleted file mode 100644 index 736e488e..00000000 --- a/docs/uikit/chatroomuikit/android/roomfeature_member.md +++ /dev/null @@ -1,41 +0,0 @@ -# 成员管理 - - - -聊天室中的成员角色分为聊天室所有者和普通成员。普通成员可以发送和查看聊天室中的消息、进行消息翻译、举报和撤回、以及查看成员列表和搜索成员等操作。聊天室所有者除了具备普通成员的权限,还可以禁言成员和移除成员。 - -## 查看成员列表 - -聊天室中的所有成员的列表。聊天室成员列表显示了该聊天室中的当前在线用户。通过查看成员列表,用户可以看到聊天室中有哪些成员正在参与对话,也可以对于成员采取一些操作。 - -在 UIKit 中,默认通过点击聊天室界面右上角的成员按钮,触发成员列表弹窗。在成员列表中,用户可以查看聊天室当前在线成员,包括成员的身份、头像和昵称,同时可以点击每位成员右侧的按钮,触发禁言和移除的操作。 - -![img](/images/uikit/chatroomfeature/member_list.png =500x500) - -## 搜索成员 - -在聊天室中查找指定成员的功能,支持本地搜索和模糊匹配。 - -UIKit 中的成员搜索功能放置在[成员列表](#查看成员列表)中。当聊天室中的成员较多时,用户可以在成员列表搜索框中输入成员昵称快速找到指定成员。 - -![img](/images/uikit/chatroomfeature/member_search.png =300x600) - -## 禁言成员 - -聊天室所有者可以在聊天室中对某个特定的成员禁言。禁言通常是对违反聊天室规则、发表不当言论或不断干扰聊天室秩序的成员所采取的一种惩罚。 - -在 UIKit 的成员列表中,通过点击单个成员的管理功能按钮,触发禁言成员的选项,实现对指定成员的禁言惩罚。你也可以通过长按聊天室中的单条消息,触发[禁言选项](roomfeature_message#禁言成员),实现对发送该条消息的成员的禁言惩罚。成员被禁言后,会被加入[已禁言列表](roomfeature_common#已禁言列表),无法在聊天室中发送消息,但仍留在聊天室,可以查看消息。 - -此外,在聊天室消息区域,你可以长按单条消息,对发送该条消息的成员的进行禁言。 - -如果用户想要取消禁言成员,需要在已禁言列表中找到该成员,点击成员右端的管理功能按钮,触发解除禁言选项,实现取消禁言的操作。 - -![img](/images/uikit/chatroomfeature/member_mute.png =500x500) - -## 移除成员 - -从聊天室中将某个成员踢出的行为。通常,当某成员违反了聊天室规则或发表了不当言论,聊天室所有者会对该成员进行移除。 - -在 UIKit 的成员列表中,聊天室所有者通过点击单个成员的管理功能按钮,触发移除成员的选项,实现对指定成员的踢出操作。 - -![img](/images/uikit/chatroomfeature/member_mute.png =500x500) \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/android/roomfeature_message.md b/docs/uikit/chatroomuikit/android/roomfeature_message.md deleted file mode 100644 index 32c85bbf..00000000 --- a/docs/uikit/chatroomuikit/android/roomfeature_message.md +++ /dev/null @@ -1,41 +0,0 @@ -# 消息扩展特性 - - - -除了在聊天室中发送和查看消息,还可以长按一条消息进行消息举报、翻译、撤回和禁言成员。 - -## 消息举报 - -在聊天室中,当用户发现其他人发布了可能违反聊天室规则或道德准则的消息时,可以举报该消息,促使聊天室所有者采取适当的行动。 - -在 UIKit 中,默认通过长按单条消息,触发举报选项,实现消息举报。用户可以选择举报原因,如色情内容、恶意攻击、仇恨言论、垃圾广告等。你也可以根据业务需要,修改举报原因选项。 - -![img](/images/uikit/chatroomfeature/msg_report.png =600x400) - -## 消息翻译 - -将聊天室中的单条消息从一种语言转换成另一种语言。翻译特性可以帮助聊天室中的成员克服语言障碍,促进跨语言沟通和交流。 - -在 UIKit 中,默认通过长按单条消息,触发翻译选项,实现消息翻译。默认翻译后的语言与用户设备的系统设置保持一致,例如,若你的手机系统语言为中文,则消息翻译的目标语言也是中文。翻译后的消息显示在原消息的位置,替换原消息。 - -![img](/images/uikit/chatroomfeature/msg_translate.png =500x500) - -## 消息撤回 - -在聊天室中撤销已经发送的消息。当用户发送一条消息后,可能会发现消息内容有误或不妥当,可以使用消息撤回功能将消息从聊天室的聊天窗口中删除,使其他用户无法再看到该消息。在 UIKit 中,默认通过长按单条消息,触发撤回选项,实现对该条消息的撤回。撤回的默认限制是 2 分钟,超时则无法撤回。时间限制可[通过环信控制台的进行调整](/product/enable_and_configure_IM.html#设置消息撤回-rest-客户端),最长为 7 天。 - -:::tip -所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 -::: - -![img](/images/uikit/chatroomfeature/msg_recall.png =800x600) - -## 禁言成员 - -在聊天室中对指定成员采取禁止发言的措施。禁言通常是对违反聊天室规则、发表不当言论或不断干扰聊天室秩序的成员所采取的一种惩罚。 - -在 UIKit 中,默认通过长按单条消息,触发禁言选项,实现对发送该条消息的成员的禁言惩罚。此外,用户也可以通过[成员列表](roomfeature_member#查看成员列表)对指定成员直接进行禁言惩罚。 - -当成员被禁言后,将会被加入[已禁言列表](roomfeature_common#已禁言列表)。如果用户想要取消禁言成员,需要在已禁言列表中找到该成员,点击成员右端的管理功能按钮,触发解除禁言选项,实现取消禁言的操作。 - -![img](/images/uikit/chatroomfeature/msg_mute.png =500x500) diff --git a/docs/uikit/chatroomuikit/android/roomuikit_best_practice.md b/docs/uikit/chatroomuikit/android/roomuikit_best_practice.md deleted file mode 100644 index cf4d33f8..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_best_practice.md +++ /dev/null @@ -1,68 +0,0 @@ -# 最佳实践 - - - -## 初始化 ChatroomUIKit - -初始化是使用 ChatroomUIKit 的必要步骤,需在所有接口方法调用前完成。 - -初始化 ChatroomUIKit 时,你可以传入 `option` 参数,设置各种选项。 - -```kotlin - val chatroomUIKitOptions = ChatroomUIKitOptions( - chatOptions = ChatSDKOptions(enableDebug = true), - uiOptions = UiOptions( - targetLanguageList = listOf(currentLanguage), - useGiftsInList = false, - ) - ) -``` - -## 登录 ChatroomUIKit - -你可以通过使用工程中的用户对象并遵守 `UserInfoProtocol` 协议登录 ChatroomUIKit,示例代码如下: - -```kotlin -class YourAppUser: UserInfoProtocol { - var userId: String = "your application user id" - - var nickName: String = "you user nick name" - - var avatarURL: String = "you user avatar url" - - var gender: Int = 1 - - var identity: String = "you user level symbol url" - -} -ChatroomUIKitClient.getInstance().login(YourAppUser, token, onSuccess = {}, onError = {code,error ->}) -``` - -## 初始化聊天室视图 - -1. 获取聊天室列表,加入指定的聊天室。除此之外,你还可以在环信即时通讯云控制台上[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室),获取聊天室 ID。 - -2. 加载聊天室视图 `ComposeChatroom`,传入的参数包括聊天室 ID、布局参数、聊天室所有者的用户 ID 及一些选项。 - -```kotlin -class ChatroomActivity : ComponentActivity(){ - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - ComposeChatroom(roomId = roomId,roomOwner = ownerInfo) - } - } -} -``` - -## 监听 ChatroomUIKit 事件和错误 - -你可以调用 `registerRoomResultListener` 方法添加监听器用于监听 ChatroomUIKit 事件和错误。 - -```kotlin -ChatroomUIKitClient.getInstance().registerRoomResultListener(this) -``` - -## 参考 - -若要了解以上最佳实践的详情,请访问 [GitHub 仓库](https://github.com/easemob/ChatroomDemo/tree/dev/Android/ChatroomDemo)。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/android/roomuikit_config_item.md b/docs/uikit/chatroomuikit/android/roomuikit_config_item.md deleted file mode 100644 index 3c602d35..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_config_item.md +++ /dev/null @@ -1,29 +0,0 @@ -# 可配置项 - - - -- 修改 `UiOptions` 中的可配置项。例如,你可以修改 `UiOptions` 中的 `useGiftsInList` 配置消息列表上是否显示礼物。 - -```kotlin -val chatroomUIKitOptions = ChatroomUIKitOptions( - uiOptions = UiOptions( - targetLanguageList = listOf(GlobalConfig.targetLanguage.code), - useGiftsInList = false, - ) -) -``` - -- 修改 `ViewModel` 中的可配置项。例如,你可以修改 `MessageListViewModel` 中的可配项,配置是否显示时间和头像。 - -```kotlin -class MessageListViewModel( - private val isDarkTheme: Boolean? = false, - private val showDateSeparators: Boolean = true, - private val showLabel: Boolean = true, - private val showAvatar: Boolean = true, - private val roomId: String, - private val chatService: UIChatroomService, - private val composeChatListController: ComposeChatListController -) -``` - diff --git a/docs/uikit/chatroomuikit/android/roomuikit_integrated.md b/docs/uikit/chatroomuikit/android/roomuikit_integrated.md deleted file mode 100644 index 18f1701b..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_integrated.md +++ /dev/null @@ -1,33 +0,0 @@ -# 集成 ChatroomUIKit - - - -使用 ChatroomUIKit 之前,你需要将 ChatroomUIKit 集成到你的应用中。 - -## 前提条件 - -要集成 ChatroomUIKit,你的开发环境需要满足以下需求: - -- Android Studio Arctic Fox (2020.3.1) 或以上版本; -- Android API 级别 21 或以上版本; -- 使用 Kotlin 语言开发,1.5.21 或以上版本; -- JDK 1.8 或以上版本; -- Gradle 7.0.0 或以上版本。 - -## 添加 ChatroomUIKit 模块本地依赖 - -找到下载的 **ChatroomUIKit** 模块添加为本地依赖。将 [ChatroomUIKit](https://github.com/easemob/UIKit_Chatroom_android/tree/dev/ChatroomUIKit) 和 [ChatroomService](https://github.com/easemob/UIKit_Chatroom_android/tree/dev/ChatroomService) 模块导入到项目中。 - -```kotlin -// settings.gradle -include ':ChatroomUIKit' -include ':ChatroomService' -project(':ChatroomUIKit').projectDir = new File('../ChatroomUIKit/ChatroomUIKit') -project(':ChatroomService').projectDir = new File('../ChatroomUIKit/ChatroomService') - -// app/build.gradle -dependencies { - implementation(project(mapOf("path" to ":ChatroomUIKit"))) -} -``` - diff --git a/docs/uikit/chatroomuikit/android/roomuikit_overview.md b/docs/uikit/chatroomuikit/android/roomuikit_overview.md deleted file mode 100644 index 791f9076..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_overview.md +++ /dev/null @@ -1,44 +0,0 @@ -# 概述 - - - -环信 ChatroomUIKit 提供 UIKit 的各种组件帮助开发者根据实际业务需求快速搭建聊天室应用。通过该 UIKit,聊天室中的用户可实时交互,发送普通弹幕消息、打赏消息和全局广播等功能。 - -- 若要访问源码,请点击[这里](https://github.com/easemob/UIKit_Chatroom_android)。 - -- 你可以扫描以下二维码体验环信聊天室 UIKit Demo: - -![img](/images/uikit/chatroomandroid/demo.png) - -## 功能 - -ChatroomUIKit 提供以下功能: - -- **通用特性** -| 功能 | 描述 | - |--|:--| - | 创建聊天室 | ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 | - | 解散聊天室 | ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 | - | 离开聊天室 | 聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 | - | 发送弹幕消息 | 用户在聊天室中向其他参与者发送文字和表情的消息。 | - | 打赏 | 用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 | - | 全局广播 | 向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 | - | 未读消息数 | 在一个聊天室中用户尚未读取的消息数量。 | - | 已禁言列表 | 记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 | - | 暗黑模式 | ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 | - -- **消息扩展** -| 功能 | 描述 | - |--|:--| - | 消息举报 | 在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。| - | 消息翻译 | 将聊天室中的单条消息从一种语言转换成另一种语言。| - | 消息撤回 | 在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。| - | 禁言成员 | 聊天室所有者对聊天室中的成员禁止发言。| - -- **成员管理** -| 功能 | 描述 | - |--|:--| - | 查看成员列表 | 聊天室成员列表显示了该聊天室中的当前在线用户 | - | 搜索成员 | 在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 | - | 禁言成员 | 聊天室所有者可以在聊天室中对某个特定的成员禁言。 | - | 移除成员 | 聊天室所有者将指定成员从聊天室中踢出。 | diff --git a/docs/uikit/chatroomuikit/android/roomuikit_quickstart.md b/docs/uikit/chatroomuikit/android/roomuikit_quickstart.md deleted file mode 100644 index f5a1832e..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_quickstart.md +++ /dev/null @@ -1,101 +0,0 @@ -# 快速开始 - - - -利用 ChatroomUIKit,你可以轻松实现聊天室内的用户交互。本文介绍如何实现在聊天室中发送消息。 - -## 前提条件 - -- Android Studio Arctic Fox (2020.3.1) 或以上版本; -- Android API 级别 21 或以上; -- 使用 Kotlin 语言开发,1.5.21 或以上版本; -- JDK 1.8 或以上版本; -- Gradle 7.0.0 或以上版本; -- 已在[环信即时通讯云控制台](https://console.easemob.com/user/login)创建了有效的环信即时通讯 IM 开发者账号,并[获取了 App Key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 -- 如果你的网络环境部署了防火墙,请联系环信技术支持设置白名单。 - -## 创建项目引入 ChatroomUIKit 模块 - -1. 在 Android Studio 中创建一个 Android 平台下的 App 或者打开自己现有项目。 - -2. 选择 **File** > **import Module**。 - -3. 模块本地依赖。 - -找到下载的 **ChatroomUIKit** 模块添加为本地依赖。将 [ChatroomUIKit](https://github.com/easemob/UIKit_Chatroom_android/tree/dev/ChatroomUIKit) 和 [ChatroomService](https://github.com/easemob/UIKit_Chatroom_android/tree/dev/ChatroomService) 模块导入到项目中。 - -```kotlin -// settings.gradle -include ':ChatroomUIKit' -include ':ChatroomService' -project(':ChatroomUIKit').projectDir = new File('../ChatroomUIKit/ChatroomUIKit') -project(':ChatroomService').projectDir = new File('../ChatroomUIKit/ChatroomService') - -// app/build.gradle -dependencies { - implementation(project(mapOf("path" to ":ChatroomUIKit"))) -} -``` - -### 第一步 初始化 ChatroomUIKit - -你可以在应用加载时或使用 ChatroomUIKit 之前对其进行初始化。 - -初始化时,需传入 App Key。你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**应用详情**页面查看 App Key。 - -```kotlin -// 初始化 ChatroomUIKit -class ChatroomApplication : Application() { - - override fun onCreate() { - super.onCreate() - - ChatroomUIKitClient.getInstance().setUp(this, "Your AppKey") - - } -} -``` - -### 第二步 登录 ChatroomUIKit - -使用用户 ID 和用户 Token 登录 ChatroomUIKit。 - -:::tip -若你已集成了 IM SDK,SDK 的所有用户 ID 均可用于登录 ChatroomUIKit。 -::: - -为了方便快速体验,你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**应用概览** > **用户认证**页面创建用户并查看用户 token。**用户认证**页面中的用户仅用于快速体验或调试目的。 - -在开发环境中,你需要在环信控制台[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户),从你的 App Server 获取用户 token,详见[使用环信用户 token 鉴权](/product/easemob_user_token.html) 。 - - -```kotlin - ChatroomUIKitClient.getInstance().login("userId", "token") -``` - -### 第三步 创建聊天室视图 - -创建聊天室视图的步骤如下: - -1. 获取聊天室列表,加入指定的聊天室。除此之外,你还可以在环信即时通讯云控制台上[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室),获取聊天室 ID。 - -2. 加载聊天室视图 `ComposeChatroom`,传入的参数包括聊天室 ID 和聊天室所有者的用户 ID。 - -```kotlin -class ChatroomActivity : ComponentActivity(){ - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - ComposeChatroom(roomId = roomId,roomOwner = ownerInfo) - } - } -} -``` - -3. [添加聊天室成员](https://doc.easemob.com/product/enable_and_configure_IM.html#创建聊天室)。 - -### 第四步 发送消息 - -在屏幕下方输入消息内容,点击 **发送** 按钮,发送消息。 - -![img](/images/uikit/chatroomandroid/click_chat.png =500x500) \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/android/roomuikit_releasenote.md b/docs/uikit/chatroomuikit/android/roomuikit_releasenote.md deleted file mode 100644 index 95d69f4b..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_releasenote.md +++ /dev/null @@ -1,31 +0,0 @@ -# 聊天室 UIKit 更新日志 - - - -## 版本 V1.0.0 2023-12-29 - -### 新增特性 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - [创建聊天室](roomfeature_common.html#创建聊天室):ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - [离开聊天室](roomfeature_common.html#离开聊天室):聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - [发送弹幕消息](roomfeature_common.html#发送弹幕):用户在聊天室中向其他参与者发送文字和表情的消息。 - - [打赏](roomfeature_common.html#打赏):用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - [全局广播](roomfeature_common.html#全局广播):向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - [未读消息数](roomfeature_common.html#未读消息数):在一个聊天室中用户尚未读取的消息数量。 - - [已禁言列表](roomfeature_common.html#已禁言列表):记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - [暗黑模式](roomfeature_common.html#暗黑模式):ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展**(长按一条消息可进行的操作) - - [消息举报](roomfeature_message.html#消息举报):在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - [消息翻译](roomfeature_message.html#消息翻译):将聊天室中的单条消息从一种语言转换成另一种语言。 - - [消息撤回](roomfeature_message.html#消息撤回):在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - [禁言成员](roomfeature_message.html#禁言成员):聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - [查看成员列表](roomfeature_member.html#查看成员列表):聊天室成员列表显示了该聊天室中的当前在线用户。 - - [搜索成员](roomfeature_member.html#搜索成员):在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - [禁言成员](roomfeature_member.html#禁言成员):聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - [移除成员](roomfeature_member.html#移除成员):聊天室所有者将指定成员从聊天室中踢出。 - diff --git a/docs/uikit/chatroomuikit/android/roomuikit_run.md b/docs/uikit/chatroomuikit/android/roomuikit_run.md deleted file mode 100644 index c984cfb9..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_run.md +++ /dev/null @@ -1,91 +0,0 @@ -# 跑通示例项目 - - - -环信提供一个开源的 ChatroomUIKit 示例项目,演示了如何使用该 UIKit 快速搭建聊天室页面,实现完整业务。 - -本文展示如何编译并运行 Android 平台的聊天室 UIKit 示例项目。 - -## 前提条件 - -开始前,确保你的开发环境满足如下条件: - -- Android Studio Arctic Fox (2020.3.1) 或以上版本; -- Android API 级别 21 或以上; -- 使用 Kotlin 语言开发,1.5.21 或以上版本; -- JDK 1.8 或以上版本; -- Gradle 7.0.0 或以上版本。 - -## 操作步骤 - -### 第一步 下载 ChatroomUIKit 示例代码 - -点击 [github源码](https://github.com/easemob/UIKit_Chatroom_android),将示例代码下载到本地设备。 - -### 第二步 添加 ChatroomUIKit 模块依赖 - -1. 在 Android Studio 中打开你的项目。 - -2. 选择 **File** > **import Module**。 - -3. 添加模块本地依赖。 - -找到下载的 **ChatroomUIKit** 模块添加为本地依赖。将 [ChatroomUIKit](https://github.com/easemob/UIKit_Chatroom_android/tree/dev/ChatroomUIKit) 和 [ChatroomService](https://github.com/easemob/UIKit_Chatroom_android/tree/dev/ChatroomService) 模块导入到项目中。 - -```kotlin -// settings.gradle -include ':ChatroomUIKit' -include ':ChatroomService' -project(':ChatroomUIKit').projectDir = new File('../ChatroomUIKit/ChatroomUIKit') -project(':ChatroomService').projectDir = new File('../ChatroomUIKit/ChatroomService') - -// app/build.gradle -dependencies { - implementation(project(mapOf("path" to ":ChatroomUIKit"))) -} -``` - -### 第三步 编译 - -编译时,需要传入 App Key、用户 ID 和用户 token。因此,编译前,你需要在[环信控制台](https://console.easemob.com/user/login)上创建有效的环信即时通讯 IM 开发者账号,并获取 App Key,[创建环信 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。此外,还需[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室)。 - -1. 初始化 ChatroomUIKit。 - -```kotlin -class ChatroomApplication : Application() { - - override fun onCreate() { - super.onCreate() - - ChatroomUIKitClient.getInstance().setUp(this, "Your AppKey") - - } -} -``` - -2. 登录 ChatroomUIKit。 - -```kotlin - ChatroomUIKitClient.getInstance().login("userId", "token") -``` - -3. 加载 ComposeChatroom 视图,传入 `roomId` 和聊天室所有者的 `UserEntity` 对象。 - -```kotlin -class ChatroomActivity : ComponentActivity(){ - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - ComposeChatroom(roomId = roomId,roomOwner = ownerInfo) - } - } -} -``` - -### 第四步 体验项目 - -运行并体验该项目。 - -## 注意事项 - -示例工程仅用于快速跑通流程,暂时未提供多成员交互测试。 diff --git a/docs/uikit/chatroomuikit/android/roomuikit_theme.md b/docs/uikit/chatroomuikit/android/roomuikit_theme.md deleted file mode 100644 index ce1d989c..00000000 --- a/docs/uikit/chatroomuikit/android/roomuikit_theme.md +++ /dev/null @@ -1,38 +0,0 @@ -# 主题 - - - -ChatroomUIkit 内置浅色和深色主题,默认为浅色主题。 - -- 浅色主题 - -![img](/images/uikit/chatroomandroid/light_mode.png) - -- 深色主题 - -![img](/images/uikit/chatroomandroid/dark_mode.png) - -## 自定义主题 - -你可以通过更新主题相关的配置项自定义主题。若对任何配置项不做修改,可以使用默认主题。 - -```kotlin -@Composable -fun ChatroomUIKitTheme( - isDarkTheme: Boolean = isSystemInDarkTheme(), - colors: UIColors = if (!isDarkTheme) UIColors.defaultColors() else UIColors.defaultDarkColors(), - shapes: UIShapes = UIShapes.defaultShapes(), - dimens: UIDimens = UIDimens.defaultDimens(), - typography: UITypography = UITypography.defaultTypography(), - content: @Composable () -> Unit -) -``` - -## 设计指南 - -如果你对主题颜色,设计指南和细节有任何疑问,您可以在 Figma 设计稿中添加评论并提及我们的设计师 Stevie Jiang。 - -- [UI 设计资源](https://www.figma.com/community/file/1322495388317476706/chatroom-uikit)。 - -- [UI 设计指南](design_guide.html)。 - diff --git a/docs/uikit/chatroomuikit/flutter/design_guide.md b/docs/uikit/chatroomuikit/flutter/design_guide.md deleted file mode 100644 index 52ba5431..00000000 --- a/docs/uikit/chatroomuikit/flutter/design_guide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/design_guide.html", - title: "设计指南" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/flutter/roomfeature_common.md b/docs/uikit/chatroomuikit/flutter/roomfeature_common.md deleted file mode 100644 index fb695c37..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomfeature_common.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_common.html", - title: "通用" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/flutter/roomfeature_member.md b/docs/uikit/chatroomuikit/flutter/roomfeature_member.md deleted file mode 100644 index 703fa2f8..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomfeature_member.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_member.html", - title: "成员管理" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/flutter/roomfeature_message.md b/docs/uikit/chatroomuikit/flutter/roomfeature_message.md deleted file mode 100644 index e76f080f..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomfeature_message.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_message.html", - title: "消息扩展" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_best_practice.md b/docs/uikit/chatroomuikit/flutter/roomuikit_best_practice.md deleted file mode 100644 index 6dbbaceb..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_best_practice.md +++ /dev/null @@ -1,149 +0,0 @@ -# 最佳实践 - - - -## 初始化 chatroom_uikit - -初始化是使用 `chatroom_uikit` 的必要步骤,需在所有接口方法调用前完成。 - -```dart -void main() async { - assert(appKey.isNotEmpty, 'appKey is empty'); - await ChatroomUIKitClient.instance.initWithAppkey( - appKey, - ); - runApp(const MyApp()); -} -``` - -## 登录 chatroom_uikit - -你可以通过使用项目中的用户对象并遵守 `UserInfoProtocol` 协议登录。chatroom_uikit 提供了默认的 `UserEntity` 实现,如果需要自己添加属性,可以继承 `UserEntity`: - -- 使用用户 ID `userId` 和密码 `password` 登录: - -```dart -// ... -//设置当前用户的头像和昵称。 - UserEntity user = UserEntity(userId, nickname: nickname, avatarURL: avatarURL); -try { - // 通过密码登录。 - await ChatroomUIKitClient.instance.loginWithPassword( - userId: userId!, - password: password, - userInfo: user, - ); - -} on ChatError catch (e) { - // error. -} -``` - -- 使用用户 ID `userId` 和 token 登录: - -```dart -//设置当前用户的头像和昵称。 - UserEntity user = UserEntity(userId, nickname: nickname, avatarURL: avatarURL); -try { - await ChatroomUIKitClient.instance.loginWithToken( - userId: userId, - token: token!, - userInfo: user, - ); - -} on ChatError catch (e) { - // error. -} -``` - -## 初始化聊天室视图 - -1. 使用聊天室视图,需要先配置主题,确保聊天室能正常加载到主题, - -```dart - -@override - Widget build(BuildContext context) { - return MaterialApp( - builder: (context, child) { - return ChatUIKitTheme(child: child!); - }, - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ... - ); - } -``` - -2. 获取聊天室列表,加入指定的聊天室。除此之外,你还可以在环信即时通讯云控制台上[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室),获取聊天室 ID。 - -3. 使用 `chatroom_uikit` 前,需要先创建 `ChatroomController`, 并使 `ChatRoomUIKit` 作为当前页面的根节点,并将其他组件作为 `ChatRoomUIKit` 的子节点。 - -```dart -// roomId: 需要加入的聊天室 ID。 -// ownerId: 聊天室所有者的用户 ID。 -ChatroomController controller = ChatroomController(roomId: roomId, ownerId: ownerId); - -@override -Widget build(BuildContext context) { - Widget content = Scaffold( - resizeToAvoidBottomInset: false, - appBar: AppBar(), - body: ChatRoomUIKit( - controller: controller, - child: (context) { - // 在子组件中构建页面,比如 礼物弹窗,消息列表等。 - return ...; - }, - ), - ); - - return content; -} -``` - -## 监听聊天室的事件和错误 - -你可以在初始化 `ChatroomController` 时设置聊天室事件的监听器 `ChatroomEventListener`, 当前聊天室的相关事件会通过该回调返回。 - -```dart -controller = ChatroomController( - listener: ChatroomEventListener((type, error) { - // catch errors. - }), - roomId: widget.room.id, - ownerId: widget.room.ownerId, -); -``` - -如果需要监听全局事件,可以使用 `ChatroomResponse` 和 `ChatroomEventResponse` - -```dart - -class _ChatroomViewState extends State - with ChatroomResponse, ChatroomEventResponse { - @override - void initState() { - super.initState(); - - ChatroomUIKitClient.instance.roomService.bindResponse(this); - ChatroomUIKitClient.instance.bindRoomEventResponse(this); - } - - @override - void dispose() { - ChatroomUIKitClient.instance.roomService.unbindResponse(this); - ChatroomUIKitClient.instance.unbindRoomEventResponse(this); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return const Placeholder(); - } -} - -``` - -## 参考 - -若要了解以上最佳实践的详情,请访问 [GitHub 仓库](https://github.com/easemob/ChatroomDemo/tree/dev/flutter/chatroom_uikit_demo)。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_config_item.md b/docs/uikit/chatroomuikit/flutter/roomuikit_config_item.md deleted file mode 100644 index 8e0c897a..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_config_item.md +++ /dev/null @@ -1,358 +0,0 @@ -# 可配置项 - - - -`chatroom_uikit` 的组件中包含各种属性,你可以根据需求进行设置。 - - `chatroom_uikit` 主要包括如下组件: - -| 组件名称 | 组件介绍 | -| --------------- | ---------------------------- | -| [ChatroomLocal 组件](#chatroomlocal-组件) | 可以设置 `UIKit` 所有 UI 组件的语言。 | -| [ChatRoomUIKit 组件](#chatroomuikit-组件) | 提供基础的聊天室页面。 | -| [ChatroomMessageListView 组件](#chatroommessagelistview-组件) | 聊天室消息区域组件,用于显示发送或者接收到的消息。 | -| [ChatroomParticipantsListView 组件](#chatroomparticipantslistview-组件) | 聊天室成员列表组件,包括聊天室成员和禁言成员的管理。 | -| [ChatroomGiftMessageListView 组件](#chatroomgiftmessagelistview-组件) | 聊天室打赏消息区域组件,用于显示打赏的礼物。 | -| [ChatroomGlobalBroadcastView 组件](#chatroomglobalbroadcastview-组件) | 聊天室全局广播组件,用于向 app 下的所有聊天室发送消息。 | -| [ChatInputBar 组件](#chatinputbar-组件) | 聊天室底部工具栏区域,可以与消息输入组件互相切换,支持添加自定义按钮。 | -| [ChatRoomGiftListView 组件](#chatroomgiftlistview-组件) | 发送礼物组件,用于发送礼物,礼物来源由开发者指定。 | -| [ChatroomReportListView 组件](#chatroomreportlistview-组件) | 聊天室举报组件。 | - -## ChatroomLocal 组件 - -UIKit 支持多国语言切换,目前内置中文和英文,可以扩展其他语言。 - -例如:若要 UIKit 使用英文显示,可以如下设置: - -```dart -final FlutterLocalization _localization = FlutterLocalization.instance; -_localization.init(mapLocales: [ - const MapLocale('zh', ChatroomLocal.zh), - const MapLocale('en', ChatroomLocal.en), -], initLanguageCode: 'zh'); - -... - -return MaterialApp( - title: 'Flutter Demo', - supportedLocales: _localization.supportedLocales, - localizationsDelegates: _localization.localizationsDelegates, - ... -); - -``` - -## ChatRoomUIKit 组件 - -ChatRoomUIKit 组件为聊天室组件,可以用来快速提供聊天室页面,并提供了聊天室事件监听和输入组件的自定义。 - -示例如下: - -```dart -ChatroomController controller = - ChatroomController(roomId: widget.roomId, ownerId: widget.ownerId); -... - -@override -Widget build(BuildContext context) { - return ChatRoomUIKit( - controller: controller, - inputBar: ChatInputBar( // 自定义你需要的输入样式 - actions: [ - InkWell( - onTap: () => controller.showGiftSelectPages(), - child: Padding( - padding: const EdgeInsets.all(3), - child: Image.asset('images/send_gift.png'), - ), - ), - ], - ), - child: (context) { - // 返回你的 widget - return Container(); - }, - ); -} - -``` - -## ChatroomMessageListView 组件 - -聊天室消息区域组件 `ChatroomMessageListView` 提供消息的显示,聊天室接收到的文本消息、表情消息、礼物消息以及发送成功的消息会显示在该区域。 - -可以在消息区域中对消息进行操作,例如,翻译文本消息为目标语言、撤销消息和消息上报等。你可以通过长按消息列表项弹出菜单进行相应操作。 - -数据上报组件支持自定义选项,可以自定义选项上报不同内容。 - -示例代码如下: - -```dart -ChatroomController controller = - ChatroomController(roomId: widget.roomId, ownerId: widget.ownerId); -... - -@override -Widget build(BuildContext context) { - return ChatRoomUIKit( - controller: controller, - inputBar: ChatInputBar( // 自定义你需要的输入样式 - actions: [ - InkWell( - onTap: () => controller.showGiftSelectPages(), - child: Padding( - padding: const EdgeInsets.all(3), - child: Image.asset('images/send_gift.png'), - ), - ), - ], - ), - child: (context) { - return Stack( - children: [ - const Positioned( - left: 16, - right: 78, - height: 204, - bottom: 90, - child: ChatroomMessageListView(), // 添加消息列表并设置位置 - ) - ], - ); - }, - ); -} -``` - -`ChatroomMessageListView` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ------------------------ | -------- | ----------------------------------------------- | -| onTap | 否 | 消息列表点击事件。 | -| onLongPress | 否 | 消息列表长按事件。 | -| itemBuilder | 否 | 消息列表项 build,可以用于自定义显示样式。 -| reportController | 否 | `ChatReportController` 用于自定义举报内容,默认使用 `DefaultReportController`。 | -| controller | 否 | `ChatroomMessageListController`, 用于配置默认长按事件,默认使用 `DefaultMessageListController`。 | - -## ChatroomParticipantsListView 组件 - -聊天室成员组件可以显示和管理聊天室成员,聊天室所有者、禁言列表以及管理权限。 - -聊天室所有者可以修改成员状态,例如,对成员禁言或踢出聊天室。 - -:::tip -该组件不支持自定义。 -::: - -## ChatroomGiftMessageListView 组件 - -聊天室打赏消息区域组件 `ChatroomGiftMessageListView` 用于展示发送的礼物效果,礼物消息可以显示在消息列表,也可以显示在该组件单独对礼物进行显示。 - -示例代码如下: - -```dart -ChatroomController controller = - ChatroomController(roomId: widget.roomId, ownerId: widget.ownerId); -... - -@override -Widget build(BuildContext context) { - return ChatRoomUIKit( - controller: controller, - inputBar: ChatInputBar( // 自定义你需要的输入样式 - actions: [ - InkWell( - onTap: () => controller.showGiftSelectPages(), - child: Padding( - padding: const EdgeInsets.all(3), - child: Image.asset('images/send_gift.png'), - ), - ), - ], - ), - child: (context) { - return Stack( - children: [ - const Positioned( - left: 16, - right: 100, - height: 84, - bottom: 300, - child: ChatroomGiftMessageListView(), // 设置礼物展示区域 - ), - const Positioned( - left: 16, - right: 78, - height: 204, - bottom: 90, - child: ChatroomMessageListView(), // 添加消息列表并设置位置 - ) - ], - ); - }, - ); -} -``` - -`ChatroomGiftMessageListView` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ----------------------- | -------- | ---------------------------------------------- | -| giftWidgetBuilder | 否 | 单个礼物展示的 builder。 | -| placeholder | 否 | 默认图片占位符,当礼物图片下载成功之前用于占位。 | - -## ChatroomGlobalBroadcastView 组件 - -全局广播通知组件 `ChatroomGlobalBroadcastView` 接收和显示全局全局广播,也是通过添加消息到队列排队显示。 - -简单示例如下: - -```dart -ChatroomController controller = - ChatroomController(roomId: widget.roomId, ownerId: widget.ownerId); -... - -@override -Widget build(BuildContext context) { - return ChatRoomUIKit( - controller: controller, - inputBar: ChatInputBar( // 自定义你需要的输入样式 - actions: [ - InkWell( - onTap: () => controller.showGiftSelectPages(), - child: Padding( - padding: const EdgeInsets.all(3), - child: Image.asset('images/send_gift.png'), - ), - ), - ], - ), - child: (context) { - return Stack( - children: [ - Positioned( - top: MediaQuery.of(context).viewInsets.top + 10, - height: 20, - left: 20, - right: 20, - child: ChatroomGlobalBroadcastView(), // 用于展示广播消息 - ), - const Positioned( - left: 16, - right: 100, - height: 84, - bottom: 300, - child: ChatroomGiftMessageListView(), // 设置礼物展示区域 - ), - const Positioned( - left: 16, - right: 78, - height: 204, - bottom: 90, - child: ChatroomMessageListView(), // 添加消息列表并设置位置 - ) - ], - ); - }, - ); -} -``` - -`ChatroomGlobalBroadcastView` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ----------------------- | -------- | ---------------------------------------------------- | -| icon | 否 | 设置收到广播时的图标。 | -| textStyle | 否 | 设置广播内容字体。 | -| backgroundColor | 否 | 设置广播背景颜色。 | - -## ChatInputBar 组件 - -消息输入框组件 `ChatInputBar` 可以发送文本、表情等消息,可以与聊天室底部工具栏区域互相动态切换。当点击聊天室底部工具栏区域组件时切换到输入状态,发送消息或者关闭输入框时切换为聊天室底部工具栏区域组件。 - -简单示例如下: - -```dart - Widget build(BuildContext context) { - Widget content = ChatRoomUIKit( - controller: controller, - inputBar: ChatInputBar( // 添加一个礼物按钮 - actions: [ - InkWell( - onTap: () => controller.showGiftSelectPages(), - child: Padding( - padding: const EdgeInsets.all(3), - child: Image.asset('assets/images/send_gift.png'), - ), - ), - ], - ), - ); - } -``` - -`ChatInputBar` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ---------------------- | -------- | --------------------------------------------- | -| inputIcon | 否 | 显示图标。 | -| inputHint | 否 | 未输入时占位字符。 | -| leading | 否 | 输入区域左侧区域 widget。 | -| actions | 否 | 输入区域右侧区域 widget 数组,最多允许有 3 个 widget。 | -| textDirection | 否 | 输入区域的方向 | -| onSend | 否 | 点击**发送**按钮的回调。| - -## ChatRoomGiftListView 组件 - -礼物列表组件 `ChatRoomGiftListView` 提供自定义礼物列表,点击礼物项的发送按钮发送到聊天室。可以通过配置 `ChatroomController#giftControllers` 进行内容填充。 - -`giftControllers` 为 `ChatroomGiftPageController` 数组,`chatroom_uikit` 默认提供 `DefaultGiftPageController` 实现。 - -:::tip -礼物列表组件是一个独立的组件,需要应用开发者自行实现显示和加载等操作。 -::: - -示例代码如下: - -```dart -ChatroomController controller = ChatroomController( - roomId: widget.room.id, - ownerId: widget.room.ownerId, - giftControllers: () async { - List service = []; - final value = await rootBundle.loadString('assets/data/Gifts_cn.json'); // 解析json,并赋值给 giftControllers。 - Map map = json.decode(value); - for (var element in map.keys.toList()) { - service.add( - DefaultGiftPageController( - title: element, - gifts: () { - List list = []; - map[element].forEach((element) { - GiftEntityProtocol? gift = ChatroomUIKitClient - .instance.giftService - .giftFromJson(element); - if (gift != null) { - list.add(gift); - } - }); - return list; - }(), - ), - ); - } - return service; - }(), - ); -``` - -## ChatroomReportListView 组件 - -消息举报组件 `ChatroomReportListView`,默认界面不提供自定义部分,可以通过配置进行内容修改。 - -示例代码如下: - -```dart -// 修改举报内容: -ChatRoomSettings.reportMap = {'tag': 'reason'}; -``` diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_integrated.md b/docs/uikit/chatroomuikit/flutter/roomuikit_integrated.md deleted file mode 100644 index 25ba7afd..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_integrated.md +++ /dev/null @@ -1,31 +0,0 @@ -# 集成 ChatroomUIKit - - - -使用 `chatroom_uikit` 之前,你需要将 `chatroom_uikit` 集成到你的应用中。 - -## 前提条件 - -- 即时通讯 SDK 3.0.0(包含)-4.0.0; -- Flutter 3.3.0 或以上版本; -- 有效的环信即时通讯 IM 开发者账号和 [App Key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 -- 对于 `iOS` 应用: - - Xcode 13 或以上版本; - - ios 11 或以上版本; -- 对于 `Android` 应用: - - minSDKVersion 21。 - - release 时需要在 `xxx/android/app/proguard-rules.pro` 中设置免混淆规则: - -```java --keep class com.hyphenate.** {*;} --dontwarn com.hyphenate.** -``` - -## 安装 UIKit 到项目中 - -进入项目,执行以下命令: - -```sh -flutter pub get add chatroom_uikit -``` - diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_overview.md b/docs/uikit/chatroomuikit/flutter/roomuikit_overview.md deleted file mode 100644 index afde6b2f..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_overview.md +++ /dev/null @@ -1,34 +0,0 @@ -# 概述 - - - -环信 ChatroomUIKit 提供 UIKit 的各种组件帮助开发者根据实际业务需求快速搭建聊天室应用。通过该 UIKit,聊天室中的用户可实时交互,发送普通弹幕消息、打赏消息和全局广播等功能。 - -- 若要访问源码,请点击[这里](https://github.com/easemob/UIKit_Chatroom_flutter)。 - -- 你可以体验环信 [Android](http://www.pgyer.com/YZUCrW) 和 [iOS](https://testflight.apple.com/join/NzmtvJ6n) 聊天室 UIKit demo: - -## 功能 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - 创建聊天室:ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - 离开聊天室:聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - 发送弹幕消息:用户在聊天室中向其他参与者发送文字和表情的消息。 - - 打赏:用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - 全局广播:向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - 未读消息数:在一个聊天室中用户尚未读取的消息数量。 - - 已禁言列表:记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - 暗黑模式:ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展** - - 消息举报:在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - 消息翻译:将聊天室中的单条消息从一种语言转换成另一种语言。 - - 消息撤回:在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - 禁言成员:聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - 查看成员列表:聊天室成员列表显示了该聊天室中的当前在线用户。 - - 搜索成员:在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - 禁言成员:聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - 移除成员:聊天室所有者将指定成员从聊天室中踢出。 diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_quickstart.md b/docs/uikit/chatroomuikit/flutter/roomuikit_quickstart.md deleted file mode 100644 index a0f08d85..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_quickstart.md +++ /dev/null @@ -1,173 +0,0 @@ -# 快速开始 - - - -利用 `chatroom_uikit`,你可以轻松实现聊天室内的用户交互。本文介绍如何实现在聊天室中发送消息。 - -## 前提条件 - -- 即时通讯 SDK 3.0.0(包含)-4.0.0; -- Flutter 3.3.0 或以上版本; -- 有效的环信即时通讯 IM 开发者账号和 [App Key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 - -## 操作流程 - -### 第一步 创建聊天室和用户 - -在环信控制台[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室)和[用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### 第二步 创建项目 - -```sh -flutter create --platforms=android,ios room_project -``` - -### 第三步 项目中安装 UIKit - -进入创建的项目,执行以下命令: - -```sh -flutter pub get add chatroom_uikit -``` - -### 第四步 初始化 chatroom_uikit - -你可以在应用加载时或使用 `chatroom_uikit` 之前对其进行初始化。 - -初始化时,需传入 App Key。你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**应用详情**页面查看 App Key。 - -```dart -void main() async { - assert(appKey.isNotEmpty, 'appKey is empty'); - await ChatroomUIKitClient.instance.initWithAppkey( - appKey, - ); - runApp(const MyApp()); -} -``` - -### 第五步 登录 chatroom_uikit - -进入聊天室前,需首先通过用户 ID 和用户 Token 登录 `chatroom_uikit` - -:::tip -若你已集成了 IM SDK,SDK 的所有用户 ID 均可用于登录 `chatroom_uikit`。 -::: - -为了方便快速体验,你可以在[环信控制台](https://console.easemob.com/user/login)的**应用概览** > **用户认证**页面创建用户并查看用户 token。**用户认证**页面中的用户仅用于快速体验或调试目的。 - -在开发环境中,你需要在环信控制台[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户),从你的 App Server 获取用户 token,详见[使用环信用户 token 鉴权](/product/easemob_user_token.html)。 - -登录服务, 可使用 `userId` 和 `password` 登录,也可以使用 `userId` 和 token 进行登录。 - -- 使用 `userId` 和 `password` 登录: - -```dart -// ... -//设置当前用户的头像和昵称 - UserEntity user = UserEntity(userId, nickname: nickname, avatarURL: avatarURL); -try { - // 通过密码登录 - await ChatroomUIKitClient.instance.loginWithPassword( - userId: userId!, - password: password, - userInfo: user, - ); - -} on ChatError catch (e) { - // error. -} -``` - -- 使用 `userId` 和 token 登录: - -```dart -//设置当前用户的头像和昵称 - UserEntity user = UserEntity(userId, nickname: nickname, avatarURL: avatarURL); -try { - await ChatroomUIKitClient.instance.loginWithToken( - userId: userId, - token: token!, - userInfo: user, - ); - -} on ChatError catch (e) { - // error. -} -``` - -### 第六步 设置主题颜色 - -可以通过 `ChatUIKitTheme` 进行主题设置,默认提供了 `light` 和 `dart` 两种主题: - -```dart -ChatUIKitTheme( - child: child, -), -``` - -如果需要修改主题色,可以通过修改`ChatUIKitColor` 的 `hue` 值: - -```dart -ChatUIKitColor({ - this.primaryHue = 203, - this.secondaryHue = 155, - this.errorHue = 350, - this.neutralHue = 203, - this.neutralSpecialHue = 220, - this.barrageLightness = LightnessStyle.oneHundred, - this.isDark = false, -}); -``` - - -### 第七步 使用 chatroom_uikit 组件 - -1. 需要确保 `ChatUIKitTheme` 在 `ChatroomUIKit` 组件在你项目的父节点,建议将 `ChatUIKitTheme` 放到项目的根节点。 - -```dart - -@override - Widget build(BuildContext context) { - return MaterialApp( - builder: (context, child) { - return ChatUIKitTheme(child: child!); - }, - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ... - ); - } -``` - - -2. 在需要使用 `chatroom_uikit` 时,需要先创建 `ChatroomController`, 并使 `ChatRoomUIKit` 作为当前页面的根节点,并将其他组件作为 `ChatRoomUIKit` 的子组件。 - -```dart -// roomId: 需要加入的房间id; -// ownerId: 房主id; -ChatroomController controller = ChatroomController(roomId: roomId, ownerId: ownerId); - -@override -Widget build(BuildContext context) { - Widget content = Scaffold( - resizeToAvoidBottomInset: false, - appBar: AppBar(), - body: ChatRoomUIKit( - controller: controller, - child: (context) { - // 在子组件中构建页面,比如 礼物弹窗,消息列表等。 - return ...; - }, - ), - ); - - return content; -} - -``` - -### 第八步 发送第一条消息 - -输入消息内容,点击 **发送** 按钮,发送消息。 - -![img](/images/uikit/chatroomandroid/click_chat.png =500x500) diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_releasenote.md b/docs/uikit/chatroomuikit/flutter/roomuikit_releasenote.md deleted file mode 100644 index 95d69f4b..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_releasenote.md +++ /dev/null @@ -1,31 +0,0 @@ -# 聊天室 UIKit 更新日志 - - - -## 版本 V1.0.0 2023-12-29 - -### 新增特性 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - [创建聊天室](roomfeature_common.html#创建聊天室):ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - [离开聊天室](roomfeature_common.html#离开聊天室):聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - [发送弹幕消息](roomfeature_common.html#发送弹幕):用户在聊天室中向其他参与者发送文字和表情的消息。 - - [打赏](roomfeature_common.html#打赏):用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - [全局广播](roomfeature_common.html#全局广播):向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - [未读消息数](roomfeature_common.html#未读消息数):在一个聊天室中用户尚未读取的消息数量。 - - [已禁言列表](roomfeature_common.html#已禁言列表):记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - [暗黑模式](roomfeature_common.html#暗黑模式):ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展**(长按一条消息可进行的操作) - - [消息举报](roomfeature_message.html#消息举报):在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - [消息翻译](roomfeature_message.html#消息翻译):将聊天室中的单条消息从一种语言转换成另一种语言。 - - [消息撤回](roomfeature_message.html#消息撤回):在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - [禁言成员](roomfeature_message.html#禁言成员):聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - [查看成员列表](roomfeature_member.html#查看成员列表):聊天室成员列表显示了该聊天室中的当前在线用户。 - - [搜索成员](roomfeature_member.html#搜索成员):在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - [禁言成员](roomfeature_member.html#禁言成员):聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - [移除成员](roomfeature_member.html#移除成员):聊天室所有者将指定成员从聊天室中踢出。 - diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_run.md b/docs/uikit/chatroomuikit/flutter/roomuikit_run.md deleted file mode 100644 index 0be019ae..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_run.md +++ /dev/null @@ -1,39 +0,0 @@ -# 跑通示例项目 - - - -环信提供一个开源的 ChatroomUIKit 示例项目,演示了如何使用该 UIKit 快速搭建聊天室页面,实现完整业务。 - -## 开发环境要求 - -- 即时通讯 SDK 3.0.0(包含)-4.0.0; -- Flutter 3.3.0 或以上版本; -- 有效的环信即时通讯 IM 开发者账号和 [App Key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息); -- `iOS` 应用: - - Xcode 13 或以上; - - ios 11 或以上; -- `Android` 应用:minSDKVersion 21。 - -## 操作步骤 - -可以通过 `example` 项目进行演示。`example` 文件夹中为示例项目,可以下载源码、进行编译,然后运行进行体验。 - -### 第一步 下载源码仓库 - -运行以下命令: - -```sh -git clone git@github.com:easemob/UIKit_Chatroom_flutter.git -``` - -或者点击[这里](https://codeload.github.com/easemob/UIKit_Chatroom_flutter/zip/refs/heads/main)直接下载。 - -### 第二步 项目初始化 - -1. 进入 `example` 目录,运行 `flutter pub get` 命令。 - -2. 修改 `example/lib/main.dart` 中的 `appKey`。 - -### 第三步 运行项目 - -在 `vscode` 中运行。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/flutter/roomuikit_theme.md b/docs/uikit/chatroomuikit/flutter/roomuikit_theme.md deleted file mode 100644 index 4c9b6500..00000000 --- a/docs/uikit/chatroomuikit/flutter/roomuikit_theme.md +++ /dev/null @@ -1,48 +0,0 @@ -# 主题 - - - -`ChatUIKitTheme` 内置浅色和深色主题,默认为浅色主题。 - -- 浅色主题 - -![img](/images/uikit/chatroomandroid/light_mode.png) - -- 深色主题 - -![img](/images/uikit/chatroomandroid/dark_mode.png) - -## 切换主题 - -若切换 ChatUIKitTheme 内置的浅色或深色主题,可使用以下方法: - -```tsx -// ... -// 设置主题 -ChatUIKitTheme( - color: ChatUIKitColor.light() // 浅色主题, 暗色主题为:ChatUIKitColor.dark()。 - child: child, // chatroom_uikit 所有组件需要为主题组件的子组件 -), -``` - -如果需要修改主题色,可以通过修改 `ChatUIKitColor` 的 `hue` 值: - -```dart -ChatUIKitColor({ - this.primaryHue = 203, - this.secondaryHue = 155, - this.errorHue = 350, - this.neutralHue = 203, - this.neutralSpecialHue = 220, - this.barrageLightness = LightnessStyle.oneHundred, - this.isDark = false, -}); -``` - -## 设计指南 - -如果你对主题颜色,设计指南和细节有任何疑问,您可以在 Figma 设计稿中添加评论并提及我们的设计师 Stevie Jiang。 - -- [UI 设计资源](https://www.figma.com/community/file/1322495388317476706/chatroom-uikit)。 - -- [UI 设计指南](design_guide.html)。 diff --git a/docs/uikit/chatroomuikit/ios/README.md b/docs/uikit/chatroomuikit/ios/README.md deleted file mode 100644 index 32ca3595..00000000 --- a/docs/uikit/chatroomuikit/ios/README.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: iOS ---- diff --git a/docs/uikit/chatroomuikit/ios/design_guide.md b/docs/uikit/chatroomuikit/ios/design_guide.md deleted file mode 100644 index 52ba5431..00000000 --- a/docs/uikit/chatroomuikit/ios/design_guide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/design_guide.html", - title: "设计指南" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/ios/roomfeature_common.md b/docs/uikit/chatroomuikit/ios/roomfeature_common.md deleted file mode 100644 index fb695c37..00000000 --- a/docs/uikit/chatroomuikit/ios/roomfeature_common.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_common.html", - title: "通用" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/ios/roomfeature_member.md b/docs/uikit/chatroomuikit/ios/roomfeature_member.md deleted file mode 100644 index 703fa2f8..00000000 --- a/docs/uikit/chatroomuikit/ios/roomfeature_member.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_member.html", - title: "成员管理" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/ios/roomfeature_message.md b/docs/uikit/chatroomuikit/ios/roomfeature_message.md deleted file mode 100644 index e76f080f..00000000 --- a/docs/uikit/chatroomuikit/ios/roomfeature_message.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_message.html", - title: "消息扩展" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_best_practice.md b/docs/uikit/chatroomuikit/ios/roomuikit_best_practice.md deleted file mode 100644 index cd4a4db6..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_best_practice.md +++ /dev/null @@ -1,76 +0,0 @@ -# 最佳实践 - -若要了解以上最佳实践的详情,请访问 [GitHub 仓库](https://github.com/easemob/ChatroomDemo/tree/dev/iOS/ChatroomDemo)。 - -## 初始化 ChatroomUIKit - -初始化是使用 ChatroomUIKit 的必要步骤,需在所有接口方法调用前完成。 - -初始化 ChatroomUIKit 时,你可以传入 `option` 参数,设置各种选项。 - -```swift -let option = ChatroomUIKitInitialOptions.ChatOptions() -option.enableConsoleLog = true -option.autoLogin = true -let error = ChatroomUIKitClient.shared.setup(appKey,option: option) -``` - -## 登录 ChatroomUIKit - -你可以通过使用工程中的用户对象并遵守 `UserInfoProtocol` 协议登录 ChatroomUIKit,示例代码如下: - -```swift -public final class YourAppUser: NSObject,UserInfoProtocol { - - public func toJsonObject() -> Dictionary? { - ["userId":self.userId,"nickName":self.nickname,"avatarURL":self.avatarURL,"identity":self.identity,"gender":self.gender] - } - - public var identity: String = ""//用户级别图像的 URL - - public var userId: String = <#T##String#> - - public var nickname: String = "Jack" - - public var avatarURL: String = "https://accktvpic.oss-cn-beijing.aliyuncs.com/pic/sample_avatar/sample_avatar_1.png" - - public var gender: Int = 1 - - } -ChatroomUIKitClient.shared.login(user: YourAppUser(), token: "token", completion: <#T##(ChatError?) -> Void#>) -``` - -## 初始化聊天室视图 - -1. 获取聊天室列表,加入指定的聊天室。除此之外,你还可以在环信控制台上[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室),获取聊天室 ID。 - -2. 创建聊天室视图 `ChatroomView`,传入的参数包括聊天室 ID、布局参数、聊天室所有者的用户 ID 及一些选项。 - -:::tip -- 建议 ChatroomView 的宽度初始化为屏幕的宽度,高度不小于以下算式的值:屏幕高度 x 1/5 + 礼物气泡行高 x 2 + 54(底部工具栏的高度)。 -- 对于有刘海屏的机型,ChatroomView 的高度为以上算式的值加上底部安全区域的高度。 -::: - -3. 添加视图。 - -```swift -let options = ChatroomUIKitInitialOptions.UIOptions() -options.bottomDataSource = self.bottomBarDatas() -// 实现显示礼物消息区域。 -options.showGiftMessageArea = true -// 是否在聊天区域中显示礼物信息。 -options.chatAreaShowGift = false -let roomView = ChatroomUIKitClient.shared.launchRoomView(roomId: self.roomId, frame: CGRect(x: 0, y: ScreenHeight/2.0, width: ScreenWidth, height: ScreenHeight/2.0), ownerId: "Chatroom's owner user id", options: options) -addSubView(roomView) -``` - -建议你将该视图添加在你的业务视图的上面,便于 ChatroomView 拦截和透传点击事件。例如,若你有播放视频的视图,需要将 ChatroomView 添加在该视图的上面。 - -## 监听 ChatroomUIKit 事件和错误 - -你可以调用 `registerRoomEventsListener` 方法添加监听器用于监听 ChatroomUIKit 事件和错误。 - -```swift -ChatroomUIKitClient.shared.registerRoomEventsListener(self) -``` - diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_config_item.md b/docs/uikit/chatroomuikit/ios/roomuikit_config_item.md deleted file mode 100644 index a7bd7b80..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_config_item.md +++ /dev/null @@ -1,77 +0,0 @@ -# 可配置项 - -[Appearance.swift](https://github.com/zjc19891106/ChatroomUIKit/blob/main/Sources/ChatroomUIKit/Classes/UI/Core/UIKit/Utils/Appearance.swift) 是容纳了所有可配置项的类,你需要在初始化 ChatroomView 之前修改其中的属性。 - -## 消息视图 - -1. Appearance.giftDialogContainerConstraintsSize:礼物弹窗的大小。 - -![img](/images/uikit/chatroomios/giftContainerConstraintsSize.png) - -2. `Appearance.giftPlaceHolder`:礼物默认图。 - -![img](/images/uikit/chatroomios/giftPlaceHolder.png) - -3. Appearance.avatarPlaceHolder:头像默认图。 - -![img](/images/uikit/chatroomios/avatarPlaceHolder.png) - -4. Appearance.userIdentifyPlaceHolder:用户身份标识默认图。 - -![img](/images/uikit/chatroomios/userIdentityPlaceHolder.png) - -5. Appearance.messageDisplayStyle:弹幕区域 Cell 的展示样式。你可以选择对时间戳、用户标识和用户头像进行显示或隐藏。 - -![img](/images/uikit/chatroomios/customchatbarrage.png) - -6. `Appearance.notifyMessageIcon`:全局广播通知左侧图标默认图。 - -![img](/images/uikit/chatroomios/notifyMessageIcon.png) - -7. `Appearance.defaultMessageActions`:长按消息后弹起弹窗的数据源。 - -![img](/images/uikit/chatroomios/messageActions.png) - -8. `Appearance.actionSheetRowHeight`:`ActionSheet` 单行高度。 - -![img](/images/uikit/chatroomios/messageActions.png) - -9. `Appearance.reportTags`:消息举报弹窗内显示的非法信息类型。 - -![img](/images/uikit/chatroomios/report.png) - -10. Appearance.messageTranslationLanguage:目标翻译语言。你可以根据你的用户设备的语言环境设置对应的目标翻译语言,前提是需要在环信控制台开通翻译功能。目前,聊天室 UIKit 内置支持中文简体、中文繁体,英文,俄语,德语,法语,日语,韩语。 - -## 文本输入视图 - -1. Appearance.maxInputHeight:输入框的最大高度。 - -![img](/images/uikit/chatroomios/maxInputHeight.png) - -2. Appearance.inputPlaceHolder:输入框默认显示的文字。该选项的默认值是 Aa。 - -![img](/images/uikit/chatroomios/inputCorner.png) - -3. Appearance.inputBarCorner:输入框的圆角半径,默认为 `large`,即输入框高度的一半。 - -![img](/images/uikit/chatroomios/inputCorner.png) - -4. Appearance.emojiMap:若要替换全部的表情可以配置该 map,key 是代码注释中的固定字符串,value 可以传入不同 UIImage 对象即可。 - -![img](/images/uikit/chatroomios/customchatbarrage.png) - -## 用户列表 - - `Appearance.defaultOperationUserActions`:成员列表中聊天室所有者对普通成员的操作项。 - - ![img](/images/uikit/chatroomios/moreAction.png) - -## 弹窗 - -1. Appearance.pageContainerTitleBarItemWidth:`PageContainerTitleBar`(各弹窗页面顶部)的单个条目的宽度。 - -![img](/images/uikit/chatroomios/pageContainerTitleBarItemWidth.png) - -2. Appearance.pageContainerConstraintsSize:`PageContainersDialogController` 弹窗的大小。 - -![img](/images/uikit/chatroomios/pageContainerTitleBarItemWidth.png) diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_customize.md b/docs/uikit/chatroomuikit/ios/roomuikit_customize.md deleted file mode 100644 index 9f94aae1..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_customize.md +++ /dev/null @@ -1,63 +0,0 @@ -# 自定义 - -你可以对 ChatroomUIKit 中的一些控件进行自定义,添加自己的业务逻辑,实现个性化业务需求。 - -## 支持自定义的控件 - -目前,现有组件中的以下控件支持自定义: - -- `GiftMessageCell`:礼物弹幕列表 Cell 类。 - -![img](/images/uikit/chatroomios/GiftBarrageCell.png) - -- `GiftEntityCell`:礼物视图 Cell 类。 - -![img](/images/uikit/chatroomios/GiftEntityCell.png) - -- `MessageInputBar`:聊天输入框类。 - -![img](/images/uikit/chatroomios/ChatInputBar.png) - -- `ReportOptionsController`:消息举报控制器类。 - -![img](/images/uikit/chatroomios/ReportOptionsController.png) - -- `ParticipantsController`:聊天室成员列表/黑名单列表控制器类。 - -![img](/images/uikit/chatroomios/ParticipantsController.png) - -- `ChatroomParticipantsCell`:聊天室成员列表/黑名单列表 Cell 类。 - -![img](/images/uikit/chatroomios/ChatroomParticipantsCell.png) - -- `GiftsViewController`:礼物视图控制器类。 - -礼物的容器的自定义方式与其他控件类似,你需要继承 `GiftsViewController` 创建新类,在调用时 `DialogManager.shared.showGiftsDialog(titles: ["Gifts","1231232"], gifts: [self.gift1,self.gift2])` 传入新类的对象。 - -你需要在确保你的服务器端的礼物业务处理完毕,再调用 ChatroomUIKit 提供的发送礼物消息 API。 - -![img](/images/uikit/chatroomios/GiftsViewController.png) - -## 自定义示例 - -下面以如何自定义礼物弹幕视图 Cell 为例介绍如何自定义控件。首先,继承 `GiftMessageCell`,添加自己的逻辑,然后在 ChatroomUIKit 中注册新类替换原有的类。 - -````swift -class CustomGiftMessageViewCell: GiftMessageCell { - lazy var redDot: UIView = { - UIView().backgroundColor(.red).cornerRadius(.large) - }() - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - self.addSubview(redDot) - } - - override func refresh(item: GiftEntityProtocol) { - super.refresh(item: item) - self.redDot.isHidden = item.selected - } -} -//在创建 ChatroomView 或使用其他 UI 组件之前调用此方法。 -ComponentsRegister.shared.GiftMessagesViewCell = CustomGiftMessageViewCell.self -```` diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_integrated.md b/docs/uikit/chatroomuikit/ios/roomuikit_integrated.md deleted file mode 100644 index cf499229..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_integrated.md +++ /dev/null @@ -1,44 +0,0 @@ -# 集成 ChatroomUIKit - -使用 ChatroomUIKit 之前,你需要将 ChatroomUIKit 集成到你的应用中。 - -## 前提条件 - -要集成 ChatroomUIKit,你的开发环境需要满足以下需求: - -- Xcode 14.0 或以上版本; -- iOS 13.0 或以上版本; -- 项目中已设置有效的开发者签名。 - -## 使用 CocoaPods 集成 ChatroomUIKit - -你可以使用 CocoaPods 将 ChatroomUIKit 添加为 Xcode 项目的依赖项。 - -1. 在 `Podfile` 文件中添加如下依赖: - -``` -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '13.0' - -target 'YourTarget' do - use_frameworks! - - pod 'ChatroomUIKit' -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' - end - end -end -``` - -2. 打开终端,cd 到 `Podfile` 所在的目录,然后执行以下命令集成 ChatroomUIKit。 - -``` -pod install --repo-update -``` - -若 Xcode 15 编译出现以下报错 **Sandbox: rsync.samba(47334) deny(1) file-write-create...**,你可以在 **Build Setting** 中搜索 **ENABLE_USER_SCRIPT_SANDBOXING**,将 **User Script Sandboxing** 的设置修改为 **NO**。 diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_overview.md b/docs/uikit/chatroomuikit/ios/roomuikit_overview.md deleted file mode 100644 index c83a49ae..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_overview.md +++ /dev/null @@ -1,34 +0,0 @@ -# 概述 - -环信 ChatroomUIKit 提供 UIKit 的各种组件帮助开发者根据实际业务需求快速搭建聊天室应用。通过该 UIKit,聊天室中的用户可实时交互,发送普通弹幕消息、打赏消息和全局广播等功能。 - -- 若要访问源码,请点击[这里](https://github.com/easemob/UIKit_Chatroom_ios)。 - -- 你可以扫描以下二维码体验环信聊天室 UIKit demo: - -![img](/images/uikit/chatroomios/demo.png) - -## 功能 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - 创建聊天室:ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - 离开聊天室:聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - 发送弹幕:用户在聊天室中向其他参与者发送文字和表情的消息。 - - 打赏:用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - 发送全局广播通知:向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - 未读消息数:在一个聊天室中用户尚未读取的消息数量。 - - 已禁言列表:记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - 暗黑模式:ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息管理** - - 消息举报:在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - 消息翻译:将聊天室中的单条消息从一种语言转换成另一种语言。 - - 消息撤回:在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - 禁言成员:聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - 查看成员列表:聊天室成员列表显示了该聊天室中的当前在线用户。 - - 搜索成员:在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - 禁言成员:聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - 移除成员:聊天室所有者将指定成员从聊天室中踢出。 diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_quickstart.md b/docs/uikit/chatroomuikit/ios/roomuikit_quickstart.md deleted file mode 100644 index 74e0de11..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_quickstart.md +++ /dev/null @@ -1,89 +0,0 @@ -# 快速开始 - -利用 ChatroomUIKit,你可以轻松实现聊天室内的用户交互。本文介绍如何实现在聊天室中发送消息。 - -## 前提条件 - -- Xcode (推荐最新版本)。 -- 安装 iOS 13.0 或更高版本的 iOS 模拟器或 Apple 设备。 -- 已使用 CocoaPods 添加了 ChatroomUIKit 依赖项。 -- 有效的环信即时通讯 IM 开发者账号和 App Key,详见 [环信即时通讯云控制台](https://console.easemob.com/user/login)。 -- 如果你的网络环境部署了防火墙,请联系环信技术支持设置白名单。 - -## 创建项目 - -[在 Xcode 中创建一个 iOS 平台下的 App](https://developer.apple.com/cn/documentation/xcode/creating_an_xcode_project_for_an_app/)。在 **Choose options for your new project** 对话框中进行以下设置: - -- **Product Name**:填入 **ChatroomUIKitQuickStart**。 -- **Organization Identifier**:设置为你的标识符。 -- **User Interface**:选择 **Storyboard**。 -- **Language**:选择你常用的开发语言。 - -## 操作流程 - -### 第一步 初始化 ChatroomUIKit - -你可以在应用加载时或使用 ChatroomUIKit 之前对其进行初始化。 - -初始化时,需传入 App Key。你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**应用详情**页面查看 App Key。 - -```swift -import ChatroomUIKit - -@UIApplicationMain -class AppDelegate:UIResponder,UIApplicationDelegate { - var window:UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { - let error = ChatroomUIKitClient.shared.setup(appKey: "Appkey") - } -} -``` - -### 第二步 登录 ChatroomUIKit - -使用用户 ID 和用户 Token 登录 ChatroomUIKit。 - -:::tip -若你已集成了 IM SDK,SDK 的所有用户 ID 均可用于登录 ChatroomUIKit。 -::: - -为了方便快速体验,你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**应用概览** > **用户认证**页面创建用户并查看用户 token。**用户认证**页面中的用户仅用于快速体验或调试目的。 - -在开发环境中,你需要在环信控制台[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户),从你的 App Server 获取用户 token,详见[使用环信用户 token 鉴权](/product/easemob_user_token.html) 。 - -```swift -ChatroomUIKitClient.shared.login(userId: "user id", token: "token", completion: <#T##(ChatError?) -> Void#>) -``` - -### 第三步 创建聊天室视图 - -创建聊天室视图的步骤如下: - -1. 获取聊天室列表,加入指定的聊天室。除此之外,你还可以在环信控制台上[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室),获取聊天室 ID。 - -2. 创建聊天室视图 `ChatroomView`,传入的参数包括聊天室 ID、布局参数和聊天室所有者的用户 ID。 - -:::tip -- 建议 ChatroomView 的宽度初始化为屏幕的宽度,高度不小于以下算式的值:屏幕高度 x 1/5 + 礼物气泡行高 x 2 + 54(底部工具栏的高度)。 -- 对于有刘海屏的机型,ChatroomView 的高度为以上算式的值加上底部安全区域的高度。 -::: - -```swift -let roomView = ChatroomUIKitClient.shared.launchRoomView(roomId: "Chat room ID",frame: CGRect, ownerId: "Chatroom owner ID") -``` - -3. 将聊天室视图添加到目标区域。 - -在调用 `ChatroomUIKitClient.shared.launchRoomView(roomId: self.roomId, frame: CGRect(x: 0, y: ScreenHeight/2.0, width: ScreenWidth, height: ScreenHeight/2.0), ownerId: "当前聊天室的主播用户ID")` 时,记得将 `ChatroomView` 添加到现有视图之上,以方便拦截和透传点击事件。例如,如果你有一个播放视频流的视图,请添加到视频视图的上方,`ChatroomView` 实质上是全屏覆盖的,传入的 `frame` 是可用区域、弹幕区域、底部工具栏区域以及键盘弹起后输入框中事件的响应高度。 - -![img](/images/uikit/chatroomios/hierarchy.png =800x550) - -4. [添加聊天室成员](https://doc.easemob.com/product/enable_and_configure_IM.html#创建聊天室)。 - -### 第四步 发送第一条消息 - -点击屏幕下方的 `说点什么` 按钮唤起键盘,输入消息内容,点击 **发送** 按钮,发送消息。 - -![img](/images/uikit/chatroomios/click_chat.png =500x500) - -上图为聊天室 Demo 显示的内容,如果要实现类似的样式,可以点击[这里](https://github.com/easemob/ChatroomDemo/tree/dev/iOS/ChatroomDemo)。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_releasenote.md b/docs/uikit/chatroomuikit/ios/roomuikit_releasenote.md deleted file mode 100644 index 95d69f4b..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_releasenote.md +++ /dev/null @@ -1,31 +0,0 @@ -# 聊天室 UIKit 更新日志 - - - -## 版本 V1.0.0 2023-12-29 - -### 新增特性 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - [创建聊天室](roomfeature_common.html#创建聊天室):ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - [离开聊天室](roomfeature_common.html#离开聊天室):聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - [发送弹幕消息](roomfeature_common.html#发送弹幕):用户在聊天室中向其他参与者发送文字和表情的消息。 - - [打赏](roomfeature_common.html#打赏):用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - [全局广播](roomfeature_common.html#全局广播):向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - [未读消息数](roomfeature_common.html#未读消息数):在一个聊天室中用户尚未读取的消息数量。 - - [已禁言列表](roomfeature_common.html#已禁言列表):记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - [暗黑模式](roomfeature_common.html#暗黑模式):ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展**(长按一条消息可进行的操作) - - [消息举报](roomfeature_message.html#消息举报):在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - [消息翻译](roomfeature_message.html#消息翻译):将聊天室中的单条消息从一种语言转换成另一种语言。 - - [消息撤回](roomfeature_message.html#消息撤回):在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - [禁言成员](roomfeature_message.html#禁言成员):聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - [查看成员列表](roomfeature_member.html#查看成员列表):聊天室成员列表显示了该聊天室中的当前在线用户。 - - [搜索成员](roomfeature_member.html#搜索成员):在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - [禁言成员](roomfeature_member.html#禁言成员):聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - [移除成员](roomfeature_member.html#移除成员):聊天室所有者将指定成员从聊天室中踢出。 - diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_run.md b/docs/uikit/chatroomuikit/ios/roomuikit_run.md deleted file mode 100644 index 86c58372..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_run.md +++ /dev/null @@ -1,65 +0,0 @@ -# 跑通示例项目 - -环信提供一个开源的 ChatroomUIKit 示例项目,演示了如何使用该 UIKit 快速搭建聊天室页面,实现完整业务。 - -本文展示如何编译并运行 iOS 平台的聊天室 UIKit 示例项目。 - -## 前提条件 - -开始前,确保你的开发环境满足如下条件: - -- Xcode 14.0 或以上版本; -- iOS 13.0 或以上版本; -- 项目中已设置有效的开发者签名。 - -## 操作步骤 - -### 第一步 下载 ChatroomUIKit 示例代码 - -点击 [github源码](https://github.com/easemob/UIKit_Chatroom_ios)下载示例代码到本机。 - -### 第二步 执行 pod 命令 - -1. 点击打开 **UIKit_Chatroom_ios** 文件夹。 - -2. 将 **Example** 文件夹拖拽到终端。 - -3. 在终端中输入如下命令,然后回车。 - -``` - pod install --repo-update -``` - -### 第三步 编译 - -编译时,需要传入 App Key、用户 ID 和用户 token。因此,编译前,你需要在[环信控制台](https://console.easemob.com/user/login)上创建有效的环信即时通讯 IM 开发者账号,并获取 App Key,[创建环信 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。此外,还需[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室)。 - -1. 使用 Xcode 打开 .xcworkspace 工程文件。 - -2. 在键盘上按下 **cmd**+**B** 进行编译,编译结果会有如下报错。 - -![img](/images/uikit/chatroomios/buildError.png) - - 将获取的 App Key、用户 token 和用户 ID 分别填入上图中的 `appKey`、`chatToken` 和 `userId` 字段。 - -3. 在键盘上按下 **cmd**+**B** 编译程序即可跑通项目。 - -4. 在键盘上按下 **cmd**+**R**,选中设备运行项目,查看运行结果。 - -### 第四步 体验项目 - -1. 若仅体验 UI,点击 **UIComponent**。 - - 这种情况下,第三步编译过程中的 `appKey`、`chatToken` 和 `userId` 字段可以填入空字符串。体验过程中,你可以选择是否显示 UI 功能的某些配置项。 - -2. 对于 UI 和业务体验(例如,发送礼物、聊天室成员管理或消息操作),点击 **UI&Business**。 - - 这种情况下,第三步编译过程中的 `appKey`、`chatToken` 和 `userId` 字段需传入环信控制台的配置。 - -## 注意事项 - -示例工程仅用于快速跑通流程,暂时未提供多成员交互测试。 - -## 编译常见问题 - -若 Xcode 15 编译出现以下报错 **Sandbox: rsync.samba(47334) deny(1) file-write-create...**,你可以在 **Build Setting** 中搜索 **ENABLE_USER_SCRIPT_SANDBOXING**,将 **User Script Sandboxing** 的设置改为 **NO**。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/ios/roomuikit_theme.md b/docs/uikit/chatroomuikit/ios/roomuikit_theme.md deleted file mode 100644 index 50419f16..00000000 --- a/docs/uikit/chatroomuikit/ios/roomuikit_theme.md +++ /dev/null @@ -1,76 +0,0 @@ -# 主题 - -ChatroomUIkit 内置浅色和深色主题,默认为浅色主题。 - -- 浅色主题 - -![img](/images/uikit/chatroomios/light_mode.png) - -- 深色主题 - -![img](/images/uikit/chatroomios/dark_mode.png) - -## 切换为内置主题 - -若从当前的主题切换到 ChatroomUIKit 内置的浅色或深色主题,可使用以下方法: - -````swift -Theme.switchTheme(style: .dark) -```` - -````swift -Theme.switchTheme(style: .light) -```` - -## 切换为自定义主题 - -自定义设置主题时,需要参考[设计指南](https://github.com/StevieJiang/Chatroom-UIkit-Design-Guide/blob/main/README.md)的主题色定义以下五种主题色的色相值。 - -ChatroomUIKit 中的所有颜色均使用 HSLA 颜色模型定义,该模型是一种使用色调、饱和度、亮度和 Alpha 表示颜色的方式。 - -- H(Hue):色相,颜色的基本属性,是色轮上从 `0` 到 `360` 的度数。`0` 是红色,`120` 是绿色,`240` 是蓝色。 - -- S(饱和度):饱和度是颜色的强度或纯度。饱和度越高,颜色越鲜艳;饱和度越低,颜色越接近灰色。饱和度以百分比值表示,范围为 `0%` 到 `100%`。`0%` 表示灰度,`100%` 表示全色。 - -- L(明度):明度是颜色的亮度或暗度。亮度越高,颜色越亮;亮度越低,颜色越深。亮度以百分比值表示,范围为 `0%` 到 `100%`。`0%`表示黑色,`100%` 表示白色。 - -- A(Alpha):Alpha 是颜色的透明度。值 `1` 表示完全不透明,`0` 表示完全透明。 - -通过调整 HSLA 模型的色相值,你可以实现精确的色彩控制。 - -```swift -Appearance.primaryHue = 191/360.0 -Appearance.secondaryHue = 210/360.0 -Appearance.errorHue = 189/360.0 -Appearance.neutralHue = 191/360.0 -Appearance.neutralSpecialHue = 199/360.0 -Theme.switchTheme(style: .custom) -``` - -## 切换 App 中除 ChatroomUIKit 之外的其他视图的主题 - -设置 ChatroomUIKit 的主题后,若你希望 app 的其他部分也与 ChatroomUIKit 使用相同的主题,可以使用以下方法确保 app 使用统一主题。 - -1. 在 `Theme` 类中注册你的视图。 - -```swift -Theme.registerSwitchThemeViews(view: self) -``` - -2. 在上述视图中实现 `ThemeSwitchProtocol` 协议。 - -```swift -extension YourView: ThemeSwitchProtocol { - -} -``` - -3. 在 `switchTheme` 方法中根据主题类型(浅色、深色和自定义)给你的子视图设置对应颜色。 - -## 设计指南 - -如果你对主题颜色,设计指南和细节有任何疑问,您可以在 Figma 设计稿中添加评论并提及我们的设计师 Stevie Jiang。 - -- [UI 设计资源](https://www.figma.com/community/file/1322495388317476706/chatroom-uikit)。 - -- [UI 设计指南](design_guide.html)。 diff --git a/docs/uikit/chatroomuikit/react-native/design_guide.md b/docs/uikit/chatroomuikit/react-native/design_guide.md deleted file mode 100644 index 52ba5431..00000000 --- a/docs/uikit/chatroomuikit/react-native/design_guide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/design_guide.html", - title: "设计指南" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/react-native/roomfeature_common.md b/docs/uikit/chatroomuikit/react-native/roomfeature_common.md deleted file mode 100644 index fb695c37..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomfeature_common.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_common.html", - title: "通用" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/react-native/roomfeature_member.md b/docs/uikit/chatroomuikit/react-native/roomfeature_member.md deleted file mode 100644 index 703fa2f8..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomfeature_member.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_member.html", - title: "成员管理" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/react-native/roomfeature_message.md b/docs/uikit/chatroomuikit/react-native/roomfeature_message.md deleted file mode 100644 index e76f080f..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomfeature_message.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_message.html", - title: "消息扩展" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_best_practice.md b/docs/uikit/chatroomuikit/react-native/roomuikit_best_practice.md deleted file mode 100644 index 6aa95c35..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_best_practice.md +++ /dev/null @@ -1,126 +0,0 @@ -# 最佳实践 - -## 初始化 ChatroomUIKit - -初始化是使用 ChatroomUIKit 的必要步骤,需在所有接口方法调用前完成。 - -```tsx -export function App() { - const palette = usePresetPalette(); - const dark = useDarkTheme(palette); - const light = useLightTheme(palette); - const [theme, setTheme] = React.useState(light); - // const [isReady, setIsReady] = React.useState(false); - // const fontFamily = 'Twemoji-Mozilla'; - // const [fontsLoaded] = useFonts({ - // [fontFamily]: require('../assets/twemoji.ttf'), - // }); - - return ( - { - if (language === "zh-Hans") { - return createStringSetCn(); - } else { - return createStringSetEn(); - } - }} - // fontFamily={fontFamily} - onInitialized={() => { - // todo: ChatroomUIKit 完成初始化的回调通知。 - }} - avatar={{ borderRadiusStyle: "large", localIcon: a_default_avatar }} - > - {/* todo: 添加应用程序代码 */} - - ); -} -``` - -## 登录 ChatroomUIKit - -你可以通过使用工程中的用户对象并遵守 `UserInfoProtocol` 协议登录 ChatroomUIKit,示例代码如下: - -```tsx -export function LoginScreen(props: Props) { - const {} = props; - const im = useRoomContext(); - const [isLoading, setIsLoading] = React.useState(false); - // ... - const loginAction = React.useCallback( - (onFinished: (isOk: boolean) => void) => { - // ... - im.login({ - userId, - userToken: params.token!, - userNickname: nickName, - userAvatarURL: avatar, - result: (params) => { - if (params.isOk) { - // todo: 登录成功 - } else { - // todo: 登录失败 - } - }, - }); - }, - [im] - ); - - return ( - - {/* todo: 登录页面代码, 触发登录 loginAction */} - - ); -} -``` - -## 初始化聊天室视图 - -1. 获取聊天室列表,加入指定的聊天室。除此之外,你还可以在环信即时通讯云控制台上[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室),获取聊天室 ID。 - -2. 加载聊天室视图 `Chatroom`,传入的参数包括聊天室 ID、聊天室所有者的用户 ID 及一些选项。 - -```tsx -export function ChatroomScreen(props: Props) { - return ( - - - - ); -} -``` - -## 监听聊天室的事件和错误 - -你可以调用 `useRoomListener` 方法添加监听器用于监听聊天室的事件和错误。 - -```tsx -useRoomListener( - React.useMemo(() => { - return { - onError: (params) => { - // todo: 处理错误通知 - }, - onFinished: (params) => { - // todo: 操作完成通知 - }, - }; - }, []) -); -``` - -## 参考 - -若要了解以上最佳实践的详情,请访问 [GitHub 仓库](https://github.com/AsteriskZuo/react-native-chat-room-demo)。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_config_item.md b/docs/uikit/chatroomuikit/react-native/roomuikit_config_item.md deleted file mode 100644 index 8e879586..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_config_item.md +++ /dev/null @@ -1,565 +0,0 @@ -# 可配置项 - -`room uikit sdk` 的组件中包含各种属性,你可以根据需求进行设置。 - -除了[主题组件](#roomuikit_theme.html),`room uikit sdk` 主要包括如下组件: - -| 组件名称 | 组件介绍 | -| --------------- | ---------------------------- | -| [I18n](#国际化组件) | 可以设置 `UIKit` 所有 UI 组件的语言。 | -| [Chatroom](#chatroom-组件) | 聊天室组件,集成了礼物发送、消息列表、成员列表、礼物接收等组件。 | -| [MessageList](#messagelist-组件) | 聊天室消息区域组件,用于显示发送或者接收到的消息。 | -| [ParticipantList](#participantlist-组件) | 聊天室成员列表组件,包括聊天室成员和禁言成员的管理。 | -| [GiftMessageList](#giftmessagelist-组件) | 聊天室打赏消息区域组件,用于显示打赏的礼物。 | -| [GlobalBroadcast](#globalbroadcast-组件) | 聊天室全局广播组件,用于向 app 下的所有聊天室发送消息。 | -| [MessageInput](#messageinput-组件) | 消息输入组件,用于发送各类消息。 | -| [BottomToolbar](#bottomtoolbar-组件) | 聊天室底部工具栏区域,可以与消息输入组件互相切换,支持添加自定义按钮。 | -| [BottomSheetGift](#bottomsheetgift-组件) | 发送礼物组件,可以发送礼物,礼物来源由开发者指定。 | -| [ReportMessage](#reportmessage-组件) | 聊天室举报组件。 | - -## 国际化组件 - -UIKit 支持多国语言切换,目前内置中文和英文,可以扩展其他语言。 - -例如:若要 UIKit 使用英文显示,可以如下设置: - -```tsx - -``` - -语言设置规则: - -- 若未设置语言,则使用默认的系统语言。 -- 若系统语言不是中文或者英文,则国内选择中文,国外选择英文。 -- 若设置的语言不是中文或者英文,并且没有提供相应的语言集合,则国内选择中文,国外选择英文。 - -例如,若开发者希望 `UIKit` 和应用均使用中文,设置如下: - -```tsx -// ... -// 创建应用需要的语言包。 -function createLanguage(type: LanguageCode): StringSet { - return { - 'Chinese text.': '中文文本.', - }; -} -// ... -// 设置指定语言集合,并且提供语言翻译源。 -; -// ... -// 在需要国际化的地方。 -const { tr } = useI18nContext(); -return {tr('Chinese text.')}; -``` - -例如,若开发者希望应用和 UIKit 均显示法语,设置如下: - -```tsx -// ... -// 创建应用扩展语言集合。 -function createAppLanguage(type: LanguageCode): StringSet { - if (type === 'fr') { - return { - 'French text.': 'Text français.', - }; - } - return { - 'French text.': 'French text.', - }; -} -// 创建 UIKit 的语言集合,需要找到 UIKit 内置的文件 `StringSet.en.tsx`, 将所有的 `value` 修改为法语版本。 -export function createUIKitLanguage(type: LanguageCode): StringSet { - if (type === 'fr') { - return { - 'Private Chat': 'Private Chat', - '...': '...', - }; - } -} -// ... -// 设置指定语言集合,并且提供语言翻译源。 -; -``` - -## 初始化 - -`Chatroom UIKit SDK` 的入口为 `Container` 组件,主要负责集成其他组件和参数配置。 - -```tsx -export type ContainerProps = React.PropsWithChildren<{ - appKey: string; - isDevMode?: boolean; - language?: StringSetType; - languageBuiltInFactory?: CreateStringSet; - languageExtensionFactory?: CreateStringSet; - palette?: Palette; - theme?: Theme; - roomOption?: PartialRoomOption; - avatar?: { - borderRadiusStyle?: CornerRadiusPaletteType; - }; - fontFamily?: string; - onInitialized?: () => void; -}>; -``` - -```tsx -// 主要控制 `Chatroom` 组件中的组件是否加载。 -export type RoomOption = { - globalBroadcast: { - isVisible: boolean; - }; - gift: { - isVisible: boolean; - }; - messageList: { - isVisibleGift: boolean; - isVisibleTime: boolean; - isVisibleTag: boolean; - isVisibleAvatar: boolean; - }; -}; -``` - -| 参数 | 是否必需 | 描述 | -| :----------- | :----- | :--------------------- | -| `appKey` | 是 | 你在环信即时通讯云控制台创建应用时填入的应用名称。该参数是 App Key 的一部分。可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的 **应用详情** 页面查看。 | -| `isDevMode` | 否 | 如果设置为 `true`,则激活日志打印等工具。 | -| `language` | 否 | 设置当前的语言,若未设置,则获取系统当前的语言作为默认值。 | -| `languageBuiltInFactory` | 否 | 若未设置则使用内置的语言资源。通常可以修改内置的 UI 内容。 | -| `languageExtensionFactory` | 否 | 如果设置将扩展语言资源。通常应用的 UI 也需要国际化。 | -| `palette` | 否 | 设置当前的调色板,主题服务的重要依赖。 | -| `theme` | 否 | 若未设置主题,则使用 `light` 为默认主题。 | -| `roomOption` | 否 | 聊天室选项。具体参见以下全局配置参数。 | -| `avatar` | 否 | 设置全局头像的圆角样式。 | -| `fontFamily` | 否 | 支持自定义字体。默认使用系统字体。 | -| `onInitialized` | 否 | 初始化完成的回调通知。 | - -全局配置参数如下: - -| 参数 | 是否必需 | 描述 | -| :----------- | :----- | :--------------------- | -| `globalBroadcast` | 否 | 全局广播组件配置,可以设置是否加载。 | -| `gift` | 否 | 聊天室打赏消息区域组件,可以设置是否加载。 | -| `messageList` | 否 | 聊天室消息区域配置:
- `isVisibleGift`: 是否加载聊天室打赏消息区域组件;
- `isVisibleTime`: 是否显示时间标签;
- `isVisibleTag`: 是否显示用户标签;
- `isVisibleAvatar`: 是否显示头像标签。 | - -通常 `Container` 会处于应用的底层,一般为根组件,或者与根组件同一级别。例如: - -```tsx -export function App() { - return {children}; -} -``` - -## Chatroom 组件 - -Chatroom 组件集成了成员列表组件 `ParticipantList`、消息输入组件 `MessageInput`、消息区域组件 `MessageList`、打赏消息区域组件 `GiftMessageList` 和全局广播通知组件 `GlobalBroadcast`等。该组件为页面级组件,基本占据了整个屏幕,如果要添加组件,建议添加为 Chatroom 的子组件或背景组件。 - -示例如下: - -```tsx -// ... -// 创建引用对象 -const ref = React.useRef({} as any); -// ... -// 添加组件到渲染树 -; -``` - -由于 `UIKit` 没有路由 (`React-Native` 未内置),所以若需要成员搜索,设置如下: - -```tsx - { - // todo: 点击搜索按钮跳转到搜索页面 - navigation.push('SearchParticipant', { params: { memberType } }); - }, - }, - }} - roomId={room.roomId} - ownerId={room.owner} -/> -``` - -`Chatroom` 组件提供如下属性: - -| 属性 | 是否必需 | 描述 | -| -------------------------- | -------- | ---------------------------------------------------- | -| containerStyle | 否 | 设置组件容器样式。该属性可以控制 `Chatroom` 组件的背景、位置、大小、边框等样式。 | -| GiftMessageList | 否 | 打赏消息区域组件的渲染器。默认使用内部组件 `GiftMessageList`,可以设置类型为 `GiftMessageListComponent` 的自定义组件。替换之后的行为完全由开发者控制,如果在 `GiftMessageList` 组件的基础上进行扩展或者修改则更为方便。 | -| GlobalBroadcast | 否 | 全局广播组件的渲染器。默认使用内部组件 `GlobalBroadcast`,可以设置类型为 `GlobalBroadcastComponent` 的自定义组件。 | -| MessageList | 否 | 消息区域组件的渲染器。默认使用内部组件 `MessageList`,可以设置类型为 `MessageListComponent` 的自定义组件。 | -| MessageInput | 否 | 输入组件的渲染器。默认使用内部组件 `MessageInput`,可以设置类型为 `MessageInputComponent` 的自定义组件。该组件包括聊天室底部工具栏区域组件 `BottomToolbar`,若要自定义需考虑这一点。 | -| BottomSheetParticipantList | 否 | 成员列表组件的渲染器。默认使用内部组件` BottomSheetParticipantList`,可以设置类型为 `BottomSheetParticipantListComponent` 的自定义组件。| -| input | 否 | 输入组件的属性。 | -| messageList | 否 | 消息区域的属性。 | -| globalBroadcast | 否 | 聊天室全局广播的属性。 | -| gift | 否 | 打赏消息的属性。| -| participantList | 否 | 成员列表的属性。 | -| backgroundView | 否 | 背景组件。 | - -`Chatroom` 提供如下方法: - -| 方法 | 描述 | -| --------------------- | ------------------------------------------ | -| getGlobalBroadcastRef | 获取 `GlobalBroadcast` 组件的引用。默认通过收到后台的消息广播进行显示,开发者可以插入自定义全局广播消息。 | -| getGiftMessageListRef | 获取 `GiftMessageList` 组件的引用。 | -| getParticipantListRef | 获取 `BottomSheetParticipantList` 的组件引用。开发者可以自定义成员管理相关内容。 | -| getMessageListRef | 获取 `MessageList` 组件的引用。默认通过发送消息或者接收消息显示消息,开发者可以手动插入自定义消息、删除消息、滚动到最底部等操作。 | -| joinRoom | 加入聊天室。加载 `Chatroom` 组件时,你会自动加入聊天室。若由于网络等问题加入失败,开发者可以通过该方法尝试重新加入聊天室。 | -| leaveRoom | 退出聊天室,而不用卸载组件。 | - -![img](/images/uikit/chatroomrn/chatroom.png) - -## MessageList 组件 - -聊天室消息区域组件 `MessageList` 提供消息的显示,聊天室接收到的文本消息、表情消息、礼物消息以及发送成功的消息会显示在该区域。 - -可以在消息区域中对消息进行操作,例如,翻译文本消息为目标语言、撤销消息和消息上报等。你可以通过长按消息列表项弹出菜单进行相应操作。 - -数据上报组件支持自定义选项,可以自定义选项上报不同内容。 - -示例代码如下: - -```tsx -// ... -// 创建组件引用对象 -const ref = React.useRef({} as any); -// 添加消息列表组件到渲染树 -; -// ... -// 添加消息到消息列表,消息会显示在列表 -ref?.current?.addSendedMessage?.(message); -``` - -`MessageList` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ------------------------ | -------- | --------------------------------------------------------------- | -| visible | 否 | 设置组件是否可见。 | -| onUnreadCount | 否 | 未读数发生变化时的回调通知。 | -| onLongPressItem | 否 | 长按消息列表项时的回调通知。 | -| containerStyle | 否 | 设置组件容器样式。支持背景、位置、大小、边框等的设置。 | -| onLayout | 否 | 组件布局发生变化时的回调通知。 | -| MessageListItemComponent | 否 | 消息列表项的渲染器。 | -| reportProps | 否 | 消息上报的属性。 | -| maxMessageCount | 否 | 组件可以显示的最大消息数,默认为 `1000`,超过限制后将移除最早消息。 | -| messageMenuItems | 否 | 自定义消息菜单项,追加到内置菜单后面。 | - -`MessageList` 提供的方法如下表所示: - -| 方法 | 描述 | -| ---------------- | -------------------------------- | -| addSendedMessage | 将输入框中的内容发送到消息列表。 | -| scrollToEnd | 滚动消息列表到底部。 | - -![img](/images/uikit/chatroomrn/message_context_menu.png) - -![img](/images/uikit/chatroomrn/message_report.png) - -## ParticipantList 组件 - -聊天室成员组件可以显示和管理聊天室成员,聊天室所有者、禁言列表以及管理权限。 - -聊天室所有者可以修改成员状态,例如,对成员禁言或踢出聊天室。 - -:::tip -聊天室成员列表组件的显示的入口并不在 `UIKit`, 需要应用开发者自行实现,例如,添加一个按钮,点击后显示聊天室成员列表组件。 -::: - -`BottomSheetParticipantList` 组件是一个独立组件,由 `SimulativeModal` 和 `ParticipantList` 组成,可以进行显示和隐藏。 - -示例代码如下: - -```tsx -// ... -// 创建组件引用对象 -const ref = React.useRef({} as any); -// 添加成员列表组件到渲染树 -; -// ... -// 用户实现显示具体动作,例如:添加按钮,点击按钮显示成员列表组件。 -ref?.current?.startShow?.(); -``` - -`BottomSheetParticipantList` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ------------------- | -------- | ---------------------------------------------------- | -| onSearch | 否 | 点击搜索样式的回调通知。 | -| onNoMoreMember | 否 | 下滑加载更多成员时,没有更多成员的回调通知。| -| containerStyle | 否 | 设置组件容器样式。支持背景、位置、大小、边框等的设置。| -| maskStyle | 否 | 设置组件容器以外区域样式。 | -| MemberItemComponent | 否 | 成员列表项的渲染器。 | - -`BottomSheetParticipantList` 提供的方法如下表所示: - -| 方法 | 描述 | -| --------------------- | -------------------------------- | -| startShow | 显示成员列表组件。 | -| startHide | 隐藏成员列表组件,隐藏动画完成后返回通知。 | -| getParticipantListRef | 获取成员列表或者禁言列表组件的引用。 | - -`ParticipantList` 提供的方法如下表所示: - -| 方法 | 描述 | -| ------------ | ---------------------------------------------- | -| initMenu | 初始化自定义成员列表菜单,追加到内置菜单的后面。 | -| removeMember | 删除成员。 | -| muteMember | 禁言或者解除禁言成员。 | -| closeMenu | 关闭菜单。 | - -![img](/images/uikit/chatroomrn/member_list.png) - -![img](/images/uikit/chatroomrn/member_context_menu.png) - -## GiftMessageList 组件 - -聊天室打赏消息区域组件 `GiftMessageList` 用于展示发送的礼物效果,礼物消息可以显示在消息列表,也可以显示在该组件。 - -示例代码如下: - -```tsx -// ... -// 创建组件引用对象 -const ref = React.useRef({} as any); -// 添加组件到渲染树 -; -// ... -// 添加礼物消息到组件消息队列中,排队显示。 -ref.current?.pushTask({ - model: { - id: seqId('_gf').toString(), - nickName: 'NickName', - giftCount: 1, - giftIcon: 'http://notext.png', - content: 'send Agoraship too too too long', - }, -}); -``` - -`GiftMessageList` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ----------------------- | -------- | ---------------------------------------------- | -| visible | 否 | 设置组件是否可见。 | -| containerStyle | 否 | 设置组件容器样式。支持背景、位置、边框等的设置。 | -| GiftEffectItemComponent | 否 | 打赏消息列表项的渲染器。 | - -`GiftMessageList` 提供的方法如下表所示: - -| 方法 | 描述 | -| -------- | ------------------------------------ | -| pushTask | 将礼物消息任务添加到队列中,排队加载。 | - -## GlobalBroadcast 组件 - -全局广播通知组件 `GlobalBroadcast` 接收和显示全局全局广播,也是通过添加消息到队列排队显示。 - -简单示例如下: - -```tsx -// ... -// 创建组件引用对象 -const ref = React.useRef({} as any); -// ... -// 添加组件到渲染树 -; -// ... -// 将消息添加到任务队列,排队显示。 -let count = 1; -ref.current?.pushTask?.({ - model: { - id: count.toString(), - content: count.toString() + content, - }, -}); -``` - -`GlobalBroadcast` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ----------------------- | -------- | ---------------------- | -| visible | 否 | 设置组件是否可见。 | -| playSpeed | 否 | 消息播放时滚动的速度,默认值为 8。 | -| containerStyle | 否 | 设置组件容器样式。支持背景、位置、大小、边框等的设置。 | -| textStyle | 否 | 设置组件文本样式。 | -| icon | 否 | 设置组件上的图标样式。 | -| GiftEffectItemComponent | 否 | 打赏消息列表项的渲染器。 | -| onFinished | 否 | 所有消息播放完成时的回调通知。 | -| onLayout | 否 | 组件布局发生变化时的回调通知。 | - -`GlobalBroadcast` 提供的方法如下表所示: - -| 方法 | 描述 | -| -------- | ---------------------------- | -| pushTask | 将消息添加到队列中,排队加载。 | - -## MessageInput 组件 - -消息输入框组件 `MessageInput` 可以发送文本、表情等消息,可以与聊天室底部工具栏区域互相动态切换。当点击聊天室底部工具栏区域组件时切换到输入状态,发送消息或者关闭输入框时切换为聊天室底部工具栏区域组件。 - -简单示例如下: - -```tsx -// ... -// 创建引用对象 -const ref = React.useRef({} as any); -// ... -// 添加组件到渲染树 - { - // todo: 调用消息列表引用对象添加消息到消息列表 - }} -/>; -// ... -// 关闭输入状态 -ref?.current?.close?.(); -``` - -`MessageInput` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| ---------------------- | -------- | --------------------------------------------- | -| onInputBarWillShow | 否 | 将要切换为输入状态时的回调通知。 | -| onInputBarWillHide | 否 | 将要切换为聊天室底部工具栏区域时的回调通知。 | -| onSended | 否 | 发送完成时的回调通知。 | -| keyboardVerticalOffset | 否 | 键盘偏移量的数值。 | -| closeAfterSend | 否 | 发送消息后是否切换为聊天室底部工具栏区域。 | -| first | 否 | 聊天室底部工具栏区域的第一个自定义组件。 | -| after | 否 | 聊天室底部工具栏区域的自定义组件列表,最多可添加 3 个自定义组件。 | -| onLayout | 否 | 聊天室底部工具栏区域的布局发生变化时的回调通知。 | - -`MessageInput` 提供的方法如下表所示: - -| 方法 | 描述 | -| ----- | ------------------------------------ | -| close | 主动关闭输入状态,切换为聊天室底部工具栏区域。 | - -![img](/images/uikit/chatroomrn/input_bar.png) - -![img](/images/uikit/chatroomrn/emoji_list.png) - -## BottomToolbar 组件 - -聊天室底部工具栏区域组件 `BottomToolbar` 与消息输入框组件组成复合组件,可以互相切换。 - -## BottomSheetGift 组件 - -礼物列表组件 `BottomSheetGift` 提供自定义礼物列表,点击礼物项的发送按钮发送到聊天室。 - -:::tip -礼物列表组件是一个独立的组件,需要应用开发者自行实现显示和加载等操作。 -::: - -示例代码如下: - -```tsx -// ... -// 创建引用对象 -const ref = React.useRef({} as any); -// ... -// 添加组件到渲染树 - { - // todo: 发送选择的礼物。 - }} -/>; -// ... -// 显示礼物列表组件 -ref?.current?.startShow?.(); -``` - -:::tip -发送礼物组件提供 `BottomSheetGift` 和 `BottomSheetGift2`,二者的区别为是模态组件还是非模态组件。 -::: - -`BottomSheetGift` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| --------- | -------- | -------------------------- | -| gifts | 否 | 礼物列表数组。 | -| maskStyle | 否 | 设置组件容器以外区域样式。 | -| onSend | 否 | 点击发送按钮时的回调通知。 | - -`BottomSheetGift` 提供的方法如下表所示: - -| 方法 | 描述 | -| ----------------- | -------------------------------- | -| startShow | 显示组件。 | -| startShowWithInit | 显示组件,同时可以初始化列表。 | -| startHide | 隐藏组件,隐藏动画完成后返回通知。 | - -![img](/images/uikit/chatroomrn/gift_list.png) - -## ReportMessage 组件 - -消息上报组件 `ReportMessage`,可以设置上报内容。 - -示例代码如下: - -```tsx -// ... -// 创建引用对象 -const ref = React.useRef({} as any); -// ... -// 添加组件到渲染树 -; -// ... -// 显示组件 -ref?.current?.startShow?.(); -// ... -// 选择列表项,确认上报。 -``` - -`BottomSheetMessageReport` 提供的属性如下表所示: - -| 属性 | 是否必需 | 描述 | -| -------------- | -------- | ---------------------------------------------------- | -| data | 否 | 上报内容列表数组。 | -| maskStyle | 否 | 设置组件容器以外区域样式。 | -| containerStyle | 否 | 设置组件容器样式。支持背景、位置、大小、边框等的设置。 | -| onReport | 否 | 点击上报按钮时的回调通知。 | - -`BottomSheetMessageReport` 提供的方法如下表所示: - -| 方法 | 描述 | -| --------- | -------------------------------- | -| startShow | 显示组件。 | -| startHide | 隐藏组件,隐藏动画完成后返回通知。 | - - -![img](/images/uikit/chatroomrn/message_report.png) - diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_customize.md b/docs/uikit/chatroomuikit/react-native/roomuikit_customize.md deleted file mode 100644 index 6b5a41e1..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_customize.md +++ /dev/null @@ -1,123 +0,0 @@ -# 自定义 - -本文以 `Chatroom` 组件为例介绍如何添加自己的业务逻辑,实现个性化业务需求。 - -`Chatroom` 组件为页面级组件,包括成员列表组件 `ParticipantList`、输入组件 `MessageInput`、消息区域组件 `MessageList`、打赏消息区域组件 `GiftMessageList` 和全局广播通知组件 `GlobalBroadcast` 等。除了提供各种属性实现自定义配置,Chatroom 组件中的子组件支持自定义,你可以基于自己的逻辑实现更新或替换这些子组件。 - -## 自定义 GiftMessageList 组件 - -若 ChatroomUIKit 中内置的打赏消息组件 `GiftMessageList` 无法满足需求,你可以在满足 `GiftMessageListComponent` 的约束的前提下创建新组件,例如 `MyGiftMessageList`,实现自定义业务逻辑和自定义样式。 - -```tsx -export const MyGiftMessageList: GiftMessageListComponent = React.forwardRef< - GiftMessageListRef, - GiftMessageListProps ->(function ( - props: GiftMessageListProps, - ref?: React.ForwardedRef -) { - // todo:实现你的业务逻辑或修改现有的业务逻辑。 - const {} = props; - React.useImperativeHandle( - ref, - () => { - return { - pushTask: (task: GiftMessageListTask) => { - // todo: 实现该接口。 - }, - }; - }, - [] - ); - return <>; -}); -``` - -利用新的 `MyGiftMessageList` 组件替换内置的 `GiftMessageList` 组件,添加到 Chatroom 组件。 - -```tsx - -``` - -## 自定义 GlobalBroadcast 组件 - -若 ChatroomUIKit 中内置的全局广播消息组件 `GlobalBroadcast` 无法满足需求,你可以在满足 `GlobalBroadcastComponent` 的约束的情况下创建新组件,例如 `MyGlobalBroadcast`,实现自定义业务逻辑和自定义样式。 - -```tsx -export const MyGlobalBroadcast = React.forwardRef< - GlobalBroadcastRef, - GlobalBroadcastProps ->(function ( - props: GlobalBroadcastProps, - ref?: React.ForwardedRef -) { - // todo: 实现自己的业务逻辑或修改当前业务逻辑。 - React.useImperativeHandle( - ref, - () => { - return { - pushTask: (task: GlobalBroadcastTask) => { - // todo:实现该接口。 - }, - }; - }, - [] - ); - return <>; -}); -``` - -利用 `MyGlobalBroadcast` 组件替换内置的 `GlobalBroadcast` 组件。 - -```tsx - -``` - -## 自定义消息列表项样式 - -修改组件的消息样式。示例代码如下: - -```tsx -export function MyMessageListItem(props: MessageListItemProps) { - // todo:实现自己的业务逻辑或修改当前业务逻辑。 - return <>; -} -export const MyMessageListItemMemo = React.memo(MyMessageListItem); -``` - -更新消息列表项的样式。示例代码如下: - -```tsx - -``` - -## 自定义聊天室成员列表项样式 - -修改聊天室成员组件的列表项样式。示例代码如下: - -```tsx -export function MyParticipantListItem(props: ParticipantListItemProps) { - // todo:实现自己的业务逻辑或修改当前业务逻辑。 - return <>; -} - -export const MyParticipantListItemMemo = React.memo(MyParticipantListItem); -``` - -更新聊天室成员组件的列表项样式。示例代码如下: - -```tsx - -``` diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_integrated.md b/docs/uikit/chatroomuikit/react-native/roomuikit_integrated.md deleted file mode 100644 index c5d7d198..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_integrated.md +++ /dev/null @@ -1,34 +0,0 @@ -# 集成 ChatroomUIKit - -使用 ChatroomUIKit 之前,你需要将 ChatroomUIKit 集成到你的应用中。 - -## 前提条件 - -- MacOS 12 或以上版本; -- React-Native 0.66 或以上版本; -- NodeJs 16.18 或以上版本; -- iOS 应用:Xcode 13 或以上版本以及它的相关依赖工具; -- Android 应用:Android Studio 2021 或以上版本以及它的相关依赖工具; -- 有效的环信即时通讯 IM 开发者账号和 [App key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 - -## 创建项目或现有项目 - -如果创建请执行命令: - -```sh -npx react-native init MyApp --version 0.71.11 -``` - -## 安装 UIKit 到项目中 - -进入项目,执行以下命令: - -```sh -npm install react-native-chat-room -# or -yarn add react-native-chat-room -# or -npx expo install react-native-chat-room -``` - - diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_overview.md b/docs/uikit/chatroomuikit/react-native/roomuikit_overview.md deleted file mode 100644 index 52115a8d..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_overview.md +++ /dev/null @@ -1,35 +0,0 @@ -# 概述 - -环信 ChatroomUIKit 提供 UIKit 的各种组件帮助开发者根据实际业务需求快速搭建聊天室应用。通过该 UIKit,聊天室中的用户可实时交互,发送普通弹幕消息、打赏消息和全局广播等功能。 - -- 若要访问源码,请点击[这里](https://github.com/easemob/UIKit_Chatroom_rn)。 - -- 你可以扫描以下 Android 和 iOS 平台的二维码体验环信聊天室 UIKit demo: - -![img](/images/uikit/chatroomrn/demo_rn.png) - -## 功能 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - 创建聊天室:ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - 解散聊天室:ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - 离开聊天室:聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - 发送弹幕:用户在聊天室中向其他参与者发送文字和表情的消息。 - - 打赏:用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - 全局广播:向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - 未读消息数:在一个聊天室中用户尚未读取的消息数量。 - - 已禁言列表:记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - 暗黑模式:ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展** - - 消息举报:在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - 消息翻译:将聊天室中的单条消息从一种语言转换成另一种语言。 - - 消息撤回:在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - 禁言成员:聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - 查看成员列表:聊天室成员列表显示了该聊天室中的当前在线用户。 - - 搜索成员:在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - 禁言成员:聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - 移除成员:聊天室所有者将指定成员从聊天室中踢出。 - diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_quickstart.md b/docs/uikit/chatroomuikit/react-native/roomuikit_quickstart.md deleted file mode 100644 index ad02cb8c..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_quickstart.md +++ /dev/null @@ -1,121 +0,0 @@ -# 快速开始 - -利用 ChatroomUIKit,你可以轻松实现聊天室内的用户交互。本文介绍如何实现在聊天室中发送消息。 - -## 前提条件 - -- MacOS 12 或以上版本; -- React-Native 0.66 或以上版本; -- NodeJs 16.18 或以上版本; -- iOS 应用:Xcode 13 或以上版本以及它的相关依赖工具; -- Android 应用:Android Studio 2021 或以上版本以及它的相关依赖工具; -- 有效的环信即时通讯 IM 开发者账号和 [App Key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 - -## 操作流程 - -### 第一步 创建聊天室和用户 - -在环信控制台[创建聊天室](/product/enable_and_configure_IM.html#创建聊天室)和[用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### 第二步 创建项目 - -```sh -npx react-native init MyApp --version 0.71.11 -``` - -### 第三步 项目中安装 UIKit - -进入创建的项目,执行以下命令: - -```sh -npm install react-native-chat-room -# or -yarn add react-native-chat-room -# or -npx expo install react-native-chat-room -``` - -### 第四步 初始化 ChatroomUIKit - -你可以在应用加载时或使用 ChatroomUIKit 之前对其进行初始化。 - -初始化时,需要填写必要的参数和配置,将 `Container` 放在组件树的根部。 - -初始化时,需传入 App Key。你可以在[环信即时通讯云控制台](https://console.easemob.com/user/login)的**应用详情**页面查看 App Key。 - -```tsx -export function App() { - const appKey = ''; - return {/* // todo: 在这里添加组件 */}; -} -``` - -### 第五步 登录 ChatroomUIKit - -进入聊天室前,需首先通过用户 ID 和用户 Token 登录 ChatroomUIKit。 - -:::tip -若你已集成了 IM SDK,SDK 的所有用户 ID 均可用于登录 ChatroomUIKit。 -::: - -为了方便快速体验,你可以在[环信控制台](https://console.easemob.com/user/login)的**应用概览** > **用户认证**页面创建用户并查看用户 token。**用户认证**页面中的用户仅用于快速体验或调试目的。 - -在开发环境中,你需要在环信控制台[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户),从你的 App Server 获取用户 token,详见[使用环信用户 token 鉴权](/product/easemob_user_token.html)。 - -```tsx -// ... -// 获取 IM 服务对象 -const im = useRoomContext(); -// ... -// 登录服务 -// userId 和 userToken 为必填项 -im.login({ - userId: '', - userToken: '', - userNickname: '', - userAvatarURL: '', - gender: 1, - identify: '', - result: ({ isOk, error }) => { - // todo: isOk === true 用户登录成功 - // todo: isOk === false 用户登录失败 - }, -}); -``` - -### 第六步 进入聊天室 - -进入聊天室前,需要调用 `im.fetchChatroomList` 方法获取要加入的聊天室 ID 以及该聊天室的创建者的用户 ID。 - -通过加载 `Chatroom` 组件,你会自动加入聊天室,并返回是否成功加入。若该组件加载失败,你可以调用加入聊天室的 API 加入聊天室。 - -```tsx -// ... -// 创建组件引用对象。 -const chatroomRef = React.useRef({} as any); -// ... -// 关注组件状态变化。 -useRoomListener( - React.useMemo(() => { - return { - onError: (params) => { - // todo: 失败通知处理。错误类型可参考 UIKitError。 - // todo: 例如:被踢出聊天室后,可调用 API 重新加入:chatroomRef.current?.joinRoom({roomId, ownerId}}); - }, - onFinished: (params) => { - // todo: 该通知会包含完成结果。例如:加入聊天室之后收到通知。通知类型可以参考 RoomEventType。 - }, - }; - }, []) -); -// ... -// 加载组件到渲染树。 -; -// ... -``` - -### 第七步 发送第一条消息 - -在屏幕下方输入消息内容,点击 **发送** 按钮,发送消息。 - -![img](/images/uikit/chatroomandroid/click_chat.png =500x500) diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_releasenote.md b/docs/uikit/chatroomuikit/react-native/roomuikit_releasenote.md deleted file mode 100644 index 95d69f4b..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_releasenote.md +++ /dev/null @@ -1,31 +0,0 @@ -# 聊天室 UIKit 更新日志 - - - -## 版本 V1.0.0 2023-12-29 - -### 新增特性 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - [创建聊天室](roomfeature_common.html#创建聊天室):ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - [离开聊天室](roomfeature_common.html#离开聊天室):聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - [发送弹幕消息](roomfeature_common.html#发送弹幕):用户在聊天室中向其他参与者发送文字和表情的消息。 - - [打赏](roomfeature_common.html#打赏):用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - [全局广播](roomfeature_common.html#全局广播):向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - [未读消息数](roomfeature_common.html#未读消息数):在一个聊天室中用户尚未读取的消息数量。 - - [已禁言列表](roomfeature_common.html#已禁言列表):记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - [暗黑模式](roomfeature_common.html#暗黑模式):ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展**(长按一条消息可进行的操作) - - [消息举报](roomfeature_message.html#消息举报):在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - [消息翻译](roomfeature_message.html#消息翻译):将聊天室中的单条消息从一种语言转换成另一种语言。 - - [消息撤回](roomfeature_message.html#消息撤回):在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - [禁言成员](roomfeature_message.html#禁言成员):聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - [查看成员列表](roomfeature_member.html#查看成员列表):聊天室成员列表显示了该聊天室中的当前在线用户。 - - [搜索成员](roomfeature_member.html#搜索成员):在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - [禁言成员](roomfeature_member.html#禁言成员):聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - [移除成员](roomfeature_member.html#移除成员):聊天室所有者将指定成员从聊天室中踢出。 - diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_run.md b/docs/uikit/chatroomuikit/react-native/roomuikit_run.md deleted file mode 100644 index 34595466..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_run.md +++ /dev/null @@ -1,63 +0,0 @@ -# 跑通示例项目 - -环信提供一个开源的 ChatroomUIKit 示例项目,演示了如何使用该 UIKit 快速搭建聊天室页面,实现完整业务。 - -## 开发环境要求 - -- MacOS 12 或以上版本; -- React-Native 0.66 或以上版本; -- NodeJs 16.18 或以上版本; -- iOS 应用:Xcode 13 或以上版本,以及它的相关依赖工具。 -- Android 应用:Android Studio 2021 或以上版本,以及它的相关依赖工具。 - -## 操作步骤 - -### 第一步 在项目中安装 ChatroomUIKit - -```tsx -npm install react-native-chat-room -// or -yarn add react-native-chat-room -// or -npx expo install react-native-chat-room -``` - -### 第二步 示例项目演示 - -`example` 文件夹中为示例项目,可以下载源码、进行编译,然后运行进行体验。 - -下载源码仓库: - -```sh -git clone https://github.com/agora/rncr/react-native-chat-room -``` - -或者,你可以下载源码压缩包: - -```sh -curl -L -o file.zip https://github.com/AsteriskZuo/react-native-chat-room/archive/refs/heads/main.zip -``` - -### 第三步 项目初始化 - -1. 进入项目根目录,运行 `yarn & yarn env` 命令完成初始化。 - -2. 在生成的文件 `example/src/env.ts` 中,修改必要的配置项。 - -- 对于 `iOS` 应用: - - 需要运行 `pod install` 命令进行初始化。 - -- 对于 `Android` 应用: - - 需要执行 `gradle sync` 命令进行初始化。 - -### 第四步 运行项目 - -在 `react-native-chat-room/tree/main/example` 目录下运行以下命令: - -```sh -yarn run ios -// or -yarn run android -``` \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/react-native/roomuikit_theme.md b/docs/uikit/chatroomuikit/react-native/roomuikit_theme.md deleted file mode 100644 index 11d1265a..00000000 --- a/docs/uikit/chatroomuikit/react-native/roomuikit_theme.md +++ /dev/null @@ -1,58 +0,0 @@ -# 主题 - -ChatroomUIkit 内置浅色和深色主题,默认为浅色主题。每个 UI 组件都会用到主题。 - -- 浅色主题 - -![img](/images/uikit/chatroomandroid/light_mode.png) - -- 深色主题 - -![img](/images/uikit/chatroomandroid/dark_mode.png) - -## 切换主题 - -若切换 ChatroomUIKit 内置的浅色或深色主题,可使用以下方法: - -```tsx -// ... -// 设置主题 -const palette = usePresetPalette(); -const dark = useDarkTheme(palette); -const light = useLightTheme(palette); -const [theme, setTheme] = React.useState(light); -// ... -// 添加组件到渲染树 -; -// ... -// 切换为浅色或深色主题 -setTheme(theme === light ? dark : light); -``` - -## 设置自定义主题颜色 - -`usePresetPalette` 可以使用内置的默认主题颜色,也可以使用 `useCreatePalette` 设置自定义主题颜色。 - -```swift -// 自定义颜色。通过修改颜色具体值,组件中对应颜色将统一改变。 -// 参考这里:https://www.figma.com/file/OX2dUdilAKHahAh9VwX8aI/Streamuikit?type=design&node-id=101-41012&mode=design&t=Fzou3Gwsk4owLLbr-4 -const { createPalette } = useCreatePalette({ - colors: { - primary: 203, - secondary: 155, - error: 350, - neutral: 203, - neutralSpecial: 220, - }, -}); -const palette = createPalette(); -// ... -``` - -## 设计指南 - -如果你对主题颜色,设计指南和细节有任何疑问,您可以在 Figma 设计稿中添加评论并提及我们的设计师 Stevie Jiang。 - -- [UI 设计资源](https://www.figma.com/community/file/1322495388317476706/chatroom-uikit)。 - -- [UI 设计指南](design_guide.html)。 diff --git a/docs/uikit/chatroomuikit/web/design_guide.md b/docs/uikit/chatroomuikit/web/design_guide.md deleted file mode 100644 index 52ba5431..00000000 --- a/docs/uikit/chatroomuikit/web/design_guide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/design_guide.html", - title: "设计指南" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/web/roomfeature_common.md b/docs/uikit/chatroomuikit/web/roomfeature_common.md deleted file mode 100644 index fb695c37..00000000 --- a/docs/uikit/chatroomuikit/web/roomfeature_common.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_common.html", - title: "通用" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/web/roomfeature_member.md b/docs/uikit/chatroomuikit/web/roomfeature_member.md deleted file mode 100644 index 703fa2f8..00000000 --- a/docs/uikit/chatroomuikit/web/roomfeature_member.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_member.html", - title: "成员管理" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/web/roomfeature_message.md b/docs/uikit/chatroomuikit/web/roomfeature_message.md deleted file mode 100644 index e76f080f..00000000 --- a/docs/uikit/chatroomuikit/web/roomfeature_message.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -{ - pageUri: "/uikit/chatroomuikit/android/roomfeature_message.html", - title: "消息扩展" -} ---- \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/web/roomuikit_best_practice.md b/docs/uikit/chatroomuikit/web/roomuikit_best_practice.md deleted file mode 100644 index 4dcaa7bd..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_best_practice.md +++ /dev/null @@ -1,124 +0,0 @@ -# 最佳实践 - - - -## 初始化 - -`Chatroom` 和 `ChatroomMember` 组件需要包裹在 `UIKitProvider` 组件内部使用。如果 `UIKitProvider` 在初始化完成前在组件内部使用 `useClient` 获取 SDK,则会获取失败,所以建议将 `UIKitProvider` 放在使用 `Chatroom` 或 `ChatroomMember` 组件的父组件中。 - -```tsx -// App.ts -// ... -const App = () => { - return -} - -// idnex.ts -// ... -ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - -) -``` - -## 登录 - -UIKit 提供两种登录方式: - -- 初始化时指定 `userId` 和 `password/token` 进行自动登录。 -- 使用 `useClient` 获取 SDK 实例进行手动登录。 - -```tsx -// 手动登录 -// ... -const App = () => { - const client = useClient() - const login = () => { - client.open({ - user: 'userId', - token: 'token' - }) - } - return -} - -// 自动登录 -// ... -ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - -) -``` - -## 聊天室事件 - -ChatroomUIKit 中提供了聊天室事件的监听接口。你可以通过注册聊天室监听器,获取聊天室事件,并作出相应处理。 - -ChatroomUIKit 中主动调用 API 的事件监听如下: - -```javascript -import { eventHandler } from "easemob-chat-uikit"; - -eventHandler.addEventHandler("chatroom", { - onError: (error) => { - // 所有 API 调用失败除了回调相应的事件外都会回调 onError 事件 - }, - joinChatRoom: { - error: (err) => {}, - success: () => {}, - }, - recallMessage: { - error: (err) => {}, - success: () => {}, - }, - reportMessage: { - // ... - }, - sendMessage: { - // ... - }, - getChatroomMuteList: { - // ... - }, - removeUserFromMuteList: { - // ... - }, - unmuteChatRoomMember: { - // ... - }, - removerChatroomMember: { - // ... - }, -}); -``` - -从 UIKit 中获取 Chat SDK 实例来监听收到的聊天室事件: - -```javascript -import React, { useEffect } from "react"; -import { useClient } from "easemob-chat-uikit"; - -const ChatroomApp = () => { - const client = useClient(); - - useEffect(() => { - client.addEventHandler("chatroom", { - onChatroomEvent: (event: ChatSDK.EventData) => { - if (event.operation === "muteMember") { - // console.log('你已被禁言') - } - // 全部事件请参考 https://doc.easemob.com/document/web/room_manage.html#监听聊天室事件 - }, - }); - }, []); -}; -``` - -## 参考 - -若要了解以上最佳实践的详情,请访问 [GitHub 仓库](https://github.com/easemob/ChatroomDemo/tree/dev/WEB/ChatroomDemo)。 diff --git a/docs/uikit/chatroomuikit/web/roomuikit_config_item.md b/docs/uikit/chatroomuikit/web/roomuikit_config_item.md deleted file mode 100644 index 43761e2d..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_config_item.md +++ /dev/null @@ -1,71 +0,0 @@ -# 可配置项 - - - -ChatroomUIKit 提供 `Chatroom` 和 `ChatroomMember` 组件,组件中包含各种属性,你可以根据需求进行设置。 - -## Chatroom 组件 - -![img](/images/uikit/chatroomweb/chatroom.png) - -`Chatroom` 是整个聊天界面组件,由 `Header`、`MessageList`、`MessageInput` 和 `Broadcast` 子组件组成。每个组件可以用 `renderX` 方法替换成自定义的组件。 - -| 属性 | 是否必需 | 类型 | 描述 | -| ---------- | -------- | ----------------- | ------------ | -| className | 否 | String | 组件的类名。 | -| prefix | 否 | String | CSS 类名的前缀。 | -| style | 否 | React.CSSProperties | 组件的样式。 | -| chatroomId | 是 | String | 聊天室 ID。 | -| renderEmpty | 否 | () => ReactNode | 自定义渲染没有会话时的内容。 | -| renderHeader | 否 | (roomInfo: ChatroomInfo) => ReactNode | 自定义渲染 Header。 | -| headerProps | 否 | HeaderProps | Header 组件的属性。 | -| renderMessageList | 否 | () => ReactNode | 自定义渲染聊天室消息区域。 | -| renderMessageInput | 否 | () => ReactNode | 自定义渲染消息输入区域。 | -| messageInputProps | 否 | MessageEditorProps | 消息输入区域组件的属性。 | -| messageListProps | 否 | MsgListProps | 聊天室消息区域组件的属性。 | -| renderBroadcast | 否 | () => ReactNode | 自定义渲染全局广播组件。 | -| broadcastProps | 否 | BroadcastProps | 全局广播组件的属性。 | - -例如,可以通过组件的属性传递 `className`、`style` 和 `prefix` 修改样式: - -```javascript -import { Chatroom, Button } from "easemob-chat-uikit"; - -const ChatApp = () => { - return ( -
- - -
- ); -}; -``` - -## ChatroomMember 组件 - -![img](/images/uikit/chatroomweb/chatroomMember.png) - -`ChatroomMember` 用于展示聊天室所有者和聊天室成员,以及禁言列表。聊天室所有者可以对成员禁言或踢出聊天室。 - -| 属性 | 是否必需 | 类型 | 描述 | -| --------------- | -------- | -------------------------------------- | -------------------- | -| className | 否 | String | 组件的类名。 | -| prefix | 否 | String | CSS 类名的前缀。 | -| style | 否 | React.CSSProperties | 组件的样式。 | -| chatroomId | 否 | String | 聊天室 ID。 | -| renderHeader | 否 | (roomInfo: ChatroomInfo) => ReactNode | 自定义渲染 Header。 | -| headerProps | 否 | HeaderProps | Header 组件的属性。 | -| memberListProps | 否 | { search?: boolean; placeholder?: string; renderEmpty?: () => ReactNode; renderItem?: (item: AppUserInfo) => ReactNode; UserItemProps?: UserItemProps; } | 成员列表组件的属性。 | -| muteListProps | 否 | { search?: boolean; placeholder?: string; renderEmpty?: () => ReactNode; renderItem?: (item: AppUserInfo) => ReactNode; UserItemProps?: UserItemProps; } | 禁言列表组件的属性。 | - -```javascript -import { ChatroomMember } from "easemob-chat-uikit"; - -const ChatApp = () => { - return ( -
- -
- ); -}; -``` diff --git a/docs/uikit/chatroomuikit/web/roomuikit_customize.md b/docs/uikit/chatroomuikit/web/roomuikit_customize.md deleted file mode 100644 index 4258d468..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_customize.md +++ /dev/null @@ -1,128 +0,0 @@ -# 自定义 - - - -本文通过几个示例介绍如何添加自己的业务逻辑,实现个性化业务需求。 - -## 自定义渲染 header - -你可以通过容器组件的 `renderHeader` 方法渲染自定义 header: - -```javascript -import {Chatroom, Header} from 'easemob-chat-uikit' - -const ChatApp = () => { - const CustomHeader =
- return( -
- CustomHeader}> -
- ) -} -``` - -## 自定义渲染消息 - -你可以通过容器组件的 `renderMessageList` 方法渲染自定义聊天室消息区域: - -```tsx -import { Chatroom, MessageList } from "easemob-chat-uikit"; - -const ChatApp = () => { - const renderMessage = (message) => { - switch (message.type) { - case "txt": - return
{message.msg}
; - } - }; - return ( -
- ( - - )} - > -
- ); -}; -``` - -## 自定义礼物 - -你可以通过容器组件的 `messageEditorProps` 属性自定义 `giftConfig`: - -```tsx -import { Chatroom, MessageList } from "easemob-chat-uikit"; - -const ChatApp = () => { - const renderMessage = (message) => { - switch (message.type) { - case "txt": - return
{message.msg}
; - } - }; - return ( -
- -
- ); -}; -``` - -## Context - -UIKit 使用 React Context 管理全局数据,用户可以使用自定义 hook `useChatroomContext` 获取和管理聊天室相关数据。 - -### 使用示例 - -```javascript -import React from "react"; -import { useChatroomContext, Button } from "easemob-chat-uikit"; - -const ChatAPP = () => { - const { - chatroom, - muteChatRoomMember, - unmuteChatRoomMember, - removerChatroomMember, - } = useChatroomContext(); - - const muteMember = () => { - muteChatRoomMember("chatroomId", "userId"); - }; - return ; -}; -``` - -### useChatroomContext 总览 - -| 属性/方法 | 类型 | 描述 | -| :-------------------- | :-------------- | :-------------------- | -| `chatroom` | `ChatroomInfo` | 聊天室信息。 | -| `muteChatRoomMember` | `(chatroomId: string, userId: string, muteDuration?: number) => Promise` | 对成员禁言。 | -| `unmuteChatRoomMember` | `(chatroomId: string, userId: string) => Promise` | 对成员解除禁言。 | -| `removerChatroomMember` | `(chatroomId: string, userId: string) => void` | 移除成员。 | diff --git a/docs/uikit/chatroomuikit/web/roomuikit_integrated.md b/docs/uikit/chatroomuikit/web/roomuikit_integrated.md deleted file mode 100644 index 51ad699a..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_integrated.md +++ /dev/null @@ -1,55 +0,0 @@ -# 集成 ChatroomUIKit - - - -使用 ChatroomUIKit 之前,你需要将 ChatroomUIKit 集成到你的应用中。 - -## 前提条件 - -- React 16.8.0 或以上版本; -- React DOM 16.8.0 或以上版本; -- 有效的 Easemob IM 开发者账号,并[获取 App Key](/product/enable_and_configure_IM.html#获取环信即时通讯-im-的信息)。 - -## 创建项目 - -```bash -# 安装 CLI 工具。 -npm install create-react-app -# 构建一个 my-app 的项目。 -npx create-react-app my-app -cd my-app -``` - -``` -项目目录: -├── package.json -├── public # Webpack 的静态目录。 -│ ├── favicon.ico -│ ├── index.html # 默认的单页面应用。 -│ └── manifest.json -├── src -│ ├── App.css # App 根组件的 CSS。 -│ ├── App.js # App 组件代码。 -│ ├── App.test.js -│ ├── index.css # 启动文件样式。 -│ ├── index.js # 启动文件。 -│ ├── logo.svg -│ └── serviceWorker.js -└── yarn.lock -``` - -## 安装 easemob-chat-uikit - -- 通过 npm 安装,运行以下命令: - -```bash -npm install easemob-chat-uikit --save -``` - -- 通过 yarn 安装,运行以下命令: - -```bash -yarn add easemob-chat-uikit -``` - - diff --git a/docs/uikit/chatroomuikit/web/roomuikit_overview.md b/docs/uikit/chatroomuikit/web/roomuikit_overview.md deleted file mode 100644 index bb959037..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_overview.md +++ /dev/null @@ -1,34 +0,0 @@ -# 概述 - - - -环信 ChatroomUIKit 提供 UIKit 的各种组件帮助开发者根据实际业务需求快速搭建聊天室应用。通过该 UIKit,聊天室中的用户可实时交互,发送普通弹幕消息、打赏消息和全局广播等功能。 - -- 若要访问源码,请点击[这里](https://github.com/easemob/Easemob-UIKit-web)。 - -- 要体验环信聊天室 UIKit demo,请点击[这里](https://webim-live.easemob.com/login)。 - -## 功能 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - 创建聊天室:ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - 解散聊天室:ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - 离开聊天室:聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - 发送弹幕:用户在聊天室中向其他参与者发送文字和表情的消息。 - - 打赏:用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - 全局广播:向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - 未读消息数:在一个聊天室中用户尚未读取的消息数量。 - - 已禁言列表:记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - 暗黑模式:ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展** - - 消息举报:在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - 消息翻译:将聊天室中的单条消息从一种语言转换成另一种语言。 - - 消息撤回:在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - 禁言成员:聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - 查看成员列表:聊天室成员列表显示了该聊天室中的当前在线用户。 - - 搜索成员:在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - 禁言成员:聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - 移除成员:聊天室所有者将指定成员从聊天室中踢出。 diff --git a/docs/uikit/chatroomuikit/web/roomuikit_quickstart.md b/docs/uikit/chatroomuikit/web/roomuikit_quickstart.md deleted file mode 100644 index 0a8955e1..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_quickstart.md +++ /dev/null @@ -1,166 +0,0 @@ -# 快速开始 - - - -利用 ChatroomUIKit,你可以轻松实现聊天室内的用户交互。本文介绍如何实现在聊天室中发送第一条消息。 - -## 前提条件 - -- React 16.8.0 或以上版本; -- React DOM 16.8.0 或以上版本; -- 有效的 Easemob IM 开发者账号,并获取 App Key。 - -## 支持的浏览器 - -| 浏览器 | 支持的版本 | -| ----------------- | ---------- | -| Internet Explorer | 11 或以上 | -| Edge | 43 或以上 | -| Firefox | 10 或以上 | -| Chrome | 54 或以上 | -| Safari | 11 或以上 | - -## 操作流程 - -### 第一步 创建项目 - -```bash -# 安装 CLI 工具。 -npm install create-react-app -# 构建一个 my-app 的项目。 -npx create-react-app my-app -cd my-app -``` - -``` -项目目录: -├── package.json -├── public # Webpack 的静态目录。 -│ ├── favicon.ico -│ ├── index.html # 默认的单页面应用。 -│ └── manifest.json -├── src -│ ├── App.css # App 根组件的 CSS。 -│ ├── App.js # App 组件代码。 -│ ├── App.test.js -│ ├── index.css # 启动文件样式。 -│ ├── index.js # 启动文件。 -│ ├── logo.svg -│ └── serviceWorker.js -└── yarn.lock -``` - -### 第二步 安装 easemob-chat-uikit - -- 通过 npm 安装,运行以下命令: - -```bash -npm install easemob-chat-uikit --save -``` - -- 通过 yarn 安装,运行以下命令: - -```bash -yarn add easemob-chat-uikit -``` - -### 第三步 使用 easemob-chat-uikit 组件构建应用 - -将 easemob-chat-uikit 库导入到你的代码中: - -```javascript -// App.js -import React, { Component, useEffect } from "react"; -import { - Provider, - Chatroom, - useClient, - rootStore, - ChatroomMember, -} from "easemob-chat-uikit"; -import "easemob-chat-uikit/style.css"; - -const ChatroomApp = observer(() => { - const client = useClient(); - const chatroomId = ""; // 要加入的聊天室 - const appKey = ""; // 你的 App Key - - useEffect(() => { - if (client.addEventHandler) { - client.addEventHandler("chatroom", { - onConnected: () => { - console.log("登录成功"); - }, - }); - } - }, [client]); - - const [userId, setUserId] = useState(""); - const [password, setPassword] = useState(""); - const login = () => { - client - .open({ - user: userId, - pwd: password, - //accessToken: '', - }) - .then((res) => { - console.log("获取token成功"); - }); - }; - return ( - <> - -
-
- - { - setUserId(e.target.value); - }} - > -
-
- - { - setPassword(e.target.value); - }} - > -
-
- -
-
- -
- -
-
- -
-
- - ); -}); -export default ChatroomApp; -``` - -### 第四步 运行项目 - -```bash -npm run start -``` - -### 第五步 发送第一条消息 - -输入消息内容,点击 **发送** 按钮,发送消息。 - -![img](/images/uikit/chatroomweb/chatroom.png) \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/web/roomuikit_releasenote.md b/docs/uikit/chatroomuikit/web/roomuikit_releasenote.md deleted file mode 100644 index 95d69f4b..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_releasenote.md +++ /dev/null @@ -1,31 +0,0 @@ -# 聊天室 UIKit 更新日志 - - - -## 版本 V1.0.0 2023-12-29 - -### 新增特性 - -ChatroomUIKit 提供以下功能: - -- **通用特性** - - [创建聊天室](roomfeature_common.html#创建聊天室):ChatroomUIKit 不提供创建聊天室的功能,你可以[调用即时通讯 IM SDK 的接口创建聊天室](/document/server-side/chatroom.html#创建聊天室)。 - - [解散聊天室](roomfeature_common.html#解散聊天室):ChatroomUIKit 不提供解散聊天室的功能,你可以[调用即时通讯 IM SDK 的接口解散聊天室](/document/server-side/chatroom.html#解散聊天室)。 - - [离开聊天室](roomfeature_common.html#离开聊天室):聊天室中的成员可自行离开聊天室,聊天室所有者也可以将成员移出聊天室。 - - [发送弹幕消息](roomfeature_common.html#发送弹幕):用户在聊天室中向其他参与者发送文字和表情的消息。 - - [打赏](roomfeature_common.html#打赏):用户通过赠送虚拟礼物,向聊天室中的主播或其他用户表达赞赏或者支持 - - [全局广播](roomfeature_common.html#全局广播):向 App 内所有在线聊天室中的所有用户发送相同的消息或通知。 - - [未读消息数](roomfeature_common.html#未读消息数):在一个聊天室中用户尚未读取的消息数量。 - - [已禁言列表](roomfeature_common.html#已禁言列表):记录被禁止发言用户的列表。当用户违反了聊天室的规则时,聊天室所有者将其禁言,即添加至已禁言列表。 - - [暗黑模式](roomfeature_common.html#暗黑模式):ChatroomUIKit 默认风格为明亮模式,切换为暗黑模式后,聊天室界面中所有元素将替换为暗黑风格设计,提供用户舒适的视觉体验。 -- **消息扩展**(长按一条消息可进行的操作) - - [消息举报](roomfeature_message.html#消息举报):在聊天室中,用户可以举报不适当、违规或有害的消息内容以促使聊天室所有者采取适当的行动。 - - [消息翻译](roomfeature_message.html#消息翻译):将聊天室中的单条消息从一种语言转换成另一种语言。 - - [消息撤回](roomfeature_message.html#消息撤回):在聊天室中撤销已经发送的消息。所有用户只能撤回自己发送的消息,即使聊天室所有者也不能撤回其他成员发送的消息。 - - [禁言成员](roomfeature_message.html#禁言成员):聊天室所有者对聊天室中的成员禁止发言。 -- **成员管理** - - [查看成员列表](roomfeature_member.html#查看成员列表):聊天室成员列表显示了该聊天室中的当前在线用户。 - - [搜索成员](roomfeature_member.html#搜索成员):在聊天室中查找指定成员的功能,支持支持本地搜索和模糊匹配。 - - [禁言成员](roomfeature_member.html#禁言成员):聊天室所有者可以在聊天室中对某个特定的成员禁言。 - - [移除成员](roomfeature_member.html#移除成员):聊天室所有者将指定成员从聊天室中踢出。 - diff --git a/docs/uikit/chatroomuikit/web/roomuikit_run.md b/docs/uikit/chatroomuikit/web/roomuikit_run.md deleted file mode 100644 index 1bd20269..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_run.md +++ /dev/null @@ -1,31 +0,0 @@ -# 跑通示例项目 - - - -环信提供一个[开源的 ChatroomUIKit 示例项目](https://github.com/easemob/ChatroomDemo/tree/dev/WEB/ChatroomDemo),演示了如何使用该 UIKit 快速搭建聊天室页面,实现完整业务。 - -本文展示如何运行 Web 平台的聊天室 UIKit 示例项目。 - -## 下载项目 - -```sh -git clone git@github.com:easemob/ChatroomDemo.git -``` - -## 安装依赖 - -```sh -cd WEB/ChatroomDemo - -npm install -``` - -## 运行项目 - -```sh -npm start -``` - -浏览器会显示以下页面: - -![img](/images/uikit/chatroomweb/chatroom_enter.png) diff --git a/docs/uikit/chatroomuikit/web/roomuikit_storybook.md b/docs/uikit/chatroomuikit/web/roomuikit_storybook.md deleted file mode 100644 index 1f7ccdd6..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_storybook.md +++ /dev/null @@ -1,5 +0,0 @@ -# 组件文档 - -ChatroomUIKit 提供 container 组件 `Chatroom` 和 `ChatroomMember`,module 组件 `ChatroomMessage`。组件中包含各种属性供你配置。 - -若要查看组件配置详情,请点击[这里](https://storybook.easemob.com/)。 \ No newline at end of file diff --git a/docs/uikit/chatroomuikit/web/roomuikit_theme.md b/docs/uikit/chatroomuikit/web/roomuikit_theme.md deleted file mode 100644 index 12709bde..00000000 --- a/docs/uikit/chatroomuikit/web/roomuikit_theme.md +++ /dev/null @@ -1,42 +0,0 @@ -# 主题 - - - -ChatroomUIkit 内置浅色和深色主题,默认为浅色主题。 - -- 浅色主题 - -![img](/images/uikit/chatroomweb/light_mode.png) - -- 深色主题 - -![img](/images/uikit/chatroomweb/dark_mode.png) - -## 修改主题 - -你可以设置 `Provider` 组件的主题属性修改主题: - -```javascript -import { Chatroom, UIKitProvider } from 'easemob-chat-uikit'; - -const ChatApp = () => { - return ( - - - - ); -}; -``` - -## 设计指南 - -如果你对主题颜色,设计指南和细节有任何疑问,您可以在 Figma 设计稿中添加评论并提及我们的设计师 Stevie Jiang。 - -- [UI 设计资源](https://www.figma.com/community/file/1322495388317476706/chatroom-uikit)。 - -- [UI 设计指南](design_guide.html)。 From c7a0df9b42a14db5dd6a60092f1dccfeab4b465b Mon Sep 17 00:00:00 2001 From: haoxiuwen Date: Sat, 28 Dec 2024 17:58:33 +0800 Subject: [PATCH 2/2] modify --- docs/document/harmonyos/privatecloud.md | 34 -- docs/document/ios/demo.md | 69 ---- docs/document/ios/easecallkit.md | 400 ------------------------ docs/document/ios/elite_sdk.md | 385 ----------------------- docs/document/ios/overview.md | 253 --------------- docs/document/ios/privatecloud.md | 34 -- docs/document/react-native/overview.md | 256 --------------- docs/document/unity/overview.md | 299 ------------------ docs/document/web/demo_react.md | 44 --- docs/document/web/demo_vue.md | 49 --- docs/document/web/easecallkit.md | 223 ------------- docs/document/web/overview.md | 287 ----------------- docs/document/web/privatecloud.md | 67 ---- docs/document/windows/overview.md | 266 ---------------- 14 files changed, 2666 deletions(-) delete mode 100644 docs/document/harmonyos/privatecloud.md delete mode 100644 docs/document/ios/demo.md delete mode 100644 docs/document/ios/easecallkit.md delete mode 100644 docs/document/ios/elite_sdk.md delete mode 100644 docs/document/ios/overview.md delete mode 100644 docs/document/ios/privatecloud.md delete mode 100644 docs/document/react-native/overview.md delete mode 100644 docs/document/unity/overview.md delete mode 100644 docs/document/web/demo_react.md delete mode 100644 docs/document/web/demo_vue.md delete mode 100644 docs/document/web/easecallkit.md delete mode 100644 docs/document/web/overview.md delete mode 100644 docs/document/web/privatecloud.md delete mode 100644 docs/document/windows/overview.md diff --git a/docs/document/harmonyos/privatecloud.md b/docs/document/harmonyos/privatecloud.md deleted file mode 100644 index 82cd261b..00000000 --- a/docs/document/harmonyos/privatecloud.md +++ /dev/null @@ -1,34 +0,0 @@ -# 私有云 SDK 集成配置 - - - -## 静态配置 IP(域名)地址 - -SDK 默认指向公有云地址,在部署私有云后,需要将地址重新指向到新的地址,以下是地址修改方法: - -```typescript -let options = new ChatOptions();//实例化 EMOptions 对象 -options.setRestServer("10.10.10.10:00");//设置私有云 REST 地址(ip/域名:port) -options.setIMServer("10.10.10.10");//设置私有云 IM 地址 -options.setImPort(100);//设置私有云 IM 端口号 - -ChatClient.getInstance().init(options);//最后初始化 SDK -``` -:::tip -如果需要配置 HTTPS 只需在 REST 地址前加一个前缀。 -::: - -```typescript -options.setRestServer("https://10.10.10.10:00");//设置私有云 REST 地址(ip:port) -``` - -## 动态配置地址 - -1. 服务器端配置 DNS 地址表 -2. 从服务器端动态获取地址 - -```typescript -let options = new ChatOptions(); -options.setDnsURL("url");//从服务器端动态获取地址 -ChatClient.getInstance().init(options);//初始化 SDK -``` \ No newline at end of file diff --git a/docs/document/ios/demo.md b/docs/document/ios/demo.md deleted file mode 100644 index 8d2494ec..00000000 --- a/docs/document/ios/demo.md +++ /dev/null @@ -1,69 +0,0 @@ -# Demo(EaseIM App)介绍 - - - -环信即时通讯 IM iOS 端提供示例应用可供体验。 - -1. [下载 Demo](https://www.easemob.com/download/demo)。 - -2. 输入你的手机号,获取验证码,然后输入。 - -3. 选择同意《环信服务条款》与《环信隐私协议》,然后点击 **登录** 登录 Demo。 - -![img](/images/demo/ios_login.png =350x750) - -## 代码下载 - -您可以通过以下两种方式获取到源代码: - -- 下载代码压缩包:[IM SDK 及 Demo 下载](https://www.easemob.com/download/im) -- 下载源代码:[github 源码地址](https://github.com/easemob/easemob-demo-ios) - - 4.5.0 及之前版本的 Demo 为 Objective-C 语言。点击[这里](https://github.com/easemob/easemob-demo-ios/tree/OCDemo)查看 Demo 源码地址。环信已不再维护该地址的 Demo 源码。 - - 4.6.0 及之后版本的 Demo 为 Swift 语言。点击[这里](https://github.com/easemob/easemob-demo-ios)查看 Demo 源码地址。 - -## 运行 EaseChatDemo 工程 - -从 [IM SDK 及 Demo 下载](https://www.easemob.com/download/im) 下载 iOS SDK 压缩包,然后解压。解压后在 `EaseChatDemo` 文件夹下,即为 `EaseChatDemo` 的工程目录。 - -终端 cd 到 EaseChatDemo 的 `podfile` 目录下,终端执行 `pod install` 命令,等待下载完所有的 pod 依赖库,即可打开 `EaseChatDemo.xcworkspace`,运行 EaseIM demo 进行自定义再次开发。 - -## 使用到的 pod 库 - -- 环信IM SDK pod 'HyphenateChat' -- 环信 IM UI 库 pod 'EaseChatUIKit' -- 环信音视频 UI 库 pod 'EaseCallKit' -- 声网音视频 SDK pod 'AgoraRtcEngine_iOS' - -三方库包含: - -``` -- Swift JSON 解析库 pod 'KakaJSON' -- 封装FFDB的便捷化数据库 pod 'SwiftFFDBHotFix' -``` - -## 主要模块介绍 - -Demo 中有几大 UI 功能模块,在集成时将对应的模块添加到工程中即可。 - -- Utils——工具类。 -- Main——主界面模块 包含 Provider 实现 以及 1v1 实时通话以及多人实时通话的功能。 -- LoginViewController——登录模块 EaseChatUIKit 在 Demo 中的登录应用。 -- AppDelegate&SceneDelegate——EaseChatUIKit 在 Demo 中初始化以及配置项、继承注册等应用。 -- CustomConstants——自定义常量模块,主要包含需要用户填入的 AppKey 以及 ServerHost。 -- IntegratedFromEaseChatUIKit——继承 EaseChatUIKit 中的类并进行二次自定义开发相关的类模块。 -- Me——个人信息以及 EaseChatUIKit 相关配置项及其如何生效示例。 - -## 主要类介绍 - -- **MainViewController**:此页面中包含了包含 Provider 实现 以及 1v1 实时通话以及多人实时通话的功能的初始化与回调处理。 -- **MineMessageListViewController&MineContactDetailViewController&MineGroupDetailViewController**:中 `EaseCallManager.shared()` 是如何发起音视频通话的示例代码。 -- **DemoLanguage**:Demo 层语言偏好设置切换。 -- **MineMessageListViewController**:Demo 中聊天页面。 -- **EasemobBusinessRequest**:实现了 RESTful 的几种基本业务请求工具类,可以根据请求时需要返回参数类型来返回对应模型无需用户解析但是依赖第三方解析库 `Kakajson`,也有只返回 Dictionary 的请求方法,便于用户使用。 -- **Appdelegate&NotificationService**:推送相关设置。 - -## 部分 UI 展示 - -![img](/images/demo/ios_contact.png) - -![img](/images/demo/ios_chat.png) diff --git a/docs/document/ios/easecallkit.md b/docs/document/ios/easecallkit.md deleted file mode 100644 index 91043c6a..00000000 --- a/docs/document/ios/easecallkit.md +++ /dev/null @@ -1,400 +0,0 @@ -# iOS 端 EaseCallKit 使用指南 - - - -## 功能概述 - -`EaseCallKit` 是一套基于声网音视频服务,使用环信 IM 作为信令通道的开源音视频 UI 库。UI 库提供了单人语音通话、视频通话,以及多人会议的功能接口。 - -使用 `EaseCallKit` 库可以快速实现常用的音视频场景,通过信令的交互确认,保证 **用户多端登录时,收到呼叫同时振铃,一端处理后,其他端自动停止**。 - -`EaseCallKit` 库在 Github 上进行了保存,请参见 [EaseCallKit iOS 端使用指南](https://github.com/easemob/easecallkitui-ios)。 - -**`EaseCallKit` 在通话过程中,使用环信 ID 加入频道,方便音视频视图中显示用户名。如果用户不使用 `EaseCallKit` 而直接调用声网 API,也可以直接使用数字 UID 加入频道。** - -:::tip -本 UI 库只和移动端 3.8.0 以上版本 Demo 互通。3.8.1 的 UI 库使用声网数字 UID 加入频道,而 3.8.0 使用字符串加入频道,3.8.1 版本不与 3.8.0 互通,Demo 中 EaseCallKit 使用的 token 和 UID 均由你自己生成。若你需要使用声网对应的音视频服务,需单独在声网申请。 -::: - -## 跑通 Demo - -`EaseCallKit` 集成在环信提供的开源 IM Demo 中,你可以通过进入 [环信 IM Demo 下载页面](https://www.easemob.com/download/im),选择 iOS 端 Demo 下载,或直接进入 [Github 开源网站](https://github.com/easemob/chat-ios) 下载。 - -- 安装 SDK 与 `EaseCallKit` - -Demo 源码中不涉及 SDK 和 `EaseCallKit`,你可以通过直接导入或通过 CocoaPods 安装。 - -如果当前系统上没有安装 CocoaPods,需参考 [CocoaPods 安装说明](https://guides.cocoapods.org/using/getting-started.html)进行安装。 - -使用 CocoaPods 安装需要进入 `podfile` 所在目录,然后在终端执行如下命令: - -``` -pod install -``` - -- 运行 demo - -安装完成 SDK 与 `EaseCallKit` 后,在 Xcode 打开工作空间 `EaseIM.xcworkspace`,连接手机,然后就可以运行了。 - -## 准备条件 - -在集成该库前,你需要满足以下条件: - -- 分别创建 [环信应用](/product/enable_and_configure_IM.html) 及 [声网应用](https://doc.shengwang.cn/doc/rtc/ios/get-started/enable-service#创建声网项目); -- 已完成环信 IM 的基本功能,包括登录、好友、群组以及会话等的集成; -- 上线之前开通声网 token 验证时,用户需要实现自己的 [App Server](https://github.com/easemob/easemob-im-app-server/tree/master/agora-app-server),用于生成 token。利用 App Server 生成 token 的过程参见 [声网 token](https://doc.shengwang.cn/doc/rtc/ios/basic-features/token-authentication)。 - -## 快速集成 - -使用 `EaseCallKit` 库完成音视频通话的基本流程如下: - -1. 用户调用 `EaseCallKit` 库初始化接口; -2. 主叫方调用发起通话邀请接口,自动进入通话页面; -3. 被叫方自动弹出通话请求页面,在 UI 界面选择接听,进入通话; -4. 结束通话时,点击 UI 界面挂断按钮。 - -### 导入 EaseCallKit 库 - -`EaseCallKit` UI 库依赖于 `HyphenateChat`、`AgoraRtcEngine_iOS`、`Masonry` 和 `SDWebImage` 库,导入该 UI 库时需要同步导入工程,依赖库可通过 CocoaPods 导入。 - -**`EaseCallKit` 是动态库,在 `podfile` 中必须加入 `use_frameworks!`**。 - -`EaseCallKit` 库可通过手动导入,也可利用 CocoaPods 导入。 - -#### 使用 CocoaPods 导入 EaseCallKit - -- 在 Terminal 里进入项目根目录,并运行 `pod init` 命令。项目文件夹下会生成一个 `Podfile` 文本文件。 -- 打开 `Podfile` 文件,修改文件为如下内容。注意将 `AppName` 替换为你的 app 名称。 - -``` -use_frameworks! -target 'AppName' do - pod 'HyphenateChat' - pod 'Masonry' - pod 'AgoraRtcEngine_iOS' - pod 'SDWebImage' - pod 'EaseCallKit', '~> version' -end -``` - -使用 easecallkit 4.0.0 时,请使用声网音视频库 `AgoraRtcEngine_iOS/RtcBasic` 的 4.1.1 版本。 - -- 在 Terminal 内运行 `pod update` 命令更新本地库版本。 -- 运行 `pod install` 命令安装 `EaseCallKit` UI 库。成功安装后,Terminal 中会显示 **Pod installation complete!**,此时项目文件夹下会生成一个 `xcworkspace` 文件。 -- 打开新生成的 `xcworkspace` 文件,连接手机,运行 demo。 - -#### 手动导入 EaseCallKit - -- 将在跑通 Demo 阶段下载的 `EaseCallKit.framework` 复制到项目工程目录下; -- 打开 Xcode,选择 **工程设置** > **General** 菜单,将 `EaseCallKit.framework` 拖拽到工程下,在 `Frameworks`、`libraries` 和 `Embedded Content` 中设置 `EaseCallKit.framework` 为 `Embed & Sign`。 - -### 添加权限 - -应用需要音频设备及摄像头权限。在 `info.plist` 文件中,点击 `+` 图标,添加如下信息: - -| Key | Type | Value | -| :------------------------------------- | :----- | :-------------------------------------- | -| Privacy - Microphone Usage Description | String | 描述信息,如“环信需要使用您的麦克风”。 | -| Privacy - Camera Usage Description | String | 描述信息,如“环信需要使用您的摄像头” 。 | - -如果希望在后台运行,还需要添加后台运行音视频权限,在 `info.plist` 文件中,点击 `+` 图标,添加 `Required background modes`,`Type` 为 `Array`,在 `Array` 下添加元素 `App plays audio or streams audio/video using AirPlay`。 - -### 初始化 - -在环信 IM SDK 初始化完成后,同时初始化 `EaseCallKit`,初始化的同时开启回调监听,设置常用配置项。代码如下: - -```objectivec -EaseCallConfig* config = [[EaseCallConfig alloc] init]; -EaseCallUser* usr = [[EaseCallUser alloc] init]; -usr.nickName = @"自定义昵称"; -usr.headImage = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"headImage" ofType:@"png"]]; -config.users = @{@"环信 ID":usr}; -config.agoraAppId=@"声网 AppID"; -[[EaseCallManager sharedManager] initWithConfig:config delegate:self]; -``` - -可设置的配置项包括以下内容: - -```objectivec -@interface EaseCallConfig : NSObject -// 默认头像。 -@property (nonatomic) NSURL* defaultHeadImage; -// 呼叫超时时间,单位为秒。 -@property (nonatomic) UInt32 callTimeOut; -// 用户信息字典,key 为环信 ID,value 为 `EaseCallUser`。 -@property (nonatomic) NSMutableDictionary* users; -// 振铃文件。 -@property (nonatomic) NSURL* ringFileUrl; -// 声网 appId。 -@property (nonatomic) NSString* agoraAppId; -// 声网 token 验证开关,默认不开启。 -@property (nonatomic) BOOL enableRTCTokenValidate -@end -``` - -### 发起通话邀请 - -`EaseCallKit` 初始化完成后,可以开始发起音视频通话。 - -#### 一对一音视频通话 - -一对一通话分为语音通话与视频通话,发起过程如下: - -```objectivec -// 发起一对一通话。 -// remoteUser 邀请对象的环信 ID。 -// type 通话类型。`EaseCallType1v1Audio` 表示语音通话,`EaseCallType1v1Video` 表示视频通话。 -// ext 通话扩展信息,为用户信息字典。 -[[EaseCallManager sharedManager] startSingleCallWithUId:remoteUser type:aType ext:nil completion:^(NSString * callId, EaseCallError * aError) { - -}]; -``` - -#### 多人音视频通话 - -你可以从群组成员列表或者好友列表中选择用户,发起多人音视频通话。具体实现可参考 Demo 中的 `ConfInviteUsersViewController`。 - -```objectivec -//邀请用户加入多人通话。 -// aInviteUsers 受邀用户的环信 ID 数组。 -// ext 可设置扩展信息,如果从群组发起,可通过 `ext` 设置群组 ID,其他用户也可邀请该群组成员。 -[[EaseCallManager sharedManager] startInviteUsers:aInviteUsers ext:@{@"groupId":aConversationId} completion:^(NSString * callId, EaseCallError * aError) { - -}]; -``` - -发起通话后的 UI 界面如下: - - - -### 收到邀请 - -主叫方调用邀请接口后,如果被叫方在线且并未处于通话过程中,将弹出通话页面,被叫用户可选择接听或者拒绝。通话页面如下: - - - -被叫振铃的同时,会触发以下回调: - -```objectivec -- (void)callDidReceive:(EaseCallType)aType inviter:(NSString*_Nonnull)user ext:(NSDictionary*)aExt - { - - } -``` - -### 多人通话中间发起邀请 - -多人通话中,当前用户可以点击通话界面右上角的邀请按钮再次向其他用户发起邀请。这种情况下,会触发 `EaseCallKitListener` 中的 `multiCallDidInvitingWithCurVC` 回调: - -```objectivec -// 多人音视频邀请按钮的回调。 -// vc 当前视图控制器。 -// users 通话中已存在的用户。 -// aExt 通话扩展信息。 -- (void)multiCallDidInvitingWithCurVC:(UIViewController*_Nonnull)vc excludeUsers:(NSArray *_Nullable)users ext:(NSDictionary *)aExt - { - //若只邀请群组中的用户加入通话,发起通话时在扩展信息里添加 `groupId`。 - NSString* groupId = nil; - if(aExt) { - groupId = [aExt objectForKey:@"groupId"]; - } - - ConfInviteUsersViewController * confVC = nil; - if([groupId length] == 0) { - confVC = [[ConfInviteUsersViewController alloc] initWithType:ConfInviteTypeUser isCreate:NO excludeUsers:users groupOrChatroomId:nil]; - }else{ - confVC = [[ConfInviteUsersViewController alloc] initWithType:ConfInviteTypeGroup isCreate:NO excludeUsers:users groupOrChatroomId:groupId]; - } - [confVC setDoneCompletion:^(NSArray *aInviteUsers) { - [[EaseCallManager sharedManager] startInviteUsers:aInviteUsers ext:aExt completion:nil]; - }]; - confVC.modalPresentationStyle = UIModalPresentationPopover; - [vc presentViewController:confVC animated:NO completion:nil]; - } - -``` - -通话邀请界面的实现,可以参考 Demo 中的 `ConfInviteUsersViewController` 实现。 - -### 当前用户成功加入频道回调 - -自 `EaseCallKit` 3.8.1 新增 `callDidJoinChannel` 方法,在用户加入通话后会收到回调: - -```objectivec -- (void)callDidJoinChannel:(NSString*_Nonnull)aChannelName uid:(NSUInteger)aUid - { - //此时,可以获取当前频道中已有用户的声网 ID 与环信 ID 的映射表,并将映射表设置到 `EaseCallKit`,同时也可以更新用户的头像和昵称。 - //[self _fetchUserMapsFromServer:aChannelName]; - [[EaseCallManager sharedManager] setUsers:users channelName:channelName]; - } - -``` - -### 对方成功加入频道回调 - -自 `EaseCallKit` 3.8.1 新增 `remoteUserDidJoinChannel` 方法,在对方用户加入通话后会收到回调。 - -```objectivec --(void)remoteUserDidJoinChannel:( NSString*_Nonnull)aChannelName uid:(NSInteger)aUid username:(NSString*_Nullable)aUserName -{ - // 此时,可以获取当前频道中已有用户的声网 RTC UID 与环信 ID 的映射表,并将映射表设置到 `EaseCallKit`,同时也可以更新用户的头像和昵称。 - //[self _fetchUserMapsFromServer:aChannelName]; - [[EaseCallManager sharedManager] setUsers:users channelName:channelName]; -} -``` - -### 通话结束 - -在一对一音视频通话中,若其中一方挂断,双方的通话会自动结束,而多人音视频通话中需要主动挂断才能结束通话。通话结束后,会触发 `callDidEnd` 回调: - -```objectivec -// 通话结束回调。 -// aChannelName 通话使用的声网频道名称,用户可以根据频道名称,到声网 Console 的水晶球查询通话质量。 -// aTm 通话时长,单位为秒。 -// aCallType 通话类型。 -- (void)callDidEnd:(NSString*)aChannelName reason:(EaseCallEndReason)aReason time:(int)aTm type:(EaseCallType)aCallType - { - NSString* msg = @""; - switch (aReason) { - case EaseCallEndReasonHandleOnOtherDevice: - msg = @"已在其他设备处理。"; - break; - case EaseCallEndReasonBusy: - msg = @"对方忙。"; - break; - case EaseCallEndReasonRefuse: - msg = @"对方拒绝接听。"; - break; - case EaseCallEndReasonCancel: - msg = @"您已取消通话。"; - break; - case EaseCallEndReasonRemoteCancel: - msg = @"对方取消通话。"; - break; - case EaseCallEndReasonRemoteNoResponse: - msg = @"对方无响应。"; - break; - case EaseCallEndReasonNoResponse: - msg = @"您未接听。"; - break; - case EaseCallEndReasonHangup: - msg = [NSString stringWithFormat:@"通话已结束,通话时长:%d秒",aTm]; - break; - default: - break; - } - if([msg length] > 0) - [self showHint:msg]; - } -``` - -## 进阶功能 - -### 通话异常回调 - -通话过程中如果有异常或者错误发生,会触发 `callDidOccurError` 回调: - -异常包括业务逻辑异常、音视频异常以及 Easemob IM 异常。 - -```objectivec -// 通话异常回调。 -// aError 为异常信息,包括了 Easemob IM 异常,RTC 异常,业务异常三种情况。 -- (void)callDidOccurError:(EaseCallError *)aError - { - - } -``` - -`EaseCallError` 异常包括 IM 异常,RTC 异常以及业务逻辑异常。 - -```objectivec -@interface EaseCallError : NSObject -// 异常类型,包括 Easemob IM 异常、RTC 异常和业务逻辑异常。 -@property (nonatomic) EaseCallErrorType aErrorType; -// 异常代号。 -@property (nonatomic) NSInteger errCode; -// 异常描述。 -@property (nonatomic) NSString* errDescription; -``` - -### 配置修改 - -`EaseCallKit` 库初始化之后,可调用该方法修改配置: - -```objectivec -// 以下为修改铃声过程。 -EaseCallConfig* config = [[EaseCallManager sharedManager] getEaseCallConfig]; -NSString* path = [[NSBundle mainBundle] pathForResource:@"huahai128" ofType:@"mp3"]; -config.ringFileUrl = [NSURL fileURLWithPath:path]; -``` - -### 头像昵称修改 - -自 `EaseCallKit` 3.8.1 开始,新增了修改头像昵称的接口,用户加入频道后可修改自己和通话中其他人的头像昵称,修改方法如下: - -```objectivec -EaseCallUser* user = [EaseCallUser userWithNickName:info.nickName image:[NSURL URLWithString:info.avatarUrl]]; -[[[EaseCallManager sharedManager] getEaseCallConfig] setUser:username info:user]; -``` - -## 参考 - -### 获取声网 token - -用户加入音视频通话时,如果需要进行声网 token 鉴权,需要先开启 token 验证开关,开启过程如下: - -```objectivec -EaseCallUser* callUser = [[EaseCallUser alloc] init]; -config.enableRTCTokenValidate = YES;// 开启 RTC Token 验证,默认不开启。 -[[EaseCallManager sharedManager] initWithConfig:config delegate:self]; -``` - -获取 token 的过程由用户自己完成,开启后在通话时,会收到 `callDidRequestRTCTokenForAppId`回调,用户需要在回调中,实现从用户自己的 App Server 中获取 token(App Server 的实现参见 [生成声网 Token](https://docportal.shengwang.cn/cn/video-call-4.x/token_server_ios_ng),然后调用 `setRTCToken:channelName:` 接口。 - -```objectivec -- (void)callDidRequestRTCTokenForAppId:(NSString * _Nonnull)aAppId - channelName:(NSString * _Nonnull)aChannelName - account:(NSString * _Nonnull)aUserAccount - { - [[EaseCallManager sharedManager] setRTCToken:@"自己的RTC Token"channelName:aChannelName]; - } - -// 自 EaseCallKit 3.8.1 版本开始,`callDidRequestRTCTokenForAppId` 方法中添加了 `uid` 参数,你可以使用数字 uid 加入声网频道。 -- (void)callDidRequestRTCTokenForAppId:(NSString *)aAppId channelName:(NSString *)aChannelName account:(NSString *)aUserAccount uid:(NSInteger)aAgoraUid - { - [[EaseCallManager sharedManager] setRTCToken:@"自己的RTC Token" channelName:aChannelName uid:自己的声网uid]; - } -``` - -### 离线推送 - -为保证被叫用户 App 在后台运行或离线时也能收到通话请求,用户需开启离线推送。关于如何开启离线推送,请参见 [iOS SDK 集成](/document/ios/push/push_apns.html)。开启离线推送后,用户在离线情况下收到呼叫请求时,其手机通知页面会弹出一条通知消息,用户点击该消息可唤醒 App 并进入振铃页面。 关于离线推送场景方案,请参见 [iOS 端设置推送](/document/ios/push/push_overview.html)。 - -## API 列表 - -从 API 的角度看,`EaseCallKit` 库的主要包括管理模块 `EaseCallManager` 和回调模块 `EaseCallDelegate`。 - -管理模块 `EaseCallManager` 的 API 列表如下: - -| 方法 | 说明 | -| :----------------------------------------- | :----------------------------------------------------------- | -| initWithConfig:delegate | 初始化方法 | -| startSingleCallWithUId:type:ext:completion | 发起一对一通话。 | -| startInviteUsers:type:ext:completion: | 邀请用户加入多人通话。 | -| getEaseCallConfig | 获取 `EaseCallKit` 相关配置。 | -| setRTCToken:channelName: | 设置声网 Token。该方法自 `EaseCallKit` 3.8.1 版本添加。 | -| setRTCToken:channelName:uid: | 设置声网 Token。该方法自 `EaseCallKit` 3.8.1 版本添加。 | -| setUsers:channelName: | 设置环信 ID 与声网 uid 的映射表。该方法自 `EaseCallKit` 3.8.1 版本添加。 | - -回调模块 `EaseCallDelegate` 的 API 列表如下: - -| 方法 | 说明 | -| :------------------------------------------------------ | :----------------------------------------------------------- | -| callDidEnd:reason:time:type: | 通话结束时触发该事件。 | -| multiCallDidInvitingWithCurVC:excludeUsers:ext: | 多人通话中点击邀请按钮触发该事件。 | -| callDidReceive:inviter:ext: | 振铃时触发该事件。 | -| callDidRequestRTCTokenForAppId:channelName:account: | 获取声网 token 回调。该方法自 `EaseCallKit` 3.8.1 版本添加。 | -| callDidRequestRTCTokenForAppId:channelName:account:uid: | 获取声网 token 回调。该方法自 `EaseCallKit` 3.8.1 版本添加。 | -| callDidOccurError: | 通话异常时触发该事件。 | -| remoteUserDidJoinChannel:uid: | 对方加入频道时触发。该方法自 `EaseCallKit` 3.8.1 版本添加。 | -| callDidJoinChannel:uid: | 当前用户加入频道时触发。该方法自 `EaseCallKit` 3.8.1 版本添加。 | \ No newline at end of file diff --git a/docs/document/ios/elite_sdk.md b/docs/document/ios/elite_sdk.md deleted file mode 100644 index 378e7b5e..00000000 --- a/docs/document/ios/elite_sdk.md +++ /dev/null @@ -1,385 +0,0 @@ -# 精简版 SDK - -精简版 SDK 4.2.0 支持 Android 和 iOS 平台,包含基础的单聊和聊天室功能,适用于 SDK 包体积尽量小、仅需基础收发消息功能、而无需离线推送通知等功能的情况。 - -精简版 SDK 对应用的体积增量不大,android 为 1.11 MB,iOS 为 1.09 MB。 - -要下载 iOS 端精简版 SDK,点击[这里](https://downloadsdk.easemob.com/downloads/SDK-mini/iOS_IMLite_SDK_4.2.0_1116.zip)。 - -:::tip -精简版 SDK 无本地存储,可以升级为标准版 SDK,但标准版不能降级为精简版。 -::: - -## 功能列表 - -精简版 SDK 的功能如下表所示: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
功能模块功能功能细分/描述 接口文档 精简版 SDK标准版 SDK
消息管理发送和接收消息发送和接收消息

发送和接收消息

接收消息
发送和接收附件类型的消息
发送和接收位置消息
发送和接收透传消息
发送自定义类型消息
发送和接收合并消息
发送和接收定向消息
使用消息扩展字段
管理本地消息管理本地消息

获取本地历史消息

-

搜索消息

-

导入和插入消息

-

更新消息

-

删除消息

管理服务端消息管理服务端消息

从服务器分页获取指定会话的历史消息

-

单向删除服务端的历史消息

管理消息回执消息送达回执

消息送达回执

消息已读回执

消息已读回执

撤回消息

撤回消息

-

设置消息撤回监听

 
修改消息单聊会话中已经发送成功的文本消息进行修改

修改消息

获取消息流量统计获取消息流量统计获取消息流量统计  
翻译消息翻译

消息翻译

会话管理会话列表获取本地会话 获取本地会话
从服务器分页获取会话列表

从服务器分页获取会话列表

会话未读数获取或清零本地会话的未读数

 

-

会话未读数

置顶会话置顶会话置顶会话
删除会话单向删除服务端会话及本地会话单向删除服务端会话和本地会话及其历史消息
删除本地会话及历史消息删除本地会话及历史消息
管理用户属性设置和获取用户属性用户属性指实时消息互动用户的信息,如用户昵称、头像、邮箱、电话、性别、签名、生日等管理用户属性
管理用户关系好友列表管理和黑名单管理

添加、删除好友;

-

设置和获取好友备注;

-

从服务器获取好友列表;

-

将用户添加到或移除黑名单

-

从服务器获取黑名单列表

管理用户关系
群组管理群组为多人聊天,有稳定的成员关系。

创建、管理群组;

-

管理群成员;

-

管理群成员属性

群组管理
聊天室管理聊天室为多人聊天,没有固定的成员关系。

聊天室概述

聊天室概述  
创建和管理聊天室创建聊天室创建和管理聊天室
加入聊天室
获取聊天室详情
退出聊天室
解散聊天室
监听聊天室事件
管理聊天室成员获取聊天室成员列表管理聊天室成员
将成员移出聊天室
管理聊天室黑名单
管理聊天室白名单
管理聊天室禁言列表
开启和关闭聊天室全员禁言
管理聊天室所有者和管理员
管理聊天室基本属性获取聊天室公告管理聊天室基本属性
更新聊天室公告
修改聊天室名称
修改聊天室描述
管理聊天室自定义属性管理聊天室自定义属性管理聊天室自定义属性
进阶功能离线推送集成第三方消息推送服务离线推送
登录多个设备支持同一账号在多个设备上登录并接收消息 
多设备管理多设备登录
管理在线状态订阅管理在线状态订阅在线状态订阅
消息表情回复 Reaction对单聊和群聊中的消息通过表情回复消息表情回复
子区管理子区是群组成员的子集子区管理
消息举报开发者可以在客户端调用该接口举报违规消息消息举报
- -## 错误码 - -[iOS 错误码](error.html) - - - - - - - - - - - - - - - - - diff --git a/docs/document/ios/overview.md b/docs/document/ios/overview.md deleted file mode 100644 index 45ca34bc..00000000 --- a/docs/document/ios/overview.md +++ /dev/null @@ -1,253 +0,0 @@ -# SDK 集成概述 - - - -介绍 iOS 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号并获得 App key,详见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -详见 [开发环境要求](quickstart.html#前提条件)。 - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。 - -初始化示例代码: - -```objectivec -// appkey 替换成你在环信即时通讯 IM 管理后台注册应用中的 App Key -EMOptions *options = [EMOptions optionsWithAppkey:@"<#appkey#>"]; -[[EMClient sharedClient] initializeSDKWithOptions:options]; -``` - -## 注册用户 - -目前用户注册方式有以下几种: -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```objectivec -// 异步方法 -[[EMClient sharedClient] registerWithUsername:@"username" - password:@"your password" - completion:^(NSString *aUsername, EMError *aError) { - }]; -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -目前登录服务器支持手动和自动登录。手动登录有两种方式: - -- 用户 ID + 密码 -- 用户 ID + token - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -### 手动登录 - -登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -手动登录后,收到 `connectionStateDidChange` 回调表明 SDK 与环信服务器连接成功。 - -**用户 ID + 密码** 是传统的登录方式。用户名和密码均由你的终端用户自行决定,密码需要符合密码规则要求。 - -```objectivec - //SDK 初始化 `EMOptions` 时可以传入 `loginExtensionInfo` 属性投递给被踢下线的设备。该属性需要开启多设备登录的情况下才能生效。 - EMOptions *options = [EMOptions optionsWithAppkey:<#AppKey#>]; - options.loginExtensionInfo = @"you was kicked out by other device"; - [EMClient.sharedClient initializeSDKWithOptions:options]; -// 异步方法 -[[EMClient sharedClient] loginWithUsername:@"username" - password:@"your password" - completion:^(NSString *aUsername, EMError *aError) { - -}]; - - -``` - -**用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取,详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如每次登录时更新 token 等机制。 -::: - -```objectivec -// 异步方法 -[EMClient.sharedClient loginWithUsername:@"username" token:@"token" completion:^(NSString * _Nonnull aUsername, EMError * _Nullable aError) { - -}]; -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -### 自动登录 - -在初始化的时候,可以设置是否自动登录。如果设置为自动登录,则登录成功之后,后续启动初始化的时候会自动登录。 - -自动登录完成后,触发 `EMClientDelegate` 中的以下回调: - -```objectivec -- (void)autoLoginDidCompleteWithError:(EMError * _Nullable)aError -{ -} -``` - -自动登录时,SDK 尝试连接服务器失败后,延时随机一段时间后自动重连。 - -## 退出登录 - -```objectivec -// 异步方法 -[EMClient.sharedClient logout:YES completion:^(EMError * _Nullable aError) { - -}]; -``` - -## 连接状态相关 - -你可以通过注册连接监听 `EMClientDelegate` 确认连接状态。 - -```objectivec -- viewDidLoad -{ - ... - // 注册连接状态监听,在 SDK 初始化之后调用。 - [EMClient.sharedClient addDelegate:self delegateQueue:nil]; - ... -} - -// 连接状态变更时触发该回调 -- (void)connectionStateDidChange:(EMConnectionState)aConnectionState -{ - if(aConnectionState == EMConnectionConnected) { - // 连接成功 - }else { - // 断开连接 - } -} - -// token 已过期,使用 agoraToken 登录可能触发 -- (void)tokenDidExpire:(EMErrorCode)aErrorCode -{ -} - -// token 已过期,使用 agoraToken 登录可能触发 -- (void)tokenWillExpire:(EMErrorCode)aErrorCode -{ -} - -// 连接成功,开始从服务器拉取离线消息时触发。 -// 注意:如果本次登录服务器没有离线消息,不会触发该回调。 -- (void)onOfflineMessageSyncStart -{ -} - -// 离线用户上线后从服务器拉取离线消息结束时触发。 -// 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。 -- (void)onOfflineMessageSyncFinish -{ -} -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等原因引起的连接中断,SDK 会自动尝试重连。重连成功或者失败会触发回调 `- (void)connectionStateDidChange:(EMConnectionState)aConnectionState`。 - -### 被动退出登录 - -你可以通过监听 `EMClientDelegate` 中的以下回调,调用 `EMClient#logout:completion:` 退出登录并返回登录界面。 - -```objectivec -// 当前登录账号在其它设备登录时,当前登录的设备被踢下线时会触发该回调。该回调在 4.7.0 及其以后版本已经被弃用,由 `userAccountDidLoginFromOtherDeviceWithInfo` 回调替换。 -- (void)userAccountDidLoginFromOtherDevice -{ -} -// 当前登录账号在其它设备登录时,当前的登录设备被踢下线时会触发该回调。 -- (void)userAccountDidLoginFromOtherDeviceWithInfo:(EMLoginExtensionInfo* _Nullable)info { - //`EMLoginExtensionInfo` 中包含 `deviceName`(将当前设备踢下线的设备)以及 `loginExtensionInfo` 属性。`loginExtensionInfo` 即 SDK 初始化时传入的登录时携带给其他设备的扩展信息。该扩展信息在多设备登录情况下才生效。 -} - - //若每次登录都设置 `loginExtensionInfo`,需要通过 `EMClient` 获取 SDK 初始化时的 options 属性进行设置。 - EMClient.sharedClient.options.loginExtensionInfo = @""; - //然后再调用登录 - -// 当前登录账号被强制退出时会收到该回调,如密码被修改、登录设备过多、服务被封禁、被强制下线等原因 -- (void)userAccountDidForcedToLogout:(EMError *_Nullable)aError -{ -} - -// 当前登录账号已被从服务器端删除时会收到该回调 -- (void)userAccountDidRemoveFromServer -{ -} - -// 当前用户账号被禁用时会收到该回调 -- (void)userDidForbidByServer -{ -} -``` - -## 输出信息到日志文件 - -环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。 - -默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。 - -例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。 - -SDK 的 `EMOptions#logLevel` 指定了日志输出级别,默认为 `EMLogLevelDebug`,即所有等级日志。 - -- (默认)EMLogLevelDebug:所有等级的日志; -- EMLogLevelWarning:警告及错误; -- EMLogLevelError:错误。 - -开发阶段若希望在 XCode console 上输出 SDK 日志,可在 SDK 初始化时打开开关。 - -```objectivec -EMOptions* option = [EMOptions optionsWithAppkey:@"<#appkey#>"]; -// 日志输出到 XCode console -option.enableConsoleLog = YES; -// 调整日志输出级别,默认为所有级别。 -option.logLevel = EMLogLevelDebug; -[EMClient.sharedClient initializeSDKWithOptions:option]; -``` - -### 获取本地日志 - -SDK 会写入日志文件到本地。日志文件路径如下:沙箱 Library/Application Support/HyphenateSDK/easemobLog。 - -以真机为例,获取本地日志过程如下: - -- 打开 Xcode,连接设备,选择 **Xcode** > **Window** > **Devices and Simulators**。 -- 进入 **Devices** 选项卡,在左侧选择目标设备,例如 Easemob IM,点击设置图标,然后选择 **Download Container**。 - -![img](/images/ios/overview_fetchlogfile.png) - -日志文件 `easemob.log` 文件在下载包的 AppData/Library/Application Support/HyphenateSDK/easemobLog 目录下。 diff --git a/docs/document/ios/privatecloud.md b/docs/document/ios/privatecloud.md deleted file mode 100644 index ec3d3cf1..00000000 --- a/docs/document/ios/privatecloud.md +++ /dev/null @@ -1,34 +0,0 @@ -# 私有云 SDK 集成配置 - - - -## 静态配置 IP 地址(域名) - -SDK 默认指向公有云地址,在部署私有云后,需要将地址重新指向到新的地址,以下是地址修改方法: - -```objectivec -EMOptions *options = [EMOptions optionsWithAppkey:appkey]; -options.enableDnsConfig = NO; -options.chatPort = 8080;//设置端口号 -options.chatServer = "xxx.xxx.xxx.xxx";//设置 IP 地址 -options.restServer = "xxx.xxx.xxx.xxx:8080";//设置ip:port -options.rtcUrlDomain= "wss://mprtc.easemob.com";//设置多人音视频的服务器域名,此为线上地址 -[[EMClient sharedClient] initializeSDKWithOptions:options]; -``` - -:::tip -如果需要配置 HTTPS 只需加一个属性即可。 -::: - -```objectivec -options.usingHttpsOnly = YES; -``` - -## 动态配置地址 - -1. 服务器端配置 DNS 地址表 -2. 设置服务器端配置的 URL 地址 - -```objectivec -options.dnsURL = @"xxxx";//设置服务器端配置的 URL 地址 -``` \ No newline at end of file diff --git a/docs/document/react-native/overview.md b/docs/document/react-native/overview.md deleted file mode 100644 index 2e7e77f0..00000000 --- a/docs/document/react-native/overview.md +++ /dev/null @@ -1,256 +0,0 @@ -# SDK 集成概述 - - - -介绍 React Native 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号和取得 App key,见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -具体见 [开发环境要求](quickstart.html)。 - -## 增加隐私权限 - -对于 Android 平台: - -1. 找到文件 `android/app/src/main/AndroidManifest.xml` -2. SDK 必需要添加的权限如下: - -```xml - - - - - - -``` - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。初始化的结果通过异步的方式返回。 - -初始化示例代码: - -```typescript -ChatClient.getInstance() - .init( - new ChatOptions({ - appKey: "", - autoLogin: false, - debugModel: true, - }) - ) - .then(() => { - console.log("init success"); - }) - .catch((error) => { - console.log("init fail: ", error); - }); -``` - -初始化参数非常多,这里做主要参数介绍。参数聚合在 `ChatOptions` 类型中。 - -- `appKey`:App 在控制台注册完成之后会生成该参数,这是 App 在系统中的唯一标识。 -- `autoLogin`:是否自动登录。该参数设置为 `true`,则在登录成功之后,后续 App 启动之后自动执行登录操作。如果登录失败会返回错误提示。 -- `debugModel`:是否启用日志输出功能。设置为 `true` 则会启用日志输出功能,在调试开发阶段帮助定位和分析问题。 -- `acceptInvitationAlways`:是否自动接受申请。设置为 `true` 则当有人申请好友时,自动接受申请。 -- `autoAcceptGroupInvitation`:是否自动接受邀请。设置为 `true` 则当有人邀请当前用户入群时,自动接受邀请。 -- `requireAck`:是否需要发送已读回执。设置为 `true` 则消息需要已读回执。详见 [消息回执章节](message_receipt.html)。 -- `requireDeliveryAck`:是否需要发送送达回执。设置为 `true` 则消息需要送达回执。详见消息回执章节。 -- `deleteMessagesAsExitGroup`:是否需要在离开群组时自动删除聊天历史消息。设置为 `true` 则在退出群组的时候,会删除聊天记录。 -- `deleteMessagesAsExitChatRoom`:是否需要在离开聊天室时自动删除聊天历史消息。设置为 `true` 则在退出聊天室的时候,会删除记录。 -- `isChatRoomOwnerLeaveAllowed`:是否允许聊天室所有者离开聊天室。设置为 `true` 则允许。详见 [聊天室](room_overview.html) 章节。 -- `isAutoDownload`: 是否开启自动下载。设置为 `true` 则收到图片、视频、音频、语音消息会自动下载。详见 [消息](message_overview.html) 章节。 - -## 注册用户 - -目前注册的方式有以下几种: - -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```typescript -ChatClient.getInstance() - .createAccount(username, password) - .then((value: any) => { - console.log("createAccount: success", value); - }) - .catch((reason: any) => { - console.log("createAccount: fail", reason); - }); -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -目前登录服务器有两种方式: - -- 用户 ID + 密码 -- 用户 ID + token - -手动登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `onConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -### 手动登录 - -**用户 ID +密码** 登录是传统的登录方式。用户名和密码都是你的终端用户自行决定,密码需要符合密码规则要求。 - -```typescript -ChatClient.getInstance() - .login(username, password, true) - .then((value: any) => { - console.log(`login success`, value); - }) - .catch((reason: any) => { - console.log(`login fail`, reason); - }); -``` - -**用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取。 详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```typescript -ChatClient.getInstance() - .login(username, token, false) - .then((value: any) => { - console.log(`login success`, value); - }) - .catch((reason: any) => { - console.log(`login fail`, reason); - }); -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -### 自动登录 - -在初始化的时候,可以设置是否自动登录。如果设置为自动登录,则登录成功之后,后续启动初始化的时候会自动登录,登录结果异步返回。 - -自动登录时,SDK 尝试连接服务器失败后,延时随机一段时间后自动重连。 - -## 退出登录 - -登出也是异步返回。 - -```typescript -ChatClient.getInstance() - .logout() - .then(() => { - console.log(`logout success`); - }) - .catch((reason: any) => { - console.log(`logout fail`, reason); - }); -``` - -## 连接状态相关 - -你需添加 `ChatConnectEventListener#onConnected` 回调。 - -```typescript -// 监听器建议在初始化完成之后,登录之前设置,这样可以恰当地收到登录通知。 -let listener = new (class s implements ChatConnectEventListener { - onTokenWillExpire(): void { - // todo: token即将过期 - } - onTokenDidExpire(): void { - // todo: token已过期 - } - onConnected(): void { - // todo: 已连接到服务器 - } - onDisconnected(): void { - // todo: 连接已断开,会自动重连。 - } - onAppActiveNumberReachLimit?(): void { - // todo: 达到日活上限,被服务器断开。 - } - onUserDidLoginFromOtherDeviceWithInfo?(params: { - deviceName?: string; - ext?: string; - }): void { - // todo: 用户在其它设备登录,本设备被服务器断开。 - } - onUserDidRemoveFromServer?(): void { - // todo: 当前用户被移除,被服务器断开。 - } - onUserDidForbidByServer?(): void { - // todo: 用户被禁用,被服务器断开。 - } - onUserDidChangePassword?(): void { - // todo: 用户权限信息更改,被服务器断开。 - } - onUserDidLoginTooManyDevice?(): void { - // todo: 用户登录设备超过上限,被服务器断开。 - } - onUserKickedByOtherDevice?(): void { - // todo: 用户被踢下线,被服务器断开。 - } - onUserAuthenticationFailed?(): void { - // todo: 用户权限问题,被服务器断开。 - } - onOfflineMessageSyncStart?(): void { - // todo: 连接成功,开始从服务器拉取离线消息时触发。 - // 注意:如果本次登录服务器没有离线消息,不会触发该回调。 - } - onOfflineMessageSyncFinish?(): void { - // todo: 离线用户上线后从服务器拉取离线消息结束时触发。 - // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。 - } -})(); -ChatClient.getInstance().removeAllConnectionListener(); -ChatClient.getInstance().addConnectionListener(listener); -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等引起的连接终端,系统会自动尝试重连。重连成功或者失败的结果分别会收到通知 `onConnected` 和 `onDisconnected`。 - -### 被动退出登录 - -用户需要关心什么原因被服务器踢下线,需要关注对应事件,并且进行处理。 - -- onAppActiveNumberReachLimit: -- onUserDidLoginFromOtherDeviceWithInfo: -- onUserDidRemoveFromServer: -- onUserDidForbidByServer: -- onUserDidChangePassword: -- onUserDidLoginTooManyDevice: -- onUserKickedByOtherDevice: -- onUserAuthenticationFailed: - -## 输出信息到日志文件 - -如果开启日志调试模式,会通过控制台输出日志。`debugModel` 设置为 `true`。 - -```typescript -chatlog.log(`${ChatClient.TAG}: login: `, userName, "******", isPassword); -``` diff --git a/docs/document/unity/overview.md b/docs/document/unity/overview.md deleted file mode 100644 index b7a0d44b..00000000 --- a/docs/document/unity/overview.md +++ /dev/null @@ -1,299 +0,0 @@ -# 集成概述 - - - -介绍 Unity 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号和获取 App key,参见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -具体见 [集成环境要求](quickstart.html#前提条件)。 - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。 - -初始化示例代码: - -```csharp -Options options = new Options(appkey); -options.AutoLogin = false; -options.UsingHttpsOnly = true; -options.DebugMode = true; -SDKClient.Instance.InitWithOptions(options); -``` - -初始化参数非常多,这里对主要参数进行介绍。参数聚合在 `Options` 类型中。 - -| 参数 | 描述 | -| :----------| :----------------------------------------------------------- | -| `AppKey` | App 在控制台注册完成之后会生成该参数,这是 App 在系统中的唯一标识。 | -| `AutoLogin` | 是否自动登录。该参数设置为 `true`,则在登录成功之后,后续 App 启动之后自动执行登录操作。如果登录失败会返回错误提示。 | -| `DebugMode` | 是否启用日志输出功能。设置为 `true` 则会启用日志输出功能,在调试开发阶段帮助定位和分析问题。 | -| `AcceptInvitationAlways` | 是否自动接受申请。设置为 `true` 则当用户申请好友时,自动接受申请。 | -| `AutoAcceptGroupInvitation` | 是否自动接受邀请。设置为 `true` 则当有人邀请当前用户入群时,自动接受邀请。 | -| `RequireAck` | 是否需要发送已读回执。设置为 `true` 则消息需要已读回执。详见 [消息回执](message_receipt.html) 章节。 | -| `RequireDeliveryAck` | 是否需要发送送达回执。设置为 `true` 则消息需要送达回执。详见 [消息回执](message_receipt.html) 章节。 | -| `DeleteMessagesAsExitGroup` | 是否需要在离开群组时自动删除聊天历史消息。设置为 `true` 则在退出群组的时候,会删除聊天记录。 | -| `DeleteMessagesAsExitRoom` | 是否需要在离开聊天室时自动删除聊天历史消息。设置为 `true` 则在退出聊天室的时候,会删除记录。 | -| `IsRoomOwnerLeaveAllowed` | 是否允许聊天室所有者离开聊天室。设置为 `true` 则允许。详见 [聊天室](room_overview.html) 章节。 | -| `IsAutoDownload` | 是否开启自动下载。设置为 `true` 则收到图片、视频、音频、语音消息会自动下载。详见 [消息](message_send_receive.html#发送和接收图片消息) 章节。 | - -## 注册用户 - -目前,用户注册方式有以下几种: -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```csharp -SDKClient.Instance.CreateAccount(username, password, - callback: new CallBack( - - onSuccess: () => { - Debug.Log("CreateAccount succeed"); - }, - - onError: (code, desc) => { - Debug.Log($"CreateAccount failed, code: {code} ; desc: {desc}"); - } - ) -); -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -SDK 不支持自动登录,只支持通过以下方式手动登录: - -- 用户 ID + 密码 -- 用户 ID + token - -登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `OnConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -1. **用户 ID + 密码** 登录是传统的登录方式。 - -```csharp -SDKClient.Instance.Login(username, password, - callback: new CallBack( - - onSuccess: () => - { - Debug.Log("login succeed"); - }, - - onError: (code, desc) => - { - if (code == 200) - { - Debug.Log("Already login.");; - } - else - { - Debug.Log($"login failed, code: {code} ; desc: {desc}"); - } - } - ) -); -``` - -2. **用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取,详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```csharp -SDKClient.Instance.Login(username, token, true, - callback: new CallBack( - - onSuccess: () => - { - Debug.Log("login succeed"); - }, - - onError: (code, desc) => - { - if (code == 200) - { - Debug.Log("Already login.");; - } - else - { - Debug.Log($"login failed, code: {code} ; desc: {desc}"); - } - } - ) -); -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -## 退出登录 - -登出也是异步返回。 - -```csharp -SDKClient.Instance.Logout(false, - callback: new CallBack( - onSuccess: () => - { - Debug.Log("Logout succeed"); - }, - - onError: (code, desc) => - { - Debug.Log($"Logout failed, code:{code}, desc:{desc}"); - } - ) -); -``` - -## 连接状态相关 - -你需添加 `IConnectionDelegate#OnConnected` 回调。 - -```csharp -// 监听器建议在初始化完成之后,登录之前设置,这样可确保收到登录通知。 -class ConnectionDelegate : IConnectionDelegate -{ - public void OnConnected() - { - } - public void OnDisconnected() - { - } - public void OnAuthFailed() - { - } - public void OnRemovedFromServer() - { - } - public void OnLoginTooManyDevice() - { - } - public void OnChangedIMPwd() - { - } - public void OnKickedByOtherDevice() - { - } - public void OnLoggedOtherDevice(string deviceName) - { - } - public void OnForbidByServer() - { - } - public void OnTokenExpired() - { - } - public void OnTokenWillExpire() - { - } -} -// 添加连接监听器 -ConnectionDelegate connectionDelegate = new ConnectionDelegate(); -SDKClient.Instance.AddConnectionDelegate(connectionDelegate); - -// 移除连接监听器(退出程序时建议移除) -SDKClient.Instance.DeleteConnectionDelegate(connectionDelegate); -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等引起的连接终端,系统会自动尝试重连。重连成功或者失败的结果分别会收到通知`onConnected` 和 `onDisconnected`。 - -### 被动退出登录 - -对于 `onDisconnected` 通知,这些 `errorCode` 需要用户关注,收到这些通知,建议 APP 返回登录界面。 - -- `USER_LOGIN_ANOTHER_DEVICE=206`: 用户已经在其他设备登录 -- `USER_REMOVED=207`: 用户账户已经被移除 -- `USER_BIND_ANOTHER_DEVICE=213`: 用户已经绑定其他设备 -- `SERVER_SERVING_DISABLED=305`: 服务器服务停止 -- `USER_LOGIN_TOO_MANY_DEVICES=214`: 用户登录设备超出数量限制 -- `USER_KICKED_BY_CHANGE_PASSWORD=216`: 由于密码变更被踢下线 -- `USER_KICKED_BY_OTHER_DEVICE=217`: 由于其他设备登录被踢下线 -- `USER_DEVICE_CHANGED=220`: 和上次设备不同导致下线 - -以上参数具体可以参考原生平台对应说明。 - -## 输出信息到日志文件 - -环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。 - -默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。 - -例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。 - -SDK 默认不输出调试信息(所有日志,包括调试信息、警告和错误),只需输出错误日志。若需调试信息,首先要开启调试模式。 - -```csharp -Options options = new Options("YourAppKey"); -options.DebugMode = true; -SDKClient.Instance.InitWithOptions(options); -``` - -### 获取本地日志 - -Unity 分为 4 个端:Unity Mac、Unity Windows、Unity iOS、Unity Android。 - -- Unity Mac - -日志路径: /Users/XXX/Library/Application Support/YYY/ZZZ/sdkdata/easemobLog 或者 /Users/XXX/Library/Application Support/com.YYY.ZZZ/sdkdata/easemobLog - -XXX: Mac 用户名; YYY: Unity 中设置的公司名称,如果没有设置则为 `DefaultCompany`,ZZZ 为 app 名称。 - -- Unity Windows - -日志路径:C:\Users\XXX\AppData\LocalLow\YYY\ZZZ\sdkdata\easemobLog - -XXX:Windows 用户名; YYY: Unity 中设置的公司名称,如果没有设置则为 `DefaultCompany`,ZZZ 为 app 名称。 - -- Unity iOS - -本地日志的获取与 iOS 的相同,详见 [iOS 本地日志的获取](/document/ios/log.html#获取本地日志)。 - -日志路径:沙箱 Library/Application Support/HyphenateSDK/easemobLog。 - -以真机为例,获取本地日志过程如下: - -- 打开 Xcode,连接设备,选择 **Xcode** > **Window** > **Devices and Simulators**。 -- 进入 **Devices** 选项卡,在左侧选择目标设备,例如 Easemob IM,点击设置图标,然后选择 **Download Container**。 - -![img](/images/ios/overview_fetchlogfile.png) - -日志文件 `easemob.log` 文件在下载包的 AppData/Library/Application Support/HyphenateSDK/easemobLog 目录下。 - -- Unity Android - -在 Android Studio 中,选择 **View** > **Tool Windows** > **Device File Explorer**,然后浏览设备上的文件夹。 - -日志路径为 /data/data//sdkdata/easemobLog。 diff --git a/docs/document/web/demo_react.md b/docs/document/web/demo_react.md deleted file mode 100644 index 1685322e..00000000 --- a/docs/document/web/demo_react.md +++ /dev/null @@ -1,44 +0,0 @@ -# React Demo(WebIM)介绍 - - - -环信即时通讯 Web 端提供示例应用可供体验。你可以按以下步骤体验: - -1. [登录 Demo](https://webim-h5.easemob.com/#/login)。 - -![img](/images/demo/web_react_login.png) - -2. 输入你的手机号,获取验证码,然后输入。 - -3. 点击 **登录** 登录 Demo。 - -## 代码下载 - -下载源代码:[GitHub 源码地址](https://github.com/easemob/easemob-demo-react/tree/dev_4.0) - -## 运行 Web IM 项目 - -从 [IM SDK 及 Demo 下载](https://www.easemob.com/download/im) 下载 Web SDK 压缩包,然后解压。解压后在 `demo` 文件夹即为 Web IM 的项目目录。 - -1. 安装 Demo 所需的依赖:在终端中运行 `cd demo` 和 `npm install` 命令。 - -2. 运行 Demo: - - 如果通过 HTTP 访问 Demo,在终端中运行 `cd demo` 和 `npm start` 命令。命令运行后会生成 Demo 的访问地址,例如 https://localhost:3001。通过 HTTP 访问的 Demo 中不包含音视频功能。 - - 如果通过 HTTPS 访问 Demo,在终端中运行 `cd demo` 和 `HTTPS=true npm start` 命令。命令运行后会生成 Demo 的访问地址,例如 https://localhost:3001。通过 HTTPS 访问的 Demo 中包含音视频功能。 - -## 主要模块介绍 - -Demo 中的主要模块如下: - -| 模块名称 | 描述 | -| :----------- | :--------------------------------------- | -| `components` | 项目中定义的组件。 | -| `config` | SDK 初始化配置。 | -| `containers` | 容器组件,包含联系人、聊天、登录和注册。 | -| `layout` | 聊天部分的布局。 | -| `selectors` | 缓存数据,优化性能。 | -| `utils` | 数据库和工具方法。 | - -## 部分 UI 展示 - -![img](/images/web/react_demo.png) diff --git a/docs/document/web/demo_vue.md b/docs/document/web/demo_vue.md deleted file mode 100644 index 760af404..00000000 --- a/docs/document/web/demo_vue.md +++ /dev/null @@ -1,49 +0,0 @@ -# Vue Demo(WebIM)介绍 - - - -环信即时通讯 Web 端提供示例应用可供体验。你可以按以下步骤体验: - -1. 登录 [Vue 3 Demo](https://webim-vue3.easemob.com/login) - -![img](/images/demo/web_vue3_login.png) - -2. 输入你的手机号,获取验证码,然后输入。 - -3. 点击 **登录** 登录 Demo。 - -## 代码下载 - -- Vue 3 :[GitHub 源码地址](https://github.com/easemob/webim-vue-demo/tree/demo-vue3)。 -- Vue 3(miniCore):[GitHub 源码地址](https://github.com/easemob/webim-vue-demo/tree/vue3-miniCore) **miniCore 版本提供 WebIM SDK 按需引入示例以及本地会话使用方式示例,后续新功能将在此版本添加**。 -- Vue 2:[GitHub 源码地址](https://github.com/easemob/webim-vue-demo/tree/dev-4.0)查看 Demo 源码地址。 - -## 运行 Web IM 项目 - -从 [github 下载](https://github.com/easemob/webim-vue-demo/tree/dev-4.0) 下载项目代码压缩包,然后解压。解压后,`webim-vue-demo` 文件夹即为 Web IM 的项目目录。 - -1. 安装 Demo 所需的依赖:在终端中运行 `cd demo` 和 `npm install` 命令。 - -2. 运行 Demo: - - 如果通过 HTTP 访问 Demo,在终端中运行 `cd demo` 和 `npm start` 命令。命令运行后会生成 Demo 的访问地址,例如 https://localhost:3001。通过 HTTP 访问的 Demo 中不包含音视频功能。 - - 如果通过 HTTPS 访问 Demo,在终端中运行 `cd demo` 和 `HTTPS=true npm start` 命令。命令运行后会生成 Demo 的访问地址,例如 https://localhost:3001。通过 HTTPS 访问的 Demo 中包含音视频功能。 - -## 主要模块介绍 - -Demo 中的主要模块如下: - -| 模块名称 | 描述 | -| :----------- | :--------------------- | -| `assets` | 资源文件。 | -| `components` | 项目中定义的组件。 | -| `config` | 消息表情。 | -| `pages` | 登录和聊天页面。 | -| `router` | 路由。 | -| `store` | 使用 Vuex 处理的数据。 | -| `utils` | SDK 配置。 | - -## 部分 Vue 3 Demo 界面展示 - -![img](/images/web/vue3_home.png) - -![img](/images/web/vue3_chat.png) diff --git a/docs/document/web/easecallkit.md b/docs/document/web/easecallkit.md deleted file mode 100644 index ecd0e629..00000000 --- a/docs/document/web/easecallkit.md +++ /dev/null @@ -1,223 +0,0 @@ -# CallKit 使用指南 - -`CallKit` 是一套基于环信 IM 和声网音视频结合开发的音视频 UI 库,实现了一对一语音和视频通话以及多人音视频通话的功能。通过同一用户 ID 登录多台设备的场景下,当用户处理一台设备上的来电响铃后,其他所有设备都会同时停止响铃。 - -## 技术原理 - -使用 `CallKit` 实现实时音视频通讯的基本流程如下: - -1. 调用 `init` 对 `CallKit` 进行初始化。 -2. 主叫方调用 `startCall` 发起通话邀请,进行一对一或多人通话。 -3. 被叫方收到 `onInvite` 后,选择接受或拒绝通话邀请。若接受邀请,则进入通话。 -4. 通话结束时,SDK 触发 `onStateChange` 回调。 - -## 前提条件 - -集成该库之前,你需要满足以下条件: - -- 创建 [环信应用](/product/enable_and_configure_IM.html)及[声网应用](https://doc.shengwang.cn/doc/rtc/javascript/get-started/enable-service#创建声网项目); -- 实现环信 IM 的基本功能,包括登录、好友、群组以及会话等的集成; -- 上线前开通声网 Token 验证时,用户需要实现自己的 [App Server](https://github.com/easemob/easemob-im-app-server/tree/master/agora-app-server),用于生成 Token。详见[创建 Token 服务及使用 App Server 生成 Token](https://doc.shengwang.cn/doc/rtc/javascript/basic-features/token-authentication)。 - -## 项目设置 - -1. 在终端上运行以下命令安装 `CallKit`: - -``` -npm install chat-callkit -``` - -2. 导入 `CallKit`: - -``` -import Callkit from 'chat-callkit'; -``` - -## 实现音频和视频通话 - -本节介绍如何在你的项目中实现音频和视频通话。 - -### 初始化 `CallKit` - -调用 `init` 初始化 `CallKit`。 - -```javascript -/** - * 初始化 CallKit - * - * @param appId 声网 App ID。 - * @param agoraUid 声网用户 ID(UID)。 - * @param connection IM SDK 连接实例。 - */ -CallKit.init(appId, agoraUid, connection); -``` - -### 发送通话邀请 - -主叫方调用 `startCall` 发送一对一或多人通话邀请。调用该方法时,需要指定通话类型。 - -- 一对一通话 - -一对一通话时,主叫方向被叫方发送短信作为通话邀请。 - -```javascript -let options = { - /** 通话类型: - * 0:一对一音频通话 - * 1:一对一视频通话 - * 2:多人视频通话 - * 3:多人音频通话 - */ - callType: 0, - chatType: "singleChat", - /** IM 用户 ID */ - to: "userId", - /** 通话邀请消息 */ - message: "Join me on the call", - /** 通话频道名称 */ - channel: "channel", - /** 声网 token */ - accessToken: "Agora token", -}; -CallKit.startCall(options); -``` - -- 多人通话 - -在多人通话中,主叫方向群组或聊天室发送文本消息,同时向用户发送命令消息加入通话。 - -```javascript -let options = { - /** 通话类型: - * 0:一对一音频通话 - * 1:一对一视频通话 - * 2:多人视频通话 - * 3:多人音频通话 - */ - callType: 2, - chatType: "groupChat", - /** IM 用户 ID */ - to: ["userId"], - /** 通话邀请消息 */ - message: "Join me on the call", - /** 群组 ID */ - groupId: "groupId", - /** 群组名称 */ - groupName: "group name", - /** 声网 token */ - accessToken: "Agora token", - /** 通话频道名称 */ - channel: "channel", -}; -CallKit.startCall(options); -``` - -下图为发送一对一视频通话邀请后的用户界面示例: - -![img](/images/web/callkit_single_invite.png) - -### 收到通话邀请 - -通话邀请发送后,如果被叫方在线且可以通话,将通过 `onInvite` 回调收到邀请。你可以弹出一个用户界面,让被叫方在该回调中接受或拒绝邀请。 - -```javascript -/** - * 处理通话邀请。 - * - * @param result 是否弹出用户界面,接听来电: - * - true:是。 - * - false:否。这种情况下,你无需传入 token 。 - * @param accessToken 声网 token 。 - */ -CallKit.answerCall(result, accessToken); -``` - -下图为收到一对一视频通话邀请后的用户界面示例: - -![img](/images/web/callkit_single_receive.png) - -### 多人通话中间发起邀请 - -在多人通话中,多个用户还可以向其他用户发送通话邀请。发送邀请后,SDK 会在发送方的客户端触发 `onAddPerson` 回调。在该回调中,你可以让发送方指定想要邀请加入多人通话的用户,然后调用 `startCall` 发出邀请。 - -### 监听回调事件 - -在通话中,你还可以监听以下回调事件: - -```javascript -function Call() { - // 处理会话状态变更。 - const handleCallStateChange = (info) => { - switch (info.type) { - case "hangup": - // 挂断电话。 - break; - case "accept": - // 被叫方接受通话邀请。 - break; - case "refuse": - // 被叫方拒绝通话邀请。 - break; - case "user-published": - // 远端用户在通话中发布媒体流。 - break; - case "user-unpublished": - // 远端用户在通话中停止发布媒体流。 - break; - case "user-left": - // 远端用户离开通话。 - break; - default: - break; - } - }; - return ; -} -``` - -### 结束通话 - -一对一通话中,只要有一方挂断电话,通话即结束。多人通话中,只有本地用户挂断电话,通话才会结束。若本地用户挂断电话,SDK 会触发 `onStateChange` 回调,其中 `info.type` 中的值为 `hangup`。若远端用户挂断电话,SDK 触发 `onStateChange` 回调,其中 `info.type` 的值为 `user-left`。 - -## 后续步骤 - -本节介绍你在项目中实现音频和视频通话功能时采取的其他步骤。 - -### 使用 Video SDK Token 对用户进行身份验证 - -为了提升通讯安全性,声网建议你在加入通话前通过 Video SDK token 对应用用户进行身份验证。为此,你需要确保[项目的主要证书已启用](https://doc.shengwang.cn/doc/console/general/user-guides/manage_authentication#启用主要证书)。 - -Token 由声网提供的 token 生成器在应用服务器上生成。获取 token 后,需要在调用 `startCall` 和 `answerCall` 时将 token 传递给 callkit。关于在服务器上如何生成 Token 以及在客户端如何获取和更新 Token,详见[使用 Token 认证用户](https://doc.shengwang.cn/doc/rtc/javascript/basic-features/token-authentication)。 - -## 参考 - -本节提供了实现实时音频和视频通信功能时可以参考的其他信息。 - -### API 列表 - -`CallKit` 提供以下 API: - -- 方法如下表所示: - -| 方法 | 描述 | -| ------------------------- | --------------------------------------------------------------------------------------------------------- | -| `initWithConfig:delegate` | 初始化 `CallKit`。 | -| `startCall` | 开始通话。 | -| `answerCall` | 接听电话。 | -| `setUserIdMap` | 设置环信 IM 用户 ID 与声网用户 ID(UID)的映射,格式为 `{[uid1]: 'custom name', [uid2]: 'custom name'}`。 | - -- 回调如下表所示: - -| 事件 | 描述 | -| --------------- | ---------------------------------- | -| `onAddPerson` | 当用户邀请其他用户加入通话时触发。 | -| `onInvite` | 收到通话邀请时触发。 | -| `onStateChange` | 当通话状态变更时发生。 | - -- 属性如下表所示: - -| 属性 | 描述 | -| --------------- | ------------------------ | -| `contactAvatar` | 一对一通话时显示的头像。 | -| `groupAvatar` | 多人通话时显示的头像。 | -| `ringingSource` | 铃声文件。 | diff --git a/docs/document/web/overview.md b/docs/document/web/overview.md deleted file mode 100644 index 3dbb4920..00000000 --- a/docs/document/web/overview.md +++ /dev/null @@ -1,287 +0,0 @@ -# 概述 - - - -本页介绍 Web 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号且获得 App key,见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -具体见 [开发环境要求](quickstart.html#前提条件)。 - -## 引入 SDK - -- (推荐)按需导入 SDK 文件。为了减少 SDK 体积,推荐这种方式,详见[按需引入 SDK 功能模块](import_sdk_minicore.html)。 - -- 对于 JavaScript SDK,导入代码如下: - -```javascript -import EC from "easemob-websdk"; -``` - -- 对于 TypeScript SDK,导入代码如下, EasemobChat 是 SDK 类型的命名空间。 - -```javascript -import EC, { EasemobChat } from "easemob-websdk"; -``` - -- 对于服务端渲染框架, 如 Nuxt、Next 等,需要在客户端渲染阶段引入 SDK。 - -Nuxt 项目, 你可以在 mounted 生命周期动态导入 SDK: - -```javascript -export default { - mounted: () => { - import("easemob-websdk").then((res) => { - const EC = res.default; - console.log(EC, "easemob websdk"); - const conn = new EC.connection({ - appKey: "your appkey" - }); - }); - } -}; -``` - -Next 项目, 要使用客户端组件,你可以在文件顶部的导入上方添加 `use client` 指令。 - -```tsx -'use client' - -import { useEffect } from 'react' - -export default function Home() { - useEffect(() => { - import('easemob-websdk').then((res)=>{ - const EC = res.default; - console.log(EC, "easemob websdk"); - const conn = new EC.connection({ - appKey: "your appkey" - }); - }) - }, []) -} -``` - -## SDK 初始化 - -使用 SDK 前需要进行初始化,示例代码如下: - -```javascript -const conn = new EC.connection({ - appKey: "your appKey", -}); -``` - -初始化 SDK 参数说明: - -| 参数 | 类型 | 是否必需 | 描述 | -| :-------------------- | :----- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- | -| `appKey` | String | 是 | 环信即时通讯云控制台为你的应用生成的唯一标识,由应用名称(`Appname`)和组织名称(`Orgname`)组成。 | -| `isHttpDNS` | Bool | 否 | 是否开启 DNS,防止 DNS 劫持。
-(默认)`true`:开启 DNS;
- `false`:关闭 DNS。 | -| `delivery` | Bool | 否 | 是否开启送达回执:
- `true`:开启;
-(默认)`false`:关闭。 | -| `https` | Bool | 否 | 是否支持通过 HTTPS 访问即时通讯 IM:
- (默认)`true`:支持 HTTPS 和 HTTP;
-`false`:浏览器根据使用的域名自行判断。 | -| `heartBeatWait` | Int | 否 | 心跳间隔,单位为毫秒,默认为 30000。 | -| `deviceId` | String | 否 | 设备 ID,为默认随机值。 | -| `useOwnUploadFun` | Bool | 否 | 是否支持通过自己的路径将图片、文件上传到自己的服务器。
-`true`:支持,需要指定路径;
-(默认)`false`:关闭,通过消息服务器上传下载文件。 | -| `autoReconnectNumMax` | Int | 否 | 最大重连次数。 | - -## 注册用户 - -本节介绍三种用户注册方式。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```javascript -conn - .registerUser({ - /** 用户 ID。 */ - username: string, - /** 密码。 */ - password: string - }) - .then((res) => { - console.log(res); - }); -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -SDK 不支持自动登录,只支持通过以下方式手动登录: - -- 用户 ID + 密码 -- 用户 ID + token - -登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `onConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -1. **用户 ID +密码** 登录是传统的登录方式。用户 ID 和密码都是你的终端用户自行决定,密码需要符合密码规则要求。 - -```javascript -conn - .open({ - user: "username", - pwd: "password", - }) - .then(() => { - console.log("login success"); - }) - .catch((reason) => { - console.log("login fail", reason); - }); -``` - -2. **用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取,详见 [环信用户 token 的获取](/product/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```javascript -conn - .open({ - user: "username", - accessToken: "token", - }) - .then(() => { - console.log("login success"); - }) - .catch((reason) => { - console.log("login fail", reason); - }); -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -## 退出登录 - -```typescript -conn.close(); -``` - -## 连接状态相关 - -你可以通过注册连接监听器确认连接状态。 - -```javascript -conn.addEventHandler("handlerId", { - onConnected: () => { - console.log("onConnected"); - }, - // 自 4.8.0 版本,`onDisconnected` 事件新增断开原因回调参数, 告知用户触发 `onDisconnected` 的原因。 - onDisconnected: () => { - console.log("onDisconnected"); - }, - onTokenWillExpire: () => { - console.log("onTokenWillExpire"); - }, - onTokenExpired: () => { - console.log("onTokenExpired"); - }, - // 连接成功,开始从服务器拉取离线消息时触发。 - // 注意:如果本次登录服务器没有离线消息,不会触发该回调。 - onOfflineMessageSyncStart: () => { - console.log("onOfflineMessageSyncStart"); - }, - // 离线用户上线后从服务器拉取离线消息结束时触发。 - // 注意:如果再拉取离线过程中因网络或其他原因导致连接断开,不会触发该回调。 - onOfflineMessageSyncFinish: () => { - console.log("onOfflineMessageSyncFinish"); - }, -}); -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等引起的连接中断,系统会自动尝试重连。重连成功或者失败分别会收到 `onConnected` 和 `onDisconnected` 通知。 - -你可以设置最大重连次数 `autoReconnectNumMax`,该参数默认为 5 次。 - -### 被动退出登录 - -对于 `onDisconnected` 通知,错误码(`errorCode`)可能为以下几种,建议 App 返回登录界面。 - -| 错误码 | 描述 | -| :------------------------------------------------- | :------------------------- | -| WEBIM_CONNCTION_USER_LOGIN_ANOTHER_DEVICE=206 | 用户已经在其他设备登录。 | -| WEBIM_CONNCTION_USER_REMOVED=207 | 用户账户已经被移除。 | -| WEBIM_CONNCTION_USER_KICKED_BY_CHANGE_PASSWORD=216 | 由于密码变更被踢下线。 | -| WEBIM_CONNCTION_USER_KICKED_BY_OTHER_DEVICE=217 | 由于其他设备登录被踢下线。 | - -## 输出信息到日志文件 - -开启日志输出: - -```javascript -logger.enableAll(); -``` -- 设置日志不输出到控制台: - -```javascript -logger.setConsoleLogVisibility(false) -``` - -- 监听 SDK 日志事件: - -```javascript -logger.onLog = (log)=>{ - console.log('im logger', log) -} -``` - -关闭日志输出: - -```javascript -logger.disableAll(); -``` - -设置日志输出等级: - -```javascript -// 0 - 5 或者 'TRACE','DEBUG','INFO','WARN','ERROR','SILENT'; -logger.setLevel(0); -``` - -设置缓存日志: - -```javascript -logger.setConfig({ - useCache: false, // 是否缓存 - maxCache: 3 * 1024 * 1024, // 最大缓存字节 -}); -// 缓存全部等级日志 -logger.setLevel(0); -``` - -下载日志: - -```javascript -logger.download(); -``` - -## 日志上报 - -自 4.8.1 版本,Web SDK 支持日志上报功能, 即将日志会上传到环信的服务器。该功能默认关闭,如有需要, 可联系商务开通。 \ No newline at end of file diff --git a/docs/document/web/privatecloud.md b/docs/document/web/privatecloud.md deleted file mode 100644 index e8fbdf50..00000000 --- a/docs/document/web/privatecloud.md +++ /dev/null @@ -1,67 +0,0 @@ -# 私有云 SDK 集成配置 - -## Web Vue 2 Demo - -对于 Web Vue Demo,进行私有化配置需在 [Vue 2 Demo 源代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/zq/private-vue2-20230104.zip)中进行修改。 - -### 修改环境配置 - -在 `src/utils/WebIMConfig.js` 文件中,进行如下修改: - -```javascript -appkey: 'easemob#easeim', // 私有化的 App Key -isHttpDNS: false, // 是否允许通过 DNS 获取。由于私有云需自己配置,这里必须为 `false`。 -socketServer: 'https://xxx.xxxxx.com', // 私有化的 WebSocket 地址 -restServer: 'https://xxx.xxxxx.com', // 私有化的 RESTful 服务器地址。对于 Uniapp 全平台,需要全局搜索,查找 `a1.easemob.com` 替换为 `restServer`。 -``` - -### 修改 SDK 初始化配置 - -在 `src/utils/WebIM.js` 文件中,进行如下修改: - -```javascript - appKey: WebIM.config.appkey, - url: WebIM.config.socketServer, - apiUrl: WebIM.config.restServer, - isHttpDNS:WebIM.config.isHttpDNS, // 对于私有云,该参数必须为 `false`。 - // 其他配置可酌情添加 -``` - -## Web Vue 3 Demo - -对于 Web Vue 3 Demo,进行私有化配置需在 [Vue 3 Demo 源代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/zq/private-vue3-20230104.zip)中进行修改。 - -### 修改环境配置 - -在 `src/IM/initwebsdk.js` 文件中,进行如下修改: - -```javascript -const DEFAULT_APPKEY = "easemob#easeim"; // 私有化的 App Key -const DEFAULT_URL = "https://xxx.xxxxx.com"; // 私有化的 WebSocket 地址 -const DEFAULT_APIURL = "https://xxx.xxxxx.com"; // 私有化的 RESTful 服务器地址 -``` - -## Web React Demo - -对于 Web React Demo,进行私有化配置需在 [React Demo 源代码](https://download-sdk.oss-cn-beijing.aliyuncs.com/zq/private-demo-20230104.zip)中进行修改。 - -修改配置如下: - -1. 在 `/demo/src/config/WebIMConfig.js` 中修改配置信息,如下所示: - -```javascript - appkey: appkey || 'easemob-demo#zim', - isHttpDNS: false, - restServer: rest.restServer || (window.location.protocol === 'https:' ? 'https:' : 'http:') + '//xxx.xxxxx.com', - restServer: rest.restServer || (window.location.protocol === 'https:' ? 'https:' : 'http:') + '//xxx.xxxxx.com', -``` - -2. 在 `/demo/src/config/WebIM.js` 中修改初始化配置,如下所示: - -```javascript - appKey: WebIM.config.appkey, - url: WebIM.config.socketServer, - apiUrl: WebIM.config.restServer, -``` - -然后,将 `if(WebIM.config.isSandbox)` 判断去掉,只使用 `options` 中配置的地址。 diff --git a/docs/document/windows/overview.md b/docs/document/windows/overview.md deleted file mode 100644 index 885782d7..00000000 --- a/docs/document/windows/overview.md +++ /dev/null @@ -1,266 +0,0 @@ -# 集成概述 - - - -介绍 Windows SDK 集成相关内容。 - -## 前提条件 - -开始前,请注册有效的环信即时通讯 IM 开发者账号和获取 App key,参见 [环信即时通讯云管理后台](https://console.easemob.com/user/login)。 - -## 集成环境 - -具体见 [集成环境要求](quickstart.html#前提条件)。 - -## SDK 初始化 - -初始化是使用 SDK 的必要步骤,需在所有接口方法调用前完成。 - -如果进行多次初始化操作,只有第一次初始化以及相关的参数生效。 - -初始化示例代码: - -```csharp -Options options = new Options(appkey); -options.AutoLogin = false; -options.UsingHttpsOnly = true; -options.DebugMode = true; -SDKClient.Instance.InitWithOptions(options); -``` - -初始化参数非常多,这里对主要参数进行介绍。参数聚合在 `Options` 类型中。 - -| 参数 | 描述 | -| :----------| :----------------------------------------------------------- | -| `AppKey` | App 在控制台注册完成之后会生成该参数,这是 App 在系统中的唯一标识。 | -| `AutoLogin` | 是否自动登录。该参数设置为 `true`,则在登录成功之后,后续 App 启动之后自动执行登录操作。如果登录失败会返回错误提示。 | -| `DebugMode` | 是否启用日志输出功能。设置为 `true` 则会启用日志输出功能,在调试开发阶段帮助定位和分析问题。 | -| `AcceptInvitationAlways` | 是否自动接受申请。设置为 `true` 则当用户申请好友时,自动接受申请。 | -| `AutoAcceptGroupInvitation` | 是否自动接受邀请。设置为 `true` 则当有人邀请当前用户入群时,自动接受邀请。 | -| `RequireAck` | 是否需要发送已读回执。设置为 `true` 则消息需要已读回执。详见 [消息回执](message_receipt.html) 章节。 | -| `RequireDeliveryAck` | 是否需要发送送达回执。设置为 `true` 则消息需要送达回执。详见 [消息回执](message_receipt.html) 章节。 | -| `DeleteMessagesAsExitGroup` | 是否需要在离开群组时自动删除聊天历史消息。设置为 `true` 则在退出群组的时候,会删除聊天记录。 | -| `DeleteMessagesAsExitRoom` | 是否需要在离开聊天室时自动删除聊天历史消息。设置为 `true` 则在退出聊天室的时候,会删除记录。 | -| `IsRoomOwnerLeaveAllowed` | 是否允许聊天室所有者离开聊天室。设置为 `true` 则允许。详见 [聊天室](room_overview.html) 章节。 | -| `IsAutoDownload` | 是否开启自动下载。设置为 `true` 则收到图片、视频、音频、语音消息会自动下载。详见 [消息](message_send_receive.html#发送和接收图片消息) 章节。 | - -## 注册用户 - -目前注册的方式有以下几种: -- 通过控制台注册。 -- 通过 REST API 接口注册。 -- 调用 SDK 接口注册。 - -### 控制台注册 - -通过控制台注册用户,详见[创建 IM 用户](/product/enable_and_configure_IM.html#创建-im-用户)。 - -### REST API 注册 - -请参考 [注册用户](/document/server-side/account_system.html#注册用户)。 - -### SDK 注册 - -若支持 SDK 注册,需登录[环信即时通讯云控制台](https://console.easemob.com/user/login),选择 **即时通讯** > **服务概览**,将 **设置**下的 **用户注册模式** 设置为 **开放注册**。 - -```csharp -SDKClient.Instance.CreateAccount(username, password, - callback: new CallBack( - - onSuccess: () => { - Debug.Log("CreateAccount succeed"); - }, - - onError: (code, desc) => { - Debug.Log($"CreateAccount failed, code: {code} ; desc: {desc}"); - } - ) -); -``` - -:::tip -该注册模式为在客户端注册,旨在方便测试,并不推荐在正式环境中使用。 -::: - -## 用户登录 - -SDK 不支持自动登录,只支持通过以下方式手动登录: - -- 用户 ID + 密码 -- 用户 ID + token - -登录时传入的用户 ID 必须为 String 类型,支持的字符集详见[用户注册的 RESTful 接口](/document/server-side/account_system.html#注册用户)。 - -调用登录接口后,收到 `OnConnected` 回调表明 SDK 与环信服务器连接成功。 - -用户登录流程详见[用户注册与登录的产品说明文档](/product/product_user_registration_login.html)。 - -1. **用户 ID + 密码** 登录是传统的登录方式。 - -```csharp -SDKClient.Instance.Login(username, password, - callback: new CallBack( - - onSuccess: () => - { - Debug.Log("login succeed"); - }, - - onError: (code, desc) => - { - if (code == 200) - { - Debug.Log("Already login.");; - } - else - { - Debug.Log($"login failed, code: {code} ; desc: {desc}"); - } - } - ) -); -``` - -2. **用户 ID + token** 是更加安全的登录方式。token 可以通过调用 REST API 获取,详见 [环信用户 token 的获取](/document/server-side/easemob_user_token.html)。 - -:::tip -使用 token 登录时需要处理 token 过期的问题,比如在每次登录时更新 token 等机制。 -::: - -```csharp -SDKClient.Instance.Login(username, token, true, - callback: new CallBack( - - onSuccess: () => - { - Debug.Log("login succeed"); - }, - - onError: (code, desc) => - { - if (code == 200) - { - Debug.Log("Already login.");; - } - else - { - Debug.Log($"login failed, code: {code} ; desc: {desc}"); - } - } - ) -); -``` - -登录重试机制如下: - -- 登录时,若服务器返回明确的失败原因,例如,token 不正确,SDK 不会重试登录。 -- 若登录因超时失败,SDK 会重试登录。 - -## 退出登录 - -登出也是异步返回。 - -```csharp -SDKClient.Instance.Logout(false, - callback: new CallBack( - onSuccess: () => - { - Debug.Log("Logout succeed"); - }, - - onError: (code, desc) => - { - Debug.Log($"Logout failed, code:{code}, desc:{desc}"); - } - ) -); -``` - -## 连接状态相关 - -你需添加 `IConnectionDelegate#OnConnected` 回调。 - -```csharp -// 监听器建议在初始化完成之后,登录之前设置,这样可确保收到登录通知。 -class ConnectionDelegate : IConnectionDelegate -{ - public void OnConnected() - { - } - public void OnDisconnected() - { - } - public void OnAuthFailed() - { - } - public void OnRemovedFromServer() - { - } - public void OnLoginTooManyDevice() - { - } - public void OnChangedIMPwd() - { - } - public void OnKickedByOtherDevice() - { - } - public void OnLoggedOtherDevice(string deviceName) - { - } - public void OnForbidByServer() - { - } - public void OnTokenExpired() - { - } - public void OnTokenWillExpire() - { - } -} -// 添加连接监听器 -ConnectionDelegate connectionDelegate = new ConnectionDelegate(); -SDKClient.Instance.AddConnectionDelegate(connectionDelegate); - -// 移除连接监听器(退出程序时建议移除) -SDKClient.Instance.DeleteConnectionDelegate(connectionDelegate); -``` - -### 断网自动重连 - -如果由于网络信号弱、切换网络等引起的连接终端,系统会自动尝试重连。重连成功或者失败的结果分别会收到通知`onConnected` 和 `onDisconnected`。 - -### 被动退出登录 - -对于 `onDisconnected` 通知,这些 `errorCode` 需要用户关注,收到这些通知,建议 APP 返回登录界面。 - -- `USER_LOGIN_ANOTHER_DEVICE=206`: 用户已经在其他设备登录 -- `USER_REMOVED=207`: 用户账户已经被移除 -- `USER_BIND_ANOTHER_DEVICE=213`: 用户已经绑定其他设备 -- `SERVER_SERVING_DISABLED=305`: 服务器服务停止 -- `USER_LOGIN_TOO_MANY_DEVICES=214`: 用户登录设备超出数量限制 -- `USER_KICKED_BY_CHANGE_PASSWORD=216`: 由于密码变更被踢下线 -- `USER_KICKED_BY_OTHER_DEVICE=217`: 由于其他设备登录被踢下线 -- `USER_DEVICE_CHANGED=220`: 和上次设备不同导致下线 - -以上参数具体可以参考原生平台对应说明。 - -## 输出信息到日志文件 - -环信即时通讯 IM 日志记录 SDK 相关的信息和事件。环信技术支持团队帮你排查问题时可能会请你发送 SDK 日志。 - -默认情况下,SDK 最多可生成和保存三个文件,`easemob.log` 和两个 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件。这些文件为 UTF-8 编码,每个不超过 2 MB。SDK 会将最新的日志写入 `easemob.log` 文件,写满时则会将其重命名为对应时间点的 `easemob_YYYY-MM-DD_HH-MM-SS.log` 文件,若日志文件超过三个,则会删除最早的文件。 - -例如,SDK 在 2024 年 1 月 1 日上午 8:00:00 记录日志时会生成 `easemob.log` 文件,若在 8:30:00 将 `easemob.log` 文件写满则会将其重命名为 `easemob_2024-01-01_08-30-00.log` 文件,随后在 9:30:30 和 10:30:30 分别生成了 `easemob_2024-01-01_09-30-30.log` 和 `easemob_2024-01-01_10-30-30.log` 文件,则此时 `easemob_2024-01-01_08-30-00.log` 文件会被移除。 - -SDK 默认不输出调试信息(所有日志,包括调试信息、警告和错误),只需输出错误日志。若需调试信息,首先要开启调试模式。 - -```csharp -Options options = new Options("YourAppKey"); -options.DebugMode = true; -SDKClient.Instance.InitWithOptions(options); -``` - -### 获取本地日志 - -Windows SDK 日志位于可执行程序同级目录下的 `sdkdata\easemobLog` 目录中。 \ No newline at end of file