PostMessage برای TWA، PostMessage برای TWA

سید العبادی
Sayed El-Abady

از Chrome 115 Trusted Web Activities (TWA) می‌تواند با استفاده از postMessages پیام ارسال کند. این مقاله تنظیمات لازم برای برقراری ارتباط بین برنامه شما و وب را شرح می دهد.

در پایان این راهنما، شما: - نحوه کارکرد اعتبار سنجی کلاینت و محتوای وب را درک خواهید کرد. - نحوه راه اندازی کانال ارتباطی بین مشتری و محتوای وب را بدانید. - نحوه ارسال پیام و دریافت پیام از محتوای وب را بدانید.

برای پیروی از این راهنما شما نیاز دارید:

  • برای افزودن جدیدترین کتابخانه androidx.browser (min v1.6.0-alpha02) به فایل build.gradle خود.
  • Chrome نسخه 115.0.5790.13 یا بالاتر برای TWA.

متد window.postMessage() به طور ایمن ارتباط متقاطع بین اشیاء Window را فعال می کند. به عنوان مثال، بین یک صفحه و یک پاپ آپ که ایجاد کرده است، یا بین یک صفحه و یک iframe تعبیه شده در آن.

معمولاً، اسکریپت‌های صفحات مختلف فقط در صورتی مجاز به دسترسی به یکدیگر هستند که صفحاتی که از یک مبدا منشا می‌گیرند، پروتکل، شماره پورت و میزبان یکسانی را به اشتراک بگذارند (همچنین به عنوان خط‌مشی همان مبدأ شناخته می‌شود). متد window.postMessage() مکانیزم کنترل شده ای را برای برقراری ارتباط امن بین مبداهای مختلف فراهم می کند. این می تواند برای پیاده سازی برنامه های چت، ابزارهای مشارکتی و موارد دیگر مفید باشد. به عنوان مثال، یک برنامه چت می تواند از postMessage برای ارسال پیام بین کاربرانی که در وب سایت های مختلف هستند استفاده کند. استفاده از postMessage در فعالیت‌های وب مورد اعتماد (TWA) می‌تواند کمی مشکل باشد، این راهنما شما را با نحوه استفاده از postMessage در سرویس گیرنده TWA برای ارسال پیام و دریافت پیام از صفحه وب راهنمایی می‌کند.

برنامه را به اعتبارسنجی وب اضافه کنید

برای اینکه postMessage کار کند، نیاز به یک رابطه معتبر بین یک وب سایت و برنامه Trusted Web Activity دارد که این سایت را راه اندازی می کند، این کار را می توان با پیوندهای دارایی دیجیتال (DAL) با افزودن نام بسته برنامه در فایل assetlinks.json با رابطه انجام داد. به عنوان use_as_origin بنابراین به صورت زیر خواهد بود:

[{
  "relation": ["delegate_permission/common.use_as_origin"],
  "target" : { "namespace": "android_app", "package_name": "com.example.app", "sha256_cert_fingerprints": [""] }
}]

توجه داشته باشید که راه اندازی در مبدأ مرتبط با TWA، ارائه یک مبدا برای فیلد MessageEvent.origin الزامی است، اما postMessage می تواند برای برقراری ارتباط با سایت های دیگری که شامل پیوند دارایی های دیجیتال نیستند استفاده شود. به عنوان مثال، اگر شما مالک www.example.com هستید، باید آن را از طریق DAL ثابت کنید، اما می توانید با هر وب سایت دیگری مانند www.wikipedia.org ارتباط برقرار کنید.

PostMessageService را به مانیفست خود اضافه کنید

برای دریافت ارتباط postMessage باید سرویس را راه‌اندازی کنید، این کار را با افزودن PostMessageService در مانیفست اندروید خود انجام دهید:

<service android:name="androidx.browser.customtabs.PostMessageService"
android:exported="true"/>

یک نمونه CustomTabsSession دریافت کنید

پس از افزودن سرویس به مانیفست، از کلاس CustomTabsClient برای اتصال سرویس استفاده کنید. پس از اتصال می توانید از کلاینت ارائه شده برای ایجاد یک جلسه جدید به شرح زیر استفاده کنید. CustomTabsSession کلاس اصلی برای مدیریت postMessage API است. کد زیر نشان می دهد که چگونه پس از اتصال سرویس، مشتری برای ایجاد یک جلسه جدید استفاده می شود، این جلسه برای postMessage استفاده می شود:

private CustomTabsClient mClient;
private CustomTabsSession mSession;

// We use this helper method to return the preferred package to use for
// Custom Tabs.
String packageName = CustomTabsClient.getPackageName(this, null);

