OkHttp — ما هو، الإمكانيات وهندسة عميل HTTP

المؤلف: IT Sectr نُشر: 2026-03-07 وقت القراءة: 8 دق

OkHttp هو عميل HTTP عالي الأداء لنظامي Android وKotlin، طورته شركة Square كأساس لـ Retrofit ومكتبات الشبكات الأخرى. يوفر إدارة فعالة للاتصالات، وتخزيناً مؤقتاً مدمجاً، ودعماً لـ HTTP/2. وفقاً لـ Square، 2025، OkHttp يعالج مليارات الطلبات يومياً في التطبيقات حول العالم.

الخلاصة

  • OkHttp — عميل HTTP لنظامي Android وKotlin من Square مع دعم HTTP/2 وSPDY
  • تجمع الاتصالات — آلية إعادة استخدام اتصالات TCP لتقليل زمن الوصول
  • المعترضات — Interceptor وNetworkInterceptor يعدلان الطلبات والاستجابات
  • التخزين المؤقت — Cache مدمج يقلل حركة المرور في الطلبات المتكررة
  • WebSocket — دعم الاتصال ثنائي الاتجاه عبر بروتوكول WebSocket

ما هو OkHttp؟

OkHttp هو عميل HTTP فعال لـ Java وAndroid وKotlin، طورته شركة Square. توفر المكتبة واجهة برمجة تطبيقات منخفضة المستوى لتنفيذ طلبات HTTP مع دعم HTTP/2 وSPDY وWebSocket واستعادة الاتصال التلقائي عند فشل الشبكة.

ظهر OkHttp في عام 2013 كاستجابة للحاجة إلى عميل HTTP موثوق يحل مشاكل HttpURLConnection — عدم وجود تجمع اتصالات، وضعف دعم HTTP/2، وواجهة برمجة تطبيقات غير ملائمة. بحلول عام 2025، يُستخدم OkHttp على مستوى نظام Android API: OkHttp مضمن في تنفيذ HttpURLConnection منذ Android 4.4 (API 19).

وفقاً لـ Google I/O 2024، يعالج OkHttp أكثر من 70% من جميع طلبات HTTP في النظام البيئي لنظام Android. هذا ممكن لأن OkHttp يعمل كطبقة نقل لـ Retrofit وApollo GraphQL وFirebase والعديد من المكتبات الأخرى. يحصل المطورون على وظائف OkHttp تلقائياً دون الحاجة إلى إضافته صراحة.

كيف يعمل OkHttp

هندسة OkHttp مبنية على سلسلة معترضات. يمر كل طلب عبر سلسلة من المعترضات التي يمكنها تعديل الطلب أو الاستجابة أو إحباط التنفيذ. تشبه هذه الهندسة نمط Chain of Responsibility وتسمح بالتوسع المرن.

عندما يرسل التطبيق طلباً، يقوم OkHttp بالخطوات التالية: يحل DNS، ويختار اتصالاً من التجمع (أو ينشئ اتصالاً جديداً)، ويفتح مصافحة TLS (إذا كان HTTPS)، ويرسل طلب HTTP، ويتلقى الاستجابة، ويعيدها إلى التطبيق. RealCall هي الفئة الداخلية التي تدير دورة الحياة الكاملة للطلب من الإنشاء إلى الإكمال.

يتولى OkHttp تلقائياً معالجة إعادة التوجيه (302، 301)، وإعادة محاولة الطلبات عند فشل الشبكة، واتباع بروتوكول keep-alive، ودعم ضغط gzip الشفاف. لا يحتاج المطور إلى كتابة كود لهذه العمليات — يقوم OkHttp بها تلقائياً بناءً على رؤوس الخادم.

دعم HTTP/2 وتعدد الإرسال

