Статьи

Пример SMPP Java (клиент)

В этом посте приведен пример Java-протокола SMPP путем создания простого клиента SMPP, который отправляет короткие сообщения мобильному абоненту. С помощью этого клиента мы можем либо просто отправить отправку сообщения одному мобильному абоненту, либо транслировать сообщение нескольким мобильным абонентам одним выстрелом. Также мы проверим квитанцию ​​о доставке. Для целей клиента мы будем использовать существующую клиентскую библиотеку Java SMPP — jSMPP

Что такое SMPP

SMPP расшифровывается как одноранговая передача коротких сообщений. Это открытый отраслевой стандартный протокол, разработанный для обеспечения гибкого интерфейса передачи данных для передачи данных коротких сообщений. Большую часть времени SMPP используется для массовой передачи коротких сообщений. Вы можете транслировать сообщения тысячам подписчиков одним выстрелом. не только для коротких сообщений, но и для отправки голосовых уведомлений, трансляции сотовой связи, WAP-сообщений, включая WAP Push-сообщения.

Операция SMPP

SMPP использует модель работы клиент-сервер. Прежде чем отправлять какие-либо сообщения в SMPP, мы отправляем команду bind. В этом примере мы будем отправлять bind_transmitter, поскольку мы заинтересованы только в отправке сообщений на сервер. Помимо bind_transmitter, другими командами bind являются bind_receiver, что означает, что клиент будет получать только сообщения, а bind_transceiver разрешает передачу сообщений в обоих направлениях.

Полная информация о работе SMPP выходит за рамки этой статьи. Если вы хотите узнать подробности операции, посетите — SMPP wiki

Использование jSMPP

Чтобы начать работу с клиентом SMPP, мы будем использовать jSMPP. Чтобы включить jSMPP в ваш проект, добавьте следующую зависимость maven в ваш файл pom.xml.

pom.xml

1
2
3
4
5
<dependency>
    <groupId>org.jsmpp</groupId>
    <artifactId>jsmpp</artifactId>
    <version>2.3.5</version>
</dependency>

Пример множественной отправки SMPP

Как мы уже говорили, SMPP можно использовать для отправки сообщений одному или нескольким подписчикам. Ниже приведен пример отправки сообщений нескольким мобильным подписчикам. Первым шагом является отправка команды привязки на сервер с использованием имени хоста, имени пользователя и пароля. Эту операцию мы делаем в initSession (). Как только это будет сделано, будет создан сеанс SMPP, и затем мы сможем использовать этот сеанс для отправки сообщений.

Различные параметры, такие как ip, host, username, password, будут предоставлены соответствующими провайдерами.

