انتقال فایل

این صفحه را حذف کرده اند: READ developer/swarm:file transfer

چطوري ازش استفاده کنم؟

Android

وقتی با کسی در اندروید صحبت می کنید، شما امکان ارسال یک عکس در دستگاه خود یا گرفتن یک عکس با این دکمه ها را دارید:

Android_file_buttons

توجه: وقتی یک فایل را ارسال می کنید، دیگری باید آن را بپذیرد. در این لحظه شما "انتظار همتایان" را خواهید دید:

Android_awaiting_peer

چطور کار ميکنه؟

چطور کار می کنه

مقدمه

Jami یک برنامه توزیع شده است و باید بدون هیچ اتصال به اینترنت کار کند. پس انتقال فایل نیز! اساساً، ما برای انجام انتقال فایل و تماس ها از همان روش استفاده می کنیم، اما در TCP. برای خلاصه کردن نحوه کار آن، می توانیم یک موقعیت را تصور کنیم که آلیس (A) می خواهد یک فایل را به باب (B) انتقال دهد.

اول، آلیس از باب درخواست اتصال می کند. برای انجام این کار، جامی از ICE (RFC 6544) ، پروتکل ای که برای مذاکره در مورد ارتباطات بین همسالان استفاده می شود، استفاده می کند. آلیس IP دستگاه خود را از طریق DHT به یک بسته رمزگذاری شده ارسال می کند. بنابراین، هنگامی که باب IP های آلیس را دریافت می کند، آنها قادر به مذاکره در مورد حمل و نقل هستند که در آن باب می تواند بسته ها را به آلیس ارسال کند. مذاکره می تواند موفق باشد، اما اگر شکست خورد، سرور TURN (آن که به تنظیمات پیکربندی تنظیم شده است) برای انجام انتقال استفاده می شود. اگر مذاکره موفق شود، باب ip های خود را به آلیس برای انجام مذاکره در جهت دیگر ارسال می کند. توجه داشته باشید که لینک هنوز هم ارسال نشده است، بنابراین باب IP ها را از طریق DHT در یک پیام رمزگذاری شده ارسال می کند. اگر مذاکره دوم شکست خورد، TURN به عنوان یک بازگشت به عقب استفاده می شود.

حالا که لینک دو جهت TCP اینجاست، مرحله بعدی مذاکره یک TLS 1.3 (به طور کلی یک (TLS1.3)-(DHE-FFDHE8192)-(RSA-PSS-RSAE-SHA384)-(AES-256-GCM) است که من این خطوط را می نویسم) بین آلیس و باب، سپس آلیس شروع به انتقال فایل می کند.

بخش اول یک سر و کله کوچک برای توصیف محتوای فایل خواهد بود. سپس، پس از اینکه باب انتقال را قبول می کند، فایل کامل ارسال خواهد شد.

فرآیند

ارسال پرونده

روش زیر استفاده می شود:

1. یک مشتری به DataTransferFacade::sendFile() . DataTransferFacade کلاس مربوط به API که برای مشتریان در معرض قرار گرفته است. این کلاس برای مدیریت یک نمایش انتقال فایل استفاده می شود (کلاس های مربوط به DataTransfer، IncomingFileTransfer، OutgoingFileTransfer و SubOutgoingFileTransfer). این روش از JamiAccount مرتبط خواسته می شود که یک اتصال را درخواست کند.

![ نمودار: نمودار کلاس DataTransfer] تصاویر/فایل-تحويل-داده-تحويل-دستگاه- نمودار.png)

2. روش DhtPeerConnector: requestConnection() فعال می شود و اتصال بین تمام دستگاه های متصل به همتایی (که در DHT یافت می شوند) ایجاد می شود. DhtPeerConnector برای مدیریت حلقه رویداد اصلی که ارتباطات را مدیریت می کند استفاده می شود. هنگامی که یک دستگاه یافت می شود، حرکت رویداد یک ClientConnector (که اتصال را برای یک دستگاه مدیریت می کند) ایجاد می کند و روش عملیات) را راه اندازی می کند.

3. این روش برای شروع حمل و نقل ICE استفاده می شود و یک PeerConnectionMsg (که حاوی پیام SDP است، در زیر را ببینید) را روی DHT قرار می دهد و منتظر پاسخ است (DhtPeerConnector::Impl::onResponseMsg).