HTTP/2 يسمح بإرسال طلبات متعددة عبر اتصال TCP واحد في وقت واحد، دون حظر الرأس (head-of-line blocking) المميز لـ HTTP/1.1. يستخدم OkHttp تلقائياً HTTP/2 إذا كان الخادم يدعمه، ويتحول بشفافية إلى HTTP/1.1 عند الضرورة.

تعدد إرسال HTTP/2 مهم بشكل خاص للتطبيقات المحمولة، حيث يمكن أن يتراوح زمن إنشاء الاتصال (TCP + TLS) بين 100–300 مللي ثانية. بدلاً من 10 اتصالات متسلسلة، يستخدم OkHttp اتجاهاً واحداً، مما يقلل زمن الوصول الإجمالي بنسبة 40–60% على أجهزة Android النموذجية ذات الاتصالات غير المستقرة.

معترضات OkHttp: Interceptor وNetworkInterceptor

Interceptor هي واجهة بطريقة واحدة intercept(Chain)، تستقبل طلباً وتنفذ إجراءات وتعيد استجابة. هناك نوعان من المعترضات: معترضات التطبيق (تضاف عبر addInterceptor) ومعترضات الشبكة (addNetworkInterceptor).

تعمل معترضات التطبيق قبل تشكيل طلب HTTP — ترى الطلب الأصلي والاستجابة النهائية بعد كل التحويلات. معترضات الشبكة تعمل على مستوى الشبكة: ترى الطلب بعد ضغط gzip، وإضافة رأس Content-Length، وإعادة التوجيه، وإعادة المحاولة. لا يتم استدعاء معترضات الشبكة إذا تم تقديم الاستجابة من ذاكرة التخزين المؤقت.

نوع المعترضطريقة الإضافةمتى يُستدعىيرى التخزين المؤقت
Application InterceptoraddInterceptor()قبل وبعد الطلبنعم
Network InterceptoraddNetworkInterceptor()على مستوى الشبكةلا

الاستخدام العملي للمعترضات

من الناحية العملية، تحل معترضات OkHttp ثلاث مهام رئيسية: التفويض (إضافة رأس Authorization)، التسجيل (HttpLoggingInterceptor لتصحيح الأخطاء)، وإعادة المحاولة (إعادة الطلب التلقائي عند فشل الشبكة). من خلال دمج معترضات متعددة، يمكن بناء خط أنابيب معالجة طلبات كامل دون تكرار الكود في كل استدعاء HTTP للتطبيق.

ترتيب إضافة المعترضات مهم: المعترض المضاف أولاً يُنفذ أولاً عند الدخول وآخراً عند الخروج. بالنسبة لـ NetworkInterceptor، يُحدد الترتيب بواسطة مكدس الشبكة. الترتيب الموصى به: AuthInterceptor (يضيف رمزاً مميزاً)، LoggingInterceptor (يسجل الطلب)، RetryInterceptor (يعيد المحاولة عند الفشل).

التسجيل عبر HttpLoggingInterceptor

لتصحيح أخطاء طلبات الشبكة، يُستخدم HttpLoggingInterceptor — معترض جاهز من Square. يسجل الطريقة وعنوان URL والرؤوس وجسم الطلب والاستجابة. مستويات التسجيل: BASIC (الطريقة + URL + الرمز)، HEADERS (مع الرؤوس)، وBODY (الطلب والاستجابة بالكامل). BODY مفيد أثناء التطوير ولكن يتم تعطيله في الإنتاج لأسباب أمنية وأداء.

أمثلة كود OkHttp بلغة Kotlin

دعنا نلقي نظرة على طلب GET أساسي باستخدام OkHttp. أولاً، يتم إنشاء OkHttpClient — كائن ثقيل يُنشأ مرة واحدة ويعاد استخدامه. ثم يتم تشكيل Request بعنوان URL، ويُنفذ الطلب بشكل متزامن عبر execute أو بشكل غير متزامن عبر enqueue.

kotlin
val client = OkHttpClient.Builder()
    .connectTimeout(15, TimeUnit.SECONDS)
    .readTimeout(15, TimeUnit.SECONDS)
    .build()

