החל מ-Chrome 115, פעילויות באינטרנט מהימן (TWA) יכולות לשלוח הודעות באמצעות postMessage. המסמך הזה כולל הסבר מפורט על ההגדרה הנדרשת לתקשורת בין האפליקציה שלך לאינטרנט.
בסוף המדריך הזה:
- הבן כיצד פועל אימות הלקוח ותוכן האינטרנט.
- דע כיצד לאתחל את ערוץ התקשורת בין הלקוח לתוכן אינטרנט.
- לדעת איך לשלוח הודעות לתוכן באינטרנט ולקבל ממנו הודעות.
כדי לעקוב אחר המדריך הזה, צריך:
- כדי להוסיף את הספרייה העדכנית ביותר של androidx.browser (גרסה 1.6.0-alpha02 לפחות) לקובץ ה-build.gradle.
- Chrome בגרסה 115.0.5790.13 ואילך ל-TWA.
השיטה window.postMessage()
מאפשרת תקשורת ממקורות שונים בין אובייקטים ב-Window בצורה בטוחה. לדוגמה, בין דף לבין חלון קופץ שהוא יצר, או בין דף ל-iframe שמוטמע בו.
בדרך כלל, סקריפטים בדפים שונים מורשים לגשת זה לזה רק אם הדפים שהם מקורם באותו מקור, הם חולקים את אותו פרוטוקול, מספר יציאה ואותו מארח (נקרא גם מדיניות המקור הזהה). השיטה window.postMessage()
מספקת מנגנון נשלט לצורך תקשורת מאובטחת בין מקורות שונים. האפשרות הזו יכולה להיות שימושית להטמעה של אפליקציות צ'אט, כלי שיתוף פעולה ועוד. לדוגמה, אפליקציית צ'אט יכולה להשתמש ב-postMessage
כדי לשלוח הודעות בין משתמשים שנמצאים באתרים שונים.
השימוש ב-postMessage
בפעילויות באינטרנט מהימן (TWA) יכול להיות קצת מסובך, המדריך הזה מסביר איך להשתמש ב-postMessage בלקוח TWA כדי לשלוח הודעות ולקבל הודעות בדף האינטרנט.
הוספת האפליקציה לאימות אתרים
ה-PostMessage API מאפשר לשני מקורות חוקיים לתקשר זה עם זה: מקור ומקור יעד. כדי שהאפליקציה ל-Android תוכל לשלוח הודעות למקור היעד, היא צריכה להצהיר לאיזה מקור היא מקבילה. כדי לעשות זאת באמצעות Digital Asset Links (קישורים לנכס דיגיטלי), מוסיפים את שם החבילה בקובץ assetlinks.json
עם יחס הגובה-רוחב use_as_origin
, כך שיהיה:
[{
"relation": ["delegate_permission/common.use_as_origin"],
"target" : { "namespace": "android_app", "package_name": "com.example.app", "sha256_cert_fingerprints": [""] }
}]
הערה: צריך לספק מקור שמשויך לשדה MessageEvent.origin עם ההגדרה של המקור המשויך ל-TWA. עם זאת, ניתן להשתמש ב-postMessage
כדי לתקשר עם אתרים אחרים שלא כוללים את הקישור לנכסים דיגיטליים. לדוגמה, אם הדומיין www.example.com
נמצא בבעלותך, יהיה עליך להוכיח שדרך DAL יש לך אפשרות לתקשר עם כל אתר אחר. למשל, www.wikipedia.org
.
הוספת PostMessageService למניפסט
כדי לקבל הודעות בנושא postMessage
, עליך להגדיר את השירות על ידי הוספת PostMessageService
למניפסט של Android:
<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 הוא מחלקה של קריאה חוזרת (callback) עבור CustomTabsClient לקבלת הודעות לגבי אירועים בכרטיסיות המותאמות אישית שלהם. אחד מהאירועים האלה הוא onPostMessage
והוא מתקשר כשהאפליקציה מקבלת הודעה מהאינטרנט. צריך להוסיף את הקריאה החוזרת ללקוח כדי להפעיל את ערוץ postMessage כדי להתחיל בתקשורת, כפי שמוצג בקוד הבא.
private final String TAG = "TWA/CCT-PostMessageDemo";
// The origin the TWA is equivalent to, where the Digital Asset Links file
// was created with the "use_as_origin" relationship.
private Uri SOURCE_ORIGIN = Uri.parse("https://source-origin.example.com");
// The origin the TWA will communicate with. In most cases, SOURCE_ORIGIN and
// TARGET_ORIGIN will be the same.
private Uri TARGET_ORIGIN = Uri.parse("https://target-origin.example.com");
// It stores the validation result so you can check on it before requesting
// postMessage channel, since without successful validation it is not possible
// 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.
}
};
תקשורת מהאינטרנט
עכשיו אנחנו יכולים לשלוח ולקבל הודעות מהאפליקציה המארחת שלנו. איך נוכל לעשות את אותו הדבר גם מהאינטרנט? התקשורת צריכה להתחיל באפליקציה המארחת, ואז דף האינטרנט צריך לקבל את היציאה בהודעה הראשונה. היציאה הזו משמשת לתקשורת חוזרת. קובץ ה-JavaScript ייראה בערך כמו בדוגמה הבאה:
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 ב-UnFlood