SMPP Java示例(客户端)

本文提供了一个简单的SMPP Java客户端示例,利用jSMPP库向移动用户发送短信,支持单个和多个用户提交,并介绍如何处理交货收据。SMPP是一种用于短消息传输的开放标准协议,常用于批量发送短信。文章涵盖了SMPP的基本操作,如bind命令,并展示了如何在项目中集成jSMPP。

这篇文章通过创建一个简单的SMPP客户端向移动用户发送短信来提供SMPP Java示例,使用该客户端我们可以简单地提交以向单个移动用户发送消息,也可以一次将消息广播给多个移动用户。另外,我们将验证交货收据。 出于客户端的目的,我们将使用现有的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

<dependency>
	<groupId>org.jsmpp</groupId>
	<artifactId>jsmpp</artifactId>
	<version>2.3.5</version>
</dependency>

SMPP多次提交示例

正如我们讨论的那样,SMPP可用于向单个或多个订户发送消息。以下是向多个移动订户发送消息的示例。第一步是使用主机名,用户名和密码向服务器发送绑定命令。 我们正在initSession()中执行此操作。 完成此操作后,将创建SMPP会话,然后我们可以使用此会话发送消息。

相应的提供程序将提供不同的参数,例如ip,主机,用户名,密码。

MultipleSubmitExample.java

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

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提供了许多标准的交货收据错误代码来标识交货收据。 我们几乎没有采取任何措施来识别实际的收货信息。有关完整的详尽清单,请遵循– smpperrorcodes

DeliveryReceiptState.java

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为单个提交提供了commitShortMessage()。以下是实现。 源代码中提供了完整的实现。

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());

结论

这是Java中SMPP客户端实现的简单示例。 在下一篇文章中,我们将讨论其模拟器。

翻译自: https://www.javacodegeeks.com/2018/03/smpp-java-exampleclient.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值