val request = Request.Builder()
    .url("https://api.github.com/users/octocat")
    .header("Accept", "application/vnd.github.v3+json")
    .build()

val response = client.newCall(request).execute()
println(response.body()?.string())

للتنفيذ غير المتزامن، يُستخدم أسلوب enqueue الذي يقبل Callback. ينفذ OkHttp الطلب في خلفية الموضوع ويعيد النتيجة في الاستدعاء على نفس الموضوع. للتبديل إلى الموضوع الرئيسي لنظام Android، استخدم Handler أو coroutines.

kotlin
client.newCall(request).enqueue(object : Callback {
    override fun onFailure(
        call: Call, e: IOException
    ) {
        println("فشل الطلب: ${e.message}")
    }

    override fun onResponse(
        call: Call, response: Response
    ) {
        println(response.body()?.string())
    }
})

إضافة معترض للتفويض

Interceptor مخصص يضيف رمز Bearer مميزاً إلى كل طلب. يتحقق المعترض من وجود رأس Authorization، وإذا لم يكن الرمز المميز مضبوطاً بعد، يضيفه من وحدة التخزين. عند استجابة 401، يمكن للمعترض تحديث الرمز المميز عبر Authenticator.

kotlin
class AuthInterceptor(
    private val tokenProvider: () -> String?
) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val token = tokenProvider.invoke()
        val request = originalRequest.newBuilder()
            .header("Authorization", "Bearer $token")
            .build()
        return chain.proceed(request)
    }
}

تجمع الاتصالات والتخزين المؤقت في OkHttp

تجمع الاتصالات (ConnectionPool) هو تحسين رئيسي في OkHttp يسمح بإعادة استخدام اتصالات TCP لطلبات متعددة. بدلاً من إنشاء مأخذ توصيل جديد لكل طلب، يخزن OkHttp ما يصل إلى 5 اتصالات خاملة (افتراضياً) لمدة 5 دقائق، مما يقلل زمن الوصول بنسبة 30–70% للطلبات المتكررة لنفس المضيف.

يتم تنفيذ التخزين المؤقت للاستجابات عبر فئة Cache. لتمكين التخزين المؤقت، يكفي تحديد الدليل والحجم الأقصى في OkHttpClient.Builder. يخزن OkHttp تلقائياً استجابات GET وفقاً لرؤوس Cache-Control وExpires وETag، ويعيد البيانات المخزنة مؤقتاً دون طلب شبكة إذا لم تكن قديمة.

kotlin
val cacheDir = File(context.cacheDir, "http-cache")
val cache = Cache(cacheDir, 10L * 1024 * 1024)

val client = OkHttpClient.Builder()
    .cache(cache)
    .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
    .build()

التكوين الصحيح للتجمع والتخزين المؤقت مهم بشكل خاص للتطبيقات ذات الطلبات المتكررة — خلاصات الأخبار والدردشات وتحديثات البيانات. بدون تجمع، يتطلب كل اتصال TCP مصافحة ثلاثية (SYN، SYN-ACK، ACK) وربما مصافحة TLS (2–3 جولات)، مما يضيف 100–500 مللي ثانية لكل طلب.

يدعم OkHttp أيضاً WebSocket عبر فئة RealWebSocket. يتم إنشاء اتصال WebSocket من خلال مصافحة HTTP (101 Switching Protocols) ثم يتحول إلى بروتوكول ثنائي الاتجاه. يرسل OkHttp تلقائياً إطارات ping للحفاظ على الاتصال نشطاً ويعيد الاتصال عند الانقطاع. WebSocket من OkHttp متوافق مع نقاط النهاية القياسية مثل wss://echo.websocket.org.

الأخطاء الشائعة عند العمل مع OkHttp

