一、背景
ブックその後、手書きMQフレーム(II) -達成するためのサーバー 前述は、サーバの実装について説明します。しかし、プロセスの枠組みの具体的な使用は、使用者は間違いを扱うクライアント側のサービスの形態であろう。フレームワークの使いやすさに、クライアントの直接影響の品質。
フレームワークは、現在のWebフォームを使用して機能を提供しているが、目標は、実際にソケットを介して達成されるが、ユーザーがサーバーの実装方法の過程で考慮する必要はありませんのでこと、そうではないだけで、クライアントが存在するが、また、パッケージ化。
簡単に言えば、クライアントが使用するのは簡単でなければなりません。
第二に、クライアントの実装
1、HTTP使用率
現在、クライアントのコア機能は、主にサービス側を要求するために、HttpClientを実装使用して、このクラスHttpUtilです。
特定には、以下を達成します。
パッケージcom.shuimutong.gmq.client.util。 インポートにjava.io.IOException; 輸入java.net.URISyntaxException。 輸入はjava.util.ArrayList; 輸入はjava.util.List; 輸入java.util.Map; 輸入org.apache.http.HttpEntity。 輸入org.apache.http.NameValuePair; 輸入org.apache.http.client.entity.UrlEncodedFormEntity。 輸入org.apache.http.client.methods.CloseableHttpResponse。 輸入org.apache.http.client.methods.HttpGet; 輸入org.apache.http.client.methods.HttpPost; 輸入org.apache.http.client.utils.URIBuilder。 インポートorg.apache.http.impl.client.CloseableHttpClient; インポートorg.apache.http.impl.client.HttpClients; インポートorg.apache.http.message.BasicNameValuePair; インポートorg.apache.http.util.EntityUtils; インポートORG .slf4j.Logger; インポートorg.slf4j.LoggerFactory; インポートcom.shuimutong.gmq.client.bean.HttpResponseBean; インポートcom.shuimutong.gutil.common.GUtilCommonUtil; / ** * HTTPリクエストツール * @ClassName:HTTPUTIL * @description :(一文の説明では、このクラスのここでの役割) * @author :水のバケツ * @date:5月29日の2019インディアン10日の午後九時43分54秒 * @copyright:2019 [水バケツ]すべての権利を保有。 * / パブリック クラスHttpUtil { 民間 最終 静的ロガーログ= LoggerFactory.getLogger(HttpUtil クラス)。 プライベート 静的 CloseableHttpClient HTTP_CLIENT = HttpClients.createMinimal(); 静的{ Runtime.getRuntime()addShutdownHook(。新しいスレッド(){ @Override 公共 のボイドの実行(){ 試み{ HTTP_CLIENT.close(); } キャッチ(例外:IOException e)の{ log.error("HTTP_CLIENT-closeException" 、E)。 } } })。 } / ** *得る请求 * * @param URL * @return * @throws のIOException * / パブリック 静的 HttpResponseBean GET(文字列のURL)がスローIOExceptionが{ HttpResponseBean responseBean = NULL ; HTTPGET HTTPGET = 新しいHTTPGET(URL); CloseableHttpResponse RES = HTTP_CLIENT.execute(HTTPGET)。 試す{ HttpEntity httpEntity = res.getEntity()。 文字列本体 = EntityUtils.toString(httpEntity)。 responseBean = 新しいHttpResponseBean(res.getStatusLine()、ボディ); EntityUtils.consume(httpEntity)。 } 最後に{ res.close()。 } 戻りresponseBeanと、 } / ** *带参数的取得请求 * @param URL * @param requsetParams * @return * @throwsIOExceptionが * @throws URISyntaxException * / パブリック 静的 HttpResponseBeanのget(String型のURL、地図<文字列、文字列> requsetParams)スローIOExceptionが{ HttpResponseBean responseBean = nullを。 HTTPGET HTTPGET; 試す{ URIBuilder uriBuilder = 新しいURIBuilder(URL); もし(!GUtilCommonUtil.checkListEmpty(requsetParams)){ リスト <のNameValuePair> nvps = 新しいのArrayList <のNameValuePair>(); requsetParams.forEach((K、V)- > { nvps.add(新しいBasicNameValuePair(K、V))。 }); uriBuilder.setParameters(nvps)。 } HTTPGET = 新しいHTTPGET(uriBuilder.build())。 } キャッチ(例外e){ スロー 新規のIOException(e)を、 } CloseableHttpResponse RES = HTTP_CLIENT.execute(HTTPGET)。 試す{ HttpEntity httpEntity = res.getEntity()。 文字列のボディ = EntityUtils.toString(httpEntity)。 responseBean = 新しいHttpResponseBean(res.getStatusLine()、ボディ); EntityUtils.consume(httpEntity)。 } 最後に{ res.close()。 } 戻りresponseBeanと、 } / ** *ポスト请求 * @param URL * @param requsetParams * @return * @throws IOExceptionが * / パブリック 静的 HttpResponseBeanポスト(文字列のURL、地図<文字列、文字列> requsetParams)スローIOExceptionが{ HttpResponseBean responseBean = NULL ; HttpPost httpPost = 新しいHttpPost(URL); もし(!GUtilCommonUtil.checkListEmpty(requsetParams)){ リスト <のNameValuePair> nvps = 新しいのArrayList <のNameValuePair> (); requsetParams.forEach((K、V) - > { nvps.add(新しいBasicNameValuePair(K、V)); }); httpPost.setEntity(新しいUrlEncodedFormEntity(nvps)); } CloseableHttpResponse応答 = HTTP_CLIENT.execute(httpPost)。 試す{ HttpEntity httpEntity = response.getEntity()。 文字列本体 = EntityUtils.toString(httpEntity)。 responseBean = 新しいHttpResponseBean(response.getStatusLine()、ボディ); EntityUtils.consume(httpEntity)。 } 最後に{ response.close()。 } 戻りresponseBeanと、 } }
そして、ポストの要求が応答結果をカプセル化し、要求を取得するカプセル化します。
プラスリソースを閉じるためのイニシアチブを取ることができるフックは、閉じられたJVMを作成しました。
2、サブスクリプションのニュース、ニュース制作
これらの2つの部分は、主に、結果はそれをパッケージ化され、HttpUtil上記の呼び出し。
特定の上記のgitのを参照してください。
図3に示すように、管理の例
ユーザーを作成するためには、特定の実装、構築されたインスタンスの管理クラスを心配する必要はありません。
パッケージcom.shuimutong.gmq.client.util。 輸入com.shuimutong.gmq.client.cache.CommonObjCache; 輸入com.shuimutong.gmq.client.cache.impl.CommonObjCacheImpl; 輸入com.shuimutong.gmq.client.consumer.GmqConsumer; 輸入com.shuimutong.gmq.client.producer.GmqProducer; パブリック クラスGmqInstanceManage { パブリック 静的GmqProducer getGmqProducer(文字列gmqServerUrl){ リターン 新しいGmqProducer(gmqServerUrl)。 } パブリック 静的GmqConsumer getGmqConsumer(文字列gmqServerUrl){ 戻り 新しいですGmqConsumer(gmqServerUrl)。 } パブリック 静的CommonObjCache getCommonCache(文字列SERVERURL){ リターン 新しいCommonObjCacheImpl(SERVERURL)。 } }
主に変更をパッケージ化します。それのために別の反復、現在のは確かではない具体的な実施例の後に簡単なので、そのユーザーが少ない実装心配作ってみます。
より多くのケアを使用する場合は、必ず、その後のプロジェクトの反復より困難。
第三に、例を使用して
1、ニュースの制作
@Test 公共 ボイドproduceMsg(){ GmqProducerプロデューサ = GmqInstanceManage.getGmqProducer(gmqServerUrl)。 以下のために(INT I = 0; I <5; I ++ ){ 文字列メッセージ = "メッセージ:" + I。 試す{ SendMqResult RES = producer.sendMq(トピック、メッセージ)。 System.out.println(res.getRes())。 } キャッチ(SendMqException電子){ e.printStackTrace(); } } }
2、消費者のニュース
主なアイデアは、次のとおりです。ニュースの消費者の前に、消費者は、現在のメッセージの最初のチェックを持っています。ニュースの消費者の後、消費者の数は、キャッシュに格納されています。
典型的なアクティブ・プル・メッセージは、メッセージが自分の消費パターンを担当しています。
次のことを達成するために:
@Test 公共 ボイドcomsumerMsgByCache(){ GmqConsumer comsumer = GmqInstanceManage.getGmqConsumer(gmqServerUrl)。 CommonObjCache commonCache = GmqInstanceManage.getCommonCache(gmqServerUrl)。 文字列gmqSignは = "gmq_consumer_id" 。 長い consumerId = 0 ; int型のサイズ= 2 ; 以下のために(INT I = 0; I <5; I ++ ){ 試み{ CacheObj cacheId = commonCache.getById(gmqSign)。 もし cacheId(!=NULL ){ consumerId = Long.parseLong(cacheId.getContent())。 } リスト <MqContent> RES = comsumer.getMq(トピック、consumerId、サイズ)。 用(MqContent MQ:RES){ System.out.printlnは(JSONObject.toJSONString(MQ))。 もし(mq.getId()> consumerId){ consumerId = mq.getId()。 } } commonCache.save(gmqSign、String.valueOf(consumerId))。 System.out.println( "保存consumerId:" + consumerId)。 }キャッチ(例外e){ e.printStackTrace(); } } }
IVの概要
gmq初版はもちろん、これはほんの始まりで、完了しています。
次の工程は、第1のフレームgmvcは網状直接通信し、交換しました。
その後、メッセージはディスクに保存代わりに、データベースに保存されます。
そして、変換は非常に利用可能なサービスです。
指導を歓迎します。
設計、開発の第二版......