اتبعAsyncHttpClient على تويتر.
تتيح مكتبة AsyncHttpClient (AHC) لتطبيقات Java تنفيذ طلبات HTTP بسهولة ومعالجة استجابات HTTP بشكل غير متزامن. تدعم المكتبة أيضًا بروتوكول WebSocket.
إنها مبنية على قمة Netty. تم تجميعه مع Java 11.
يتم نشر الثنائيات في Maven Central. إضافة تبعية إلى قطعة أثرية AsyncHttpClient الرئيسية:
مخضرم:
< dependencies >
< dependency >
< groupId >org.asynchttpclient</ groupId >
< artifactId >async-http-client</ artifactId >
< version >3.0.1</ version >
</ dependency >
</ dependencies >
غرادل:
dependencies {
implementation ' org.asynchttpclient:async-http-client:3.0.1 '
}
قم باستيراد مساعدي Dsl لاستخدام طرق مناسبة لتمهيد المكونات:
import static org . asynchttpclient . Dsl .*;
import static org . asynchttpclient . Dsl .*;
AsyncHttpClient asyncHttpClient = asyncHttpClient ();
يجب إغلاق مثيلات AsyncHttpClient (استدعاء التابع close
) بمجرد الانتهاء منها، عادةً عند إيقاف تشغيل التطبيق الخاص بك. إذا لم تقم بذلك، فسوف تواجه تعليق سلاسل الرسائل وتسرب الموارد.
تهدف مثيلات AsyncHttpClient إلى أن تكون موارد عالمية تشترك في نفس دورة حياة التطبيق. عادةً ما يكون أداء AHC ضعيفًا إذا قمت بإنشاء عميل جديد لكل طلب، حيث سيقوم بإنشاء سلاسل رسائل جديدة وتجمعات اتصال لكل منها. من الممكن إنشاء موارد مشتركة (EventLoop وTimer) مسبقًا وتمريرها إلى مثيلات عميل متعددة في ملف config. وستكون بعد ذلك مسؤولاً عن إغلاق تلك الموارد المشتركة.
أخيرًا، يمكنك أيضًا تكوين مثيل AsyncHttpClient عبر كائن AsyncHttpClientConfig الخاص به:
import static org . asynchttpclient . Dsl .*;
AsyncHttpClient c = asyncHttpClient ( config (). setProxyServer ( proxyServer ( "127.0.0.1" , 38080 )));
توفر AHC واجهتي برمجة تطبيقات لتحديد الطلبات: المقيدة وغير المقيدة. يوفر AsyncHttpClient
وDsl` أساليب لطرق HTTP القياسية (POST، PUT، إلخ) ولكن يمكنك أيضًا تمرير طريقة مخصصة.
import org . asynchttpclient .*;
// bound
Future < Response > whenResponse = asyncHttpClient . prepareGet ( "http://www.example.com/" ). execute ();
// unbound
Request request = get ( "http://www.example.com/" ). build ();
Future < Response > whenResponse = asyncHttpClient . executeRequest ( request );
استخدم طريقة setBody
لإضافة نص إلى الطلب.
يمكن أن يكون هذا الجسم من النوع:
java.io.File
byte[]
List<byte[]>
String
java.nio.ByteBuffer
java.io.InputStream
Publisher<io.netty.buffer.ByteBuf>
org.asynchttpclient.request.body.generator.BodyGenerator
BodyGenerator
هو تجريد عام يتيح لك إنشاء أجسام الطلب بسرعة. قم بإلقاء نظرة على FeedableBodyGenerator
إذا كنت تبحث عن طريقة لتمرير مجموعات الطلبات بسرعة.
استخدم طريقة addBodyPart
لإضافة جزء متعدد الأجزاء إلى الطلب.
يمكن أن يكون هذا الجزء من النوع:
ByteArrayPart
FilePart
InputStreamPart
StringPart
execute
الأساليب إلى إرجاع java.util.concurrent.Future
. يمكنك ببساطة حظر سلسلة الاتصال للحصول على الرد.
Future < Response > whenResponse = asyncHttpClient . prepareGet ( "http://www.example.com/" ). execute ();
Response response = whenResponse . get ();
يعد هذا مفيدًا لتصحيح الأخطاء ولكنك على الأرجح ستضر بالأداء أو ستنشئ أخطاء عند تشغيل مثل هذه التعليمات البرمجية عند الإنتاج. الهدف من استخدام عميل غير محظور هو عدم حظر مؤشر ترابط الاتصال!
في الواقع، يُرجع execute
الأساليب org.asynchttpclient.ListenableFuture
المشابه لـ Guava. يمكنك تكوين المستمعين ليتم إعلامهم باكتمال المستقبل.
ListenableFuture < Response > whenResponse = ???;
Runnable callback = () - > {
try {
Response response = whenResponse . get ();
System . out . println ( response );
} catch ( InterruptedException | ExecutionException e ) {
e . printStackTrace ();
}
};
java . util . concurrent . Executor executor = ???;
whenResponse . addListener (() - > ??? , executor );
إذا كانت معلمة executor
فارغة، فسيتم تنفيذ رد الاتصال في مؤشر ترابط الإدخال/الإخراج. يجب عليك عدم إجراء عمليات الحظر هناك، وعادةً ما ترسل طلبًا آخر وتحظر في المستقبل.
يمكن أن تتطلب أساليب execute
org.asynchttpclient.AsyncHandler
ليتم إعلامها بالأحداث المختلفة، مثل تلقي الحالة والرؤوس وأجزاء النص. عندما لا تحدد واحدًا، ستستخدم AHC org.asynchttpclient.AsyncCompletionHandler
؛
يمكن أن تسمح لك أساليب AsyncHandler
بإيقاف المعالجة مبكرًا (إرجاع AsyncHandler.State.ABORT
) ويمكن أن تسمح لك بإرجاع نتيجة حسابية من onCompleted
والتي سيتم استخدامها كنتيجة للمستقبل. راجع تنفيذ AsyncCompletionHandler
كمثال.
النموذج أدناه يلتقط حالة الاستجابة ويتخطى معالجة أجزاء نص الاستجابة.
لاحظ أن إرجاع ABORT
يؤدي إلى إغلاق الاتصال الأساسي.
import static org . asynchttpclient . Dsl .*;
import org . asynchttpclient .*;
import io . netty . handler . codec . http . HttpHeaders ;
Future < Integer > whenStatusCode = asyncHttpClient . prepareGet ( "http://www.example.com/" )
. execute ( new AsyncHandler < Integer > () {
private Integer status ;
@ Override
public State onStatusReceived ( HttpResponseStatus responseStatus ) throws Exception {
status = responseStatus . getStatusCode ();
return State . ABORT ;
}
@ Override
public State onHeadersReceived ( HttpHeaders headers ) throws Exception {
return State . ABORT ;
}
@ Override
public State onBodyPartReceived ( HttpResponseBodyPart bodyPart ) throws Exception {
return State . ABORT ;
}
@ Override
public Integer onCompleted () throws Exception {
return status ;
}
@ Override
public void onThrowable ( Throwable t ) {
t . printStackTrace ();
}
});
Integer statusCode = whenStatusCode . get ();
يحتوي ListenableFuture
على طريقة toCompletableFuture
التي تُرجع CompletableFuture
. احذر من أن إلغاء CompletableFuture
هذا لن يؤدي إلى إلغاء الطلب المستمر بشكل صحيح. هناك فرصة جيدة جدًا لأن نعيد CompletionStage
بدلاً من ذلك في الإصدار التالي.
CompletableFuture < Response > whenResponse = asyncHttpClient
. prepareGet ( "http://www.example.com/" )
. execute ()
. toCompletableFuture ()
. exceptionally ( t ->{ /* Something wrong happened... */ })
. thenApply ( response ->{ /* Do something with the Response */ return resp ;});
whenResponse . join (); // wait for completion
يمكنك الحصول على المشروع الكامل لهذا العرض التوضيحي البسيط من org.asynchttpclient.example
يدعم Async Http Client أيضًا WebSocket. تحتاج إلى تمرير WebSocketUpgradeHandler
حيث يمكنك تسجيل WebSocketListener
.
WebSocket websocket = c . prepareGet ( "ws://demos.kaazing.com/echo" )
. execute ( new WebSocketUpgradeHandler . Builder (). addWebSocketListener (
new WebSocketListener () {
@ Override
public void onOpen ( WebSocket websocket ) {
websocket . sendTextFrame ( "..." ). sendTextFrame ( "..." );
}
@ Override
public void onClose ( WebSocket websocket ) {
// ...
}
@ Override
public void onTextFrame ( String payload , boolean finalFragment , int rsv ) {
System . out . println ( payload );
}
@ Override
public void onError ( Throwable t ) {
t . printStackTrace ();
}
}). build ()). get ();
كن مطلعًا على تطورات المكتبة من خلال الانضمام إلى مجموعة مناقشة عميل HTTP غير المتزامن
مناقشات جيثب