إنشاء OkHttpClient لكل طلب هو الخطأ الأكثر شيوعاً. يحتوي OkHttpClient على تجمع اتصالات وذاكرة تخزين مؤقت وتجمع خيوط. إنشاء مثيل جديد لكل طلب لا يهدر الذاكرة فحسب، بل يفقد أيضاً فائدة إعادة استخدام الاتصالات. يجب أن يكون OkHttpClient مفردة عبر حاوية DI.

تجاهل إغلاق Response.body() يؤدي إلى تسرب الموارد. يحتوي ResponseBody على InputStream يجب إغلاقه بعد القراءة. إذا تم استخدام body().string() أو body().bytes()، يغلق OkHttp التدفق تلقائياً، ولكن عند قراءة body().byteStream() أو body().charStream()، يلزم استدعاء close() صريح في كتلة finally.

عدم معالجة المهلة مشكلة أخرى. افتراضياً، لدى OkHttp connectTimeout مدته 10 ثوانٍ، وreadTimeout مدته 10 ثوانٍ، وwriteTimeout مدته 10 ثوانٍ. للتطبيقات المحمولة ذات الاتصالات غير المستقرة، يُوصى بتعيين connectTimeout من 15–30 ثانية وreadTimeout من 15–30 ثانية، وإلا سينتظر المستخدم طويلاً مع إشارة ضعيفة.

الأسئلة الشائعة

ما الفرق بين OkHttp وRetrofit؟

OkHttp هو عميل HTTP منخفض المستوى مع إدارة يدوية للطلب والاستجابة. Retrofit هو تجريد عالي المستوى مع شروح. يُستخدم OkHttp كطبقة نقل لـ Retrofit، ولكنه يمكن أن يعمل بشكل مستقل دون مكتبات إضافية.

كيف يعالج OkHttp HTTPS؟

يستخدم OkHttp SSLSocketFactory لمصافحة TLS. تدعم المكتبة CertificatePinner لتثبيت الشهادات، وTrustManager للتحقق المخصص، وHostnameVerifier للتحقق من اسم المضيف مقابل الشهادة.

كيف يتم التقاط أخطاء الشبكة في OkHttp؟

الطلبات المتزامنة تطرح IOException عند مشاكل الشبكة. الطلبات غير المتزامنة تتلقى استدعاء onFailure مع IOException. لأخطاء HTTP (4xx، 5xx)، تعتبر الاستجابة ناجحة — يتم التحقق من رمز الخطأ عبر response.isSuccessful().

هل يدعم OkHttp WebSocket؟

نعم، OkHttp لديه دعم مدمج لـ WebSocket عبر فئة WebSocket وWebSocketListener. بعد إنشاء الاتصال، يسمح WebSocket بإرسال واستقبال الرسائل في الوقت الفعلي دون طلبات HTTP متكررة.

كيف يتم تعطيل إعادة التوجيه في OkHttp؟

قم بتعطيل إعادة التوجيه التلقائي عبر followRedirects(false) وfollowSslRedirects(false) في OkHttpClient.Builder. هذا مفيد عندما تحتاج إلى معالجة إعادة التوجيه يدوياً، على سبيل المثال، لاستخراج رمز مميز من عنوان URL لإعادة التوجيه.

الملخص

  • OkHttp — عميل HTTP عالي الأداء من Square مع دعم HTTP/2 وSPDY
  • هندسة المعترضات تطبق Chain of Responsibility لتعديل الطلبات
  • تجمع الاتصالات يعيد استخدام اتصالات TCP، مما يقلل زمن الوصول بنسبة 30–70%
  • التخزين المؤقت Cache-Control وETag يقللان حركة المرور في الطلبات المتكررة
  • WebSocket يتيح الاتصال ثنائي الاتجاه في الوقت الفعلي
  • OkHttpClient يجب أن يكون مفردة — إنشاء واحد لكل طلب يؤدي إلى تسرب
  • ResponseBody يتطلب إغلاقاً صريحاً عند القراءة عبر byteStream

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا