当社はメールとSMSに従事しています。 初期段階では、中間APIを使用してSMSを送信しました。 会社は成長しており、顧客が増えているため、smppプロトコルを介してSMSを送信するための独自のソフトウェアを作成することにしました。 これにより、一連のバイトをプロバイダーに送信することができ、すでに国や国内の事業者間でトラフィックが分散されていました。
SMSを送信するための利用可能な無料のライブラリを確認した後、選択は
jsmppに委ねられました 。
これに加えて、使用に関する情報は主に
jsmppによってgoogleからソート
されました 。 ロシアの
tytsの SMPPプロトコル自体の説明。
この記事で、SMPPサービスを作成するときの生活が楽になることを願っています。
はじめに
SMS送信の段階的な分析から始めましょう。 SMS送信ロジックは次のとおりです。
1.クライアントは、送信したいSMSを(jsonの形式で)送信します。
{ "sms_id": "test_sms_123", "sender": " ", "phone": "380959999900", "text_body": "! 1000000$!", "flash": 0 }
flashパラメーターは、これが
flash smsではないことを示しています。
2.データを受信すると、プロバイダーにデータを送信する方法、つまり
UDH、SAR、Payloadの準備を開始します。 それはすべて、プロバイダーがサポートする方法に依存します。
3.データをプロバイダーに転送すると、プロバイダーによるSMS受信を識別する行が返されます。この行を
transaction_idと呼びます。
4. SMSを送信すると、プロバイダーには48時間以内に最終ステータス(配信済み、未配信など)を返す権利が与えられます。 したがって、
sms_idと受信した
transaction_idを保存する
必要があります。
5. SMSが受信者に配信されると、プロバイダーは
transaction_idとステータス(配信済み)を送信します。
ステータス
ステータスに関する2つの記事をアドバイスします。10のステータスのみ
が説明され、名前が付けられてい
ます。ここに 、ステータスコードの完全なリストとその完全な説明があります。
jSmpp APIのMaven依存関係:
<dependency> <groupId>com.googlecode.jsmpp</groupId> <artifactId>jsmpp</artifactId> <version>2.1.0-RELEASE</version> </dependency>
作業する主なクラスについて説明します。
- SMPPSession-プロバイダーに登録し、アカウントのお金が引き出されるユーザーに対して作成されるセッション。
- SessionStateListener-リスナーは、セッションのステータスが変更されたこと、たとえばセッションが閉じられたことを通知します。
- MessageReceiverListener-リスナーは、 transaction_id 、 ステータス 、 モバイル番号を格納するDeliverSmオブジェクトを返します。
ペイロードの送信方法
これを送信する最も簡単な方法は
ペイロードです。 SMSを送信する期間に関係なく、1つのデータパケットでSMSを送信します。 プロバイダー自体がSMSを部分に分割します。 パーツは、受信者の電話で既に接着されています。 それから、SMSの送信の実装のレビューを開始します。
まず、プロバイダーに接続する必要があります。 これを行うには、セッションとそのリスナー、および送信されたSMSのステータスの受信に応答するリスナーを作成する必要があります。 以下は、作成した
SmppServerクラスにデータが保存されているプロバイダーに接続する
ための
createSmppSessionメソッドの例です。 ログイン、パスワード、IP、ポートなどのデータが含まれています。
SMPP接続を作成する方法 protected SMPPSession session; protected SmppServer server; private ExecutorService receiveTask; private SessionStateListener stateListener; ...
この例からわかるように、
SmsReceiverListenerImplおよび
SessionStateListenerImplクラス
オブジェクトを使用してセッションを作成します。 1つ目は送信されたSMSのステータスを受信し、2つ目はセッションリスナーです。
onStateChangeメソッドの
SessionStateListenerImplクラスは、古いセッション状態と新しいセッション状態のクラスを取得します。 この例では、セッションが接続されていない場合、再接続が試行されます。
SMPPセッションリスナー class SessionStateListenerImpl implements SessionStateListener { @Override public void onStateChange(SessionState newState, SessionState oldState, Object source) { if (!newState.isBound()) { log.warn("SmppSession changed status from {} to {}. {}", oldState, newState, sessionName); reconnect(); } } }
SmsReceiverListenerImplの例。 3つのメソッド
onAcceptDeliverSm 、
onAcceptAlertNotification 、
onAcceptDataSmをオーバーライドする必要があります。 SMSを送信するのは最初の人だけです。 彼はプロバイダーから
transaction_idを受け取ります。プロバイダーはその下でSMSとステータスを登録しています。 この例では、
SmppErrorStatusと
StatusTypeの 2つのクラスがあります。
それぞれ 、エラーステータスを保存し、ステータス(プロバイダーに送信されず、プロバイダーに送信されないなど)を送信する
列挙クラスです。
リスナーSMSステータス class SmsReceiverListenerImpl implements MessageReceiverListener { @Override public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { if (Objects.isNull(deliverSm)) { log.error("Smpp server return NULL delivery answer"); return; } try {
最後に、最も重要な方法はSMSを送信する方法です。 上記のJSONを
SMSMessageオブジェクトにデシリアライズしました。したがって、このクラスのオブジェクトに会うときは、送信されたSMSに関する必要な情報がすべて含まれていることに注意してください。
以下で説明する
sendSmsMessageメソッドは、
SingleSmppTransactionMessageクラスのオブジェクトを返します。このクラスには、プロバイダーによって割り当てられた
transaction_idで送信されたSMSに関するデータが含まれます。
Gsm0338クラスは、SMSのキリル文字の内容を判別するのに役立ちます。 これはプロバイダーに通知する必要があるため重要です。 このクラスは、
ドキュメントに基づいて構築されました。
Enumクラスの
SmppResponseErrorは、プロバイダーのSMPPサーバーが返す可能性のあるエラーに基づいて構築されました。リンクは
こちら 。
SMS送信方法 public SingleSmppTransactionMessage sendSmsMessage(final SMSMessage message) { final String bodyText = message.getTextBody(); final int smsLength = bodyText.length(); OptionalParameter messagePayloadParameter; String transportId = null; String error = null; boolean isUSC2 = false; boolean isFlashSms = message.isFlash(); StopWatchHires watchHires = new StopWatchHires(); watchHires.start(); log.debug("Start to send sms id {} length {}", message.getSmsId(), smsLength); try { byte[] encoded; if ((encoded = Gsm0338.encodeInGsm0338(bodyText)) != null) { messagePayloadParameter = new OptionalParameter.OctetString( OptionalParameter.Tag.MESSAGE_PAYLOAD.code(), encoded); log.debug("Found Latin symbols in sms id {} message", message.getSmsId()); } else { isUSC2 = true; messagePayloadParameter = new OptionalParameter.OctetString( OptionalParameter.Tag.MESSAGE_PAYLOAD.code(), bodyText, "UTF-16BE"); log.debug("Found Cyrillic symbols in sms id {} message", message.getSmsId()); } GeneralDataCoding dataCoding = getDataCodingForServer(isUSC2, isFlashSms); log.debug("Selected data_coding: {}, value: {}, SMPP server type: {}", dataCoding.getAlphabet(), dataCoding.toByte(), server.getServerType()); transportId = session.submitShortMessage( "CMT", TypeOfNumber.ALPHANUMERIC, NumberingPlanIndicator.UNKNOWN, message.getSender(), TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.ISDN, message.getPhone(), ESM_CLASS, ZERO_BYTE, ONE_BYTE, null, null, rd, ZERO_BYTE, dataCoding, ZERO_BYTE, EMPTY_ARRAY, messagePayloadParameter); } catch (PDUException e) { error = e.getMessage();
次の記事では、UDHを使用してSMSを送信する方法について説明します。リンクはこちらです。 このオプションでは、メッセージをバイトに変換してからサブメッセージに分割し、最初のビットに番号と番号を指定する必要があります。 楽しいでしょう。
Githubリンク 。 私の記事がSMPPサービスの開発を簡素化することを願っています。 読んでくれてありがとう。