// Binding the service to (packageName).
CustomTabsClient.bindCustomTabsService(this, packageName, new CustomTabsServiceConnection() {
 @Override
 public void onCustomTabsServiceConnected(@NonNull ComponentName name,
     @NonNull CustomTabsClient client) {
   mClient = client;

   // Note: validateRelationship requires warmup to have been called.
   client.warmup(0L);

   mSession = mClient.newSession(customTabsCallback);
 }

 @Override
 public void onServiceDisconnected(ComponentName componentName) {
   mClient = null;
 }
});

اکنون می‌پرسید که این نمونه customTabsCallback چیست؟ ما این را در بخش بعدی ایجاد خواهیم کرد.

CustomTabsCallback را ایجاد کنید

CustomTabsCallback یک کلاس بازگشت به تماس برای CustomTabsClient است تا پیام‌هایی در مورد رویدادها در برگه‌های سفارشی خود دریافت کند. یکی از این رویدادها onPostMessage است و زمانی که برنامه پیامی از وب دریافت می‌کند، با آن تماس گرفته می‌شود. همانطور که در کد زیر نشان داده شده است، تماس برگشتی را به مشتری اضافه کنید تا کانال postMessage را برای شروع ارتباط مقداردهی کنید.

private final String TAG = "TWA/CCT-PostMessageDemo";
private Uri SOURCE_ORIGIN = Uri.parse("my-app-origin-uri");
private Uri TARGET_ORIGIN = Uri.parse("website-you-are-communicating-with");

// It stores the validation result so you can check on it before requesting postMessage channel, since without successful validation it is not posible to use postMessage.
boolean mValidated;

CustomTabsCallback customTabsCallback = new CustomTabsCallback() {

// Listens for the validation result, you can use this for any kind of
// logging purposes.
 @Override
 public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin,
     boolean result, @Nullable Bundle extras) {
   // If this fails:
   // - Have you called warmup?
   // - Have you set up Digital Asset Links correctly?
   // - Double check what browser you're using.
   Log.d(TAG, "Relationship result: " + result);
   mValidated = result;
 }

// Listens for any navigation happens, it waits until the navigation finishes
// then requests post message channel using
// CustomTabsSession#requestPostMessageChannel(sourceUri, targetUri, extrasBundle)

// The targetOrigin in requestPostMessageChannel means that you can be certain their messages are delivered only to the website you expect.
 @Override
 public void onNavigationEvent(int navigationEvent, @Nullable Bundle extras) {
   if (navigationEvent != NAVIGATION_FINISHED) {
     return;
   }

   if (!mValidated) {
     Log.d(TAG, "Not starting PostMessage as validation didn't succeed.");
   }

   // If this fails:
   // - Have you included PostMessageService in your AndroidManifest.xml ?
boolean result = mSession.requestPostMessageChannel(SOURCE_ORIGIN, TARGET_ORIGIN, new Bundle());
   Log.d(TAG, "Requested Post Message Channel: " + result);
 }

// This gets called when the channel we requested is ready for sending/receiving messages.
 @Override
 public void onMessageChannelReady(@Nullable Bundle extras) {
   Log.d(TAG, "Message channel ready.");

   int result = mSession.postMessage("First message", null);
   Log.d(TAG, "postMessage returned: " + result);
 }

// Listens for upcoming messages from Web.
 @Override
 public void onPostMessage(@NonNull String message, @Nullable Bundle extras) {
   super.onPostMessage(message, extras);
// Handle the received message.

 }
};

ارتباط از طریق وب

اکنون می توانیم از برنامه میزبان خود پیام ارسال و دریافت کنیم، چگونه از وب همین کار را انجام دهیم؟ ارتباط باید از برنامه میزبان شروع شود، سپس صفحه وب باید پورت را از اولین پیام دریافت کند. این پورت برای ارتباط برگشت استفاده می شود. فایل جاوا اسکریپت شما چیزی شبیه به مثال زیر خواهد بود:

window.addEventListener("message", function (event) {
  // We are receiveing messages from any origin, you can check of the origin by
  // using event.origin

  // get the port then use it for communication.
  var port = event.ports[0];
  if (typeof port === 'undefined') return;

  // Post message on this port.
  port.postMessage("Test")

  // Receive upcoming messages on this port.
  port.onmessage = function(event) {
    console.log("[PostMessage1] Got message" + event.data);
  };
});

شما می توانید یک نمونه کامل کامل را در اینجا پیدا کنید

عکس توسط Joanna Kosinska در Unsplash