MultipleSubmitExample.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public class MultipleSubmitExample {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubmitExample.class);
 
    private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();
 
    private final String smppIp = "127.0.0.1";
 
    private int port = 8086;
 
    private final String username = "localhost";
 
    private final String password = "password";
 
    private final String address = "AX-DEV";
 
    private static final String SERVICE_TYPE = "CMT";
 
    public void broadcastMessage(String message, List numbers) {
        LOGGER.info("Broadcasting sms");
        SubmitMultiResult result = null;
        Address[] addresses = prepareAddress(numbers);
        SMPPSession session = initSession();
        if(session != null) {
            try {
                result = session.submitMultiple(SERVICE_TYPE, TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, address,
                        addresses, new ESMClass(), (byte) 0, (byte) 1, TIME_FORMATTER.format(new Date()), null,
                        new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), ReplaceIfPresentFlag.REPLACE,
                        new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte) 0,
                        message.getBytes());
 
                LOGGER.info("Messages submitted, result is {}", result);
                Thread.sleep(1000);
            } catch (PDUException e) {
                LOGGER.error("Invalid PDU parameter", e);
            } catch (ResponseTimeoutException e) {
                LOGGER.error("Response timeout", e);
            } catch (InvalidResponseException e) {
                LOGGER.error("Receive invalid response", e);
            } catch (NegativeResponseException e) {
                LOGGER.error("Receive negative response", e);
            } catch (IOException e) {
                LOGGER.error("I/O error occured", e);
            } catch (Exception e) {
                LOGGER.error("Exception occured submitting SMPP request", e);
            }
        }else {
            LOGGER.error("Session creation failed with SMPP broker.");
        }
        if(result != null && result.getUnsuccessDeliveries() != null && result.getUnsuccessDeliveries().length > 0) {
            LOGGER.error(DeliveryReceiptState.getDescription(result.getUnsuccessDeliveries()[0].getErrorStatusCode()).description() + " - " +result.getMessageId());
        }else {
            LOGGER.info("Pushed message to broker successfully");
        }
        if(session != null) {
            session.unbindAndClose();
        }
    }
 
    private Address[] prepareAddress(List numbers) {
        Address[] addresses = new Address[numbers.size()];
        for(int i = 0; i< numbers.size(); i++){
            addresses[i] = new Address(TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, numbers.get(i));
        }
        return addresses;
    }
 
    private SMPPSession initSession() {
        SMPPSession session = new SMPPSession();
        try {
            session.setMessageReceiverListener(new MessageReceiverListenerImpl());
            String systemId = session.connectAndBind(smppIp, Integer.valueOf(port), new BindParameter(BindType.BIND_TX, username, password, "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null));
            LOGGER.info("Connected with SMPP with system id {}", systemId);
        } catch (IOException e) {
            LOGGER.error("I/O error occured", e);
            session = null;
        }
        return session;
    }
 
    public static void main(String[] args) {
        MultipleSubmitExample multiSubmit = new MultipleSubmitExample();
        multiSubmit.broadcastMessage("Test message from devglan", Arrays.asList("9513059515", "8884377251"));
    }
}

При создании сеанса SMPP мы зарегистрировали получателя сообщений, который будет использоваться для получения квитанции о доставке сообщения. Ниже приведен пример.

MessageReceiverListenerImpl.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MessageReceiverListenerImpl implements MessageReceiverListener {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(MessageReceiverListenerImpl.class);
    private static final String DATASM_NOT_IMPLEMENTED = "data_sm not implemented";
 
    public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException {
         
        if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass())) {
 
            try {
                DeliveryReceipt delReceipt = deliverSm.getShortMessageAsDeliveryReceipt();
 
                long id = Long.parseLong(delReceipt.getId()) & 0xffffffff;
                String messageId = Long.toString(id, 16).toUpperCase();
 
                LOGGER.info("Receiving delivery receipt for message '{}' from {} to {}: {}",
                    messageId, deliverSm.getSourceAddr(), deliverSm.getDestAddress(), delReceipt);
            } catch (InvalidDeliveryReceiptException e) {
                LOGGER.error("Failed getting delivery receipt", e);
            }
        }
    }
     
    public void onAcceptAlertNotification(AlertNotification alertNotification) {
        LOGGER.info("AlertNotification not implemented");
    }
     
    public DataSmResult onAcceptDataSm(DataSm dataSm, Session source)
            throws ProcessRequestException {
        LOGGER.info("DataSm not implemented");
        throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID);
    }
}

SMPP-квитанция о доставке

SMPP предоставляет множество стандартных кодов ошибок квитанции доставки для идентификации квитанции доставки. Мы внедрили немного, чтобы идентифицировать фактическую информацию о квитанции.

DeliveryReceiptState.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.devglan.smpp;
 
public enum DeliveryReceiptState {
 
    ESME_ROK(0, "Ok - Message Acceptable"),
 
    ESME_RINVMSGLEN(1, "Invalid Message Length"),
 
    ESME_RINVCMDLEN(2, "Invalid Command Length"),
 
    ESME_RINVCMDID(3, "Invalid Command ID"),
 
    ESME_RINVBNDSTS(4, "Invalid bind status"),
 
    ESME_RALYBND(5, "Bind attempted when already bound"),
 
    ESME_RINVPRTFLG(6, "Invalid priority flag"),
 
    ESME_RINVREGDLVFLG(7, "Invalid registered-delivery flag"),
 
    ESME_RSYSERR(8, "SMSC system error"),
 
    ESME_RINVSRCADR(9, "Invalid source address"),
 
    ESME_RINVDSTADR(11, "Invalid destination address"),
 
    ESME_RINVMSGID(12, "Invalid message-id"),
 
    NOT_FOUND(000, "Couldn't resolve.Ask admin to add.");
 
  private int value;
  private String description;
 
  DeliveryReceiptState(int value, String description) {
    this.value = value;
    this.description = description;
  }
 
  public static DeliveryReceiptState getDescription(int value) {
    for (DeliveryReceiptState item : values()) {
      if (item.value() == value) {
        return item;
      }
    }
    return NOT_FOUND;
  }
 
    public int value() {
        return value;
    }
 
    public String description() {
        return description;
    }
 
}

Пример одиночной отправки SMPP

jSMPP предоставляет submitShortMessage () для одиночной отправки. Ниже приводится реализация. Полная реализация приведена в источнике.

1
2
3
4
5
6
String messageId = session.submitShortMessage(SERVICE_TYPE,
                        TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, address,
                        TypeOfNumber.NATIONAL, NumberingPlanIndicator.UNKNOWN, number,
                        new ESMClass(), (byte)0, (byte)1,  TIME_FORMATTER.format(new Date()), null,
                        new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), (byte)0, new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0,
                        message.getBytes());

Вывод

Это простой пример реализации клиента SMPP в Java. В следующем посте мы поговорим о его симуляторе.

Смотрите оригинальную статью здесь: SMPP Java Example (Client)

Мнения, высказанные участниками Java Code Geeks, являются их собственными.