4. سپس پاسخ از DHT دریافت می شود که شامل آدرس های عمومی دستگاه همکار است. ما اکنون می توانیم یک لینک TLS را (به طور مستقیم از طریق ICE، یا از طریق TURN به عنوان یک عقب نشینی) مذاکره کنیم. این TlsSocketEndpoint به شی `PeerConnection به عنوان یک خروجی داده می شود و انتقال می تواند آغاز شود.

5.\ وقتی سوکت TLS آماده است، callback DataTransferFacade::Impl::onConnectionRequestReply نامیده می شود و یک OutgoingFileTransfer به PeerConnection به عنوان ورودی متصل می شود. این OutgoingFileTransfer شامل یک لیست از SubOutgoingFileTransfer (یک در هر دستگاه) است که هر انتقال زیر انتقال انتقال به یک دستگاه است. ما این کار را برای ارائه بهترین دیدگاه انتقال انجام می دهیم (اگر یک تماس به عنوان 3 دستگاه، جایی که تماس انتقال را در یک دستگاه لغو می کند، اما انتقال را در دو دستگاه دیگر پذیرفته است، پیشرفته ترین انتقال نشان داده می شود).

SubOutgoingFileTransfer ابتدا عنوان فایل را منتقل می کند، منتظر پذیرش همتایان (پیام "GO\n" در سوکت) است و سپس فایل را ارسال می کند.

7. اگر از همتایان یا مشتری فسخ دریافت شود یا انتقال فایل به پایان برسد، اتصال از طریق یک پیام CANCEL در DhtPeerConnector::eventLoop() تعطیل می شود و منابع آزاد می شوند.

! TLSsocketEndpoint

دریافت فایل

از همان ساختار برای دریافت فایل ها استفاده می شود، اما روش کمی تغییر می کند:

  1. کلاس JamiAccount برای دریافت پیام های DHT استفاده می شود، زیرا اولین چیزی که دریافت می شود درخواست DHT خواهد بود.

  2. سپس این پیام به DhtPeerConnector: onRequestMessage() از طریق eventLoop داده می شود.

  3. DhtPeerConnector::Impl::answerToRequest سعی خواهد کرد به سرور TURN متصل شود (اگر متصل نشده باشد) و حمل و نقل ICE را آغاز کند. این روش دو اتصال کنترل را به یک سرور TURN باز می کند (یک برای مجوز IPV4 همتایان، دیگری برای همتایان IPv6 ، به دلیل RFC 6156) اگر هنوز باز نشده باشد و اجازه اتصال آدرس های عمومی همتایان را می دهد. سپس ، اگر SDP دریافت شده شامل کاندیداهای ICE نیست ، از TURN استفاده می کند و پاسخ SDP را برای انتظار همتایان ایجاد می کند. اگر SDP شامل کاندیداهای ICE باشد ، روش سعی خواهد کرد که در مورد لینک مذاکره (یا بازگشت به TURN) و سپس به SDP پاسخ دهد (با کاندیداهای ICE یا نه).

  4. هنگامی که لینک ها آماده هستند، مانند فرستنده، یک لینک TLS مذاکره می شود و به PeerConnection داده می شود تا به IncomingFileTransfer به عنوان ورودی داده شود. سرنخ های فایل می آیند و مشتری اکنون می تواند انتقال را بپذیرد یا لغو کند.

دوباره درخواست انتقال فایل قبلی

همانطور که در developer/swarm:Other mime types مشخص شده است، تعاملات انتقال داده ها اکنون همگام سازی شده و به مکالمه ذخیره می شود. بنابراین، یک دستگاه می تواند به راحتی تشخیص دهد که آیا یک فایل دانلود شده است یا نه. در غیر این صورت، می تواند از همه اعضای مکالمه بخواهد که فایل را دوباره ارسال کنند.

برای انجام این کار، دستگاه یک json با نوع mime ارسال می کند: application/data-transfer-request+json حاوی conversation (ID مکالمه) ، interaction (تفاعل مرتبط) ، deviceId دستگاه دریافت کننده فایل.

فرستنده اکنون بررسی می کند که آیا دستگاه یک دستگاه از همتایان اعلام شده است و آیا دستگاه عضو مکالمه است و می تواند فایل را از طریق انتقال فایل کلاسیک ارسال کند.

گیرنده می تواند اولین انتقال وارد شده را قبول کند، فایل را دانلود کند و تأیید کند که sha3sum درست است.

طرح

![ نمودار: نمودار طرح اصلی](تصاویر/فايل-تحويل-نماینه اصلی- نمودار.png)

SDP از طریق DHT ارسال شد
0d04b932
7c33834e7cf944bf0e367b47
H6e6ca682 1 TCP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 50693 typ host tcptype passive
H6e6ca682 1 TCP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 9 typ host tcptype active
H42c1b577 1 TCP 2130706431 fe80::9eb6:d0ff:fee7:1412 50693 typ host tcptype passive
H42c1b577 1 TCP 2130706431 fe80::9eb6:d0ff:fee7:1412 9 typ host tcptype active
Hc0a8007e 1 TCP 2130706431 192.168.0.123 42751 typ host tcptype passive
Hc0a8007e 1 TCP 2130706431 192.168.0.123 9 typ host tcptype active
Sc0a8007e 1 TCP 1694498815 X.X.X.X 42751 typ srflx tcptype passive
Z.Z.Z.Z:YYYY
A.A.A.A:YYYY

در حالی که 0d04b932 ufrag و 7c33834e7cf944bf0e367b47 رمز عبور جلسه ICE است. 2130706431 و 1694498815 اولویت کاندید ها هستند. 192.168.0.126 42751 میزبان tcptype نوع سلبی tcptype یک میزبان سلبی است و 1694498815 X.X.X.X 42751 typ srflx tcptype passive` یک میزبان سلبی منعکس کننده ip عمومی (برای مثال از طریق UPnP نقشه برداری شده است).

دستگاه های متعدد

A user can link its account to several devices. So, we need to implement the transfer when a user send a file to a contact who have multiple devices linked to this account.

اولین رویکرد

اولین رویکرد این بود که درخواست را از طریق DHT به تمام دستگاه ها ارسال کنید و اولین دستگاه هایی که پاسخ می دهند فایل را انتقال دهند. این برای تماس شما بد است زیرا آنها نمی دانند که کدام دستگاه دریافت خواهد کرد انتقال را دریافت می کند.

رویکرد فعلی

حالا ما هنوز یک درخواست را به تمام دستگاه ها می فرستیم. تفاوت این است که همه دستگاه ها اطلاعیه برای دریافت یک فایل دارند و می توانند انتقال را بپذیرند / رد کنند. بخش عمده ای از کد برای آن در *data_transfer.cpp است.

Now (since https://review.jami.net/c/jami-daemon/+/9327), when a user send a file, it will request a PeerConnection with all peer devices. And for all connections, we attach a new input stream to have the ability to accept/refuse/cancel each transfer separately.

در data_transfer.cpp ما کلاس OptimisticMetaOutgoingInfo را تعریف می کنیم که نمایش دیدگاه خوش بینانه را برای نمایش به مشتری نشان می دهد. این خوش بینانه است زیرا اگر یک تماس انتقال را در یک دستگاه پذیرفته و در دستگاه های دیگر رد کند، این کلاس انتقال فایل در حال انجام را نشان می دهد. و فقط در صورتی خطا را نشان می دهد که تمام دستگاه ها انتقال را رد کنند.

این کلاس به SubOutgoingFileTransfer مرتبط است که وضعیت انتقال را با یک دستگاه نشان می دهد. مشتریان قادر خواهند بود یک انتقال زیر را به جای خوشبینانه بعد نشان دهند (به لیست TODO مراجعه کنید).

با استفاده از سرور دیگر TURN

Actually the default TURN server is turn.jami.net. But you can host your own TURN server. For example by running a coturn server.

`sudo turnserver -a -v -n -u user:password -r "realm"

Then, you can configure the TURN server in the advanced settings of the app.

توجه: این نیاز به برخی از دانش فنی دارد. علاوه بر این، سرور TURN باید همان آدرس IP گره شما را به عنوان گره مقصد یا اتصال همتایان را به نمایش بگذارد (چون مجوز نادرست خواهد بود)

فهرست تمام

  1. Use libtorrent?

  2. وضعیت انتقال زیر برای فایل های خارج شده را نمایش دهید