sms短信网关对接
因为工作的需求,需要对接短信网关,业务上就是一个注册用户时,需要发送手机验证码;可能别的公司都是使用第三方接口,但是大点的公司,为了安全,他们都有自己的短信消息中心(SMSC)
1.业务需求
- 1.对接短信网关,发送消息,下行发送(MT) 使用openSMPP开源的开发包
- 2.验证码使用redis存储(主要原因是,分布式存储,支持过期时间)
2. 下面是简单的代码实例(包括发送短信和redis存储验证码)
pom中添加依赖
- <dependency>
- <groupId>org.opensmpp</groupId>
- <artifactId>opensmpp-core</artifactId>
- <version>3.0.2</version>
- </dependency>
- public class SmsController {
- @Autowiredprivate RedisTemplate redisTemplate;
- public boolean sendVerifyCode() {
- String destination = "8613594312686";
- String host = "192.168.XX";
- String port = "12345";
- String userName = "test";
- String password = "test";
- //存储redis中的key
- String key = getDestinationNumKey(destination);
- //redis中已存在验证码,则使用redis中存储的验证码(在15分钟的过期时间内发送同一条验证码),否则生成6位数字验证码
- Object valueByKey = getValueByKey(key);
- String verificationCode = Objects.nonNull(valueByKey) ? valueByKey.toString() : String.valueOf((int) (Math.random() * 900000 + 100000));
- //租户(不传,默认default)
- boolean sendSuccess = sendMessage(host, port, userName, password, destination, verificationCode);
- //发送成功后,验证码存入redis中,并设置过期时间(默认15分钟)
- if (sendSuccess) {
- putValueToRedisWithTimeout(key, verificationCode, 15, TimeUnit.MINUTES);
- }
- return sendSuccess;
- }
- private String getDestinationNumKey(String destination) {
- return String.format("%s:%s", "DESTINATION", destination);
- }
- public boolean sendMessage(String host,
- String port,
- String userName,
- String password,
- String phonenumber,
- String verifyCode) {
- log.info("start to send sms notification, reciever,host {},port {}, userName {} password {} destinations is {} verifyCode {}", host, port, userName, password, phonenumber, verifyCode);
- try {
- TCPIPConnection connection = new TCPIPConnection(host, Integer.parseInt(port));
- Session session = new Session(connection);
- BindRequest request = new BindTransmitter();
- request.setSystemId(userName);
- request.setPassword(password);
- //SMPP protocol version
- request.setInterfaceVersion((byte) 0x34);
- request.setSystemType("SMPP");
- BindResponse bind = session.bind(request);
- log.info("bind response debugString {},response command status {}", bind.debugString(), bind.getCommandStatus());
- String content = "[Registration]" + verifyCode + " is your verification code. Valid in 15 minutes. Please do not share this code with anyone else.";
- SubmitSM submitSM = constructRequest(phonenumber, content);
- //bund faild 会导致TCPIPConnection关闭从而导致outputStream关闭从而导致no
- SubmitSMResp response = session.submit(submitSM);
- log.info("send message result {},command status is {}", response.debugString(), response.getCommandStatus());
- } catch (Exception e) {
- log.error("invoke sms session exception", e);
- }
- }
- private SubmitSM constructRequest(String phoneNumber, String content) throws WrongLengthOfStringException, UnsupportedEncodingException {
- String recipientPhoneNumber = phoneNumber;
- SubmitSM request = new SubmitSM();
- request.setSourceAddr(createAddress("test"));
- request.setDestAddr(createAddress(recipientPhoneNumber));
- request.setShortMessage(content, Data.ENC_UTF8);
- request.setReplaceIfPresentFlag((byte) 0);
- request.setEsmClass((byte) 0);
- request.setProtocolId((byte) 0);
- request.setPriorityFlag((byte) 0);
- request.setRegisteredDelivery((byte) 1);// we want delivery reports
- request.setDataCoding((byte) 0);
- request.setSmDefaultMsgId((byte) 0);
- return request;
- }
- private Address createAddress(String address) throws WrongLengthOfStringException {
- Address addressInst = new Address();
- // national ton
- addressInst.setTon((byte) 5);
- // numeric plan indicator
- addressInst.setNpi((byte) 0);
- addressInst.setAddress(address, Data.SM_ADDR_LEN);
- return addressInst;
- }
- /**
- * Redis中存储Value(value可为string,map,list,set等),并设置过期时间
- *
- * @param key
- * @param value
- * @param timeout
- * @param unit
- */
- public void putValueToRedisWithTimeout(Object key, Object value, final long timeout, final TimeUnit unit) {
- try {
- ValueOperations valueOperations = redisTemplate.opsForValue();
- valueOperations.set(key, value, timeout, unit);
- } catch (Exception e) {
- }
- }
- /**
- * 根据key获取Value值
- *
- * @param key
- */
- public Object getValueByKey(Object key) {
- Object value = null;
- try {
- ValueOperations valueOperations = redisTemplate.opsForValue();
- value = valueOperations.get(key);
- } catch (Exception e) {
- }
- return value;
- }
- /**
- * 根据key获取Value值
- *
- * @param key
- */
- public Object deleteKey(Object key) {
- Object value = null;
- try {
- if (redisTemplate.hasKey(key)) {
- redisTemplate.delete(key);
- }
- } catch (Exception e) {
- }
- return value;
- }
- }
3. 校验验证码
此处代码就不贴了,直接根据手机号去redis中查询,若有值进行比较是否对错,若无值,直接抛出验证码无效即可
4. 对接网关的api
请参考:https://www.world-text.com/docs/interfaces/SMPP/ 和 https://www.smssolutions.net/tutorials/smpp/smpperrorcodes/
5.短信网关模拟器
对接在测试环境时怎么测试是个问题,从网上找到一个模拟SMPP的,感觉挺好用,此处分享地址:SMPP模拟器
其他的参考:
https://support.nowsms.com/discus/messages/1/SMPP_v3_4_Issue1_2-24857.pdf
https://www.activexperts.com/sms-component/smpp-specifications/smpp-pdu-definition/
https://www.openmarket.com/docs/Content/apis/v4smpp/bind.htm
https://zhuanlan.zhihu.com/p/58237629
sms短信网关对接的更多相关文章
- Nagios 安装及微信短信提醒
引言 Nagios 作为业界非常强大的一款开源监视系统. 监控网络服务(SMTP.POP3.HTTP.NNTP.PING 等): 监控主机资源(处理器负荷.磁盘利用率等): 简单地插件设计使得用户可以 ...
- Zabbix 安装及微信短信提醒
Zabbix简介 Zabbix 近几年得到了各大互联网公司的认可,当然第一点归功与它强大的监控功能,第二点免费开源也得到了广大用户的青睐.Zabbix 能将操作系统中的绝大部分指标进行监控,比如(CP ...
- 自学Zabbix3.7-事件Event
配置item.trigger.都是为发送报警做准备的,什么是事件通知呢?简单的说故障发生了,zabbix会发邮件或者短信给你,告诉你服务器的一些状况. 1. 通知条件 发送通知,需要有如下步骤 定义一 ...
- (25)zabbix事件通知
概述 我们前面花了大量时间去讲解item.trigger.event都是为发送报警做准备的,什么是事件通知呢?简单的说故障发生了,zabbix会发邮件或者短信给你,告诉你服务器的一些状况. 如果没有通 ...
- JavaWeb-SpringBoot(抖音)_一、抖音项目制作
JavaWeb-SpringBoot(抖音)_一.抖音项目制作 传送门 JavaWeb-SpringBoot(抖音)_二.服务器间通讯 传送门 JavaWeb-SpringBoot(抖音)_三.抖音项 ...
- 【SMS】移动短信网关返回信息状态代码说明【China Mobile】
1 由SMSC返回的一般结果状态报告 含义 说明 处理建议DELIVRD 消息发送成功 用户成功接收到短信 ??EXPIRED 因为用户长时间关机或者不在服务区等导致的短消息超时没有递交到用户手机上 ...
- 如何对接网建SMS短信通短信验证码接口
1首先注册登录网建SMS网站 http://www.smschinese.cn/ 2.下载Java代码 3.JAVA调用 import java.io.UnsupportedEncodingExce ...
- Android系统应用Mms之Sms短信发送流程(Mms应用部分)二
1. 新建一条短信, 在发送短信之前, 首先创建的是一个会话Conversation, 以后所有与该接收人(一个或多个接收人)的消息交互, 都在该会话Conversation中. ComposeMes ...
- Android 4.4 (KitKat) SMS Apis Change——Android 4.4的一个重大变化
Android团队通过Android开发博客透漏今年会放出Android 4.4 (KitKat) ,同时更新了 SMS 的部分API.博客上讲只有default SMS app才能对短信数据库有写权 ...
随机推荐
- [opencv]统计每个像素值的数目
int histo[256] = { 0 };//直方图统计每个像素值的数目 int width = img.cols, height = img.rows; int num_of_pixels = ...
- HTML网页设计基础笔记 • 【目录】
持续更新中- 我的大学笔记>>> 章节 内容 第1章 HTML网页设计基础笔记 • [第1章 HTML5基础] 第2章 HTML网页设计基础笔记 • [第2章 排列页面内容] 第3章 ...
- 使用 jQuery 操作页面元素的方法,实现浏览大图片的效果,在页面上插入一幅小图片,当鼠标悬停到小图片上时,在小图片的右侧出现与之相对应的大图片
查看本章节 查看作业目录 需求说明: 使用 jQuery 操作页面元素的方法,实现浏览大图片的效果,在页面上插入一幅小图片,当鼠标悬停到小图片上时,在小图片的右侧出现与之相对应的大图片 实现思路: 在 ...
- 你在寻找Vue3移动端项目框架嘛?请看这里
现在web开发变得更加美妙高效,在于开发工具设计得更好了,丰富性与易用性,都有所提高.丰富性带来了一个幸福的烦恼,就是针对实际应用场景,如何选择工具 ? 1. Vue Cli和Vite之间的选择 Vi ...
- SpringBoot中如何优雅的使用多线程
SpringBoot中如何优雅的使用多线程 当异步方法有返回值时,如何获取异步方法执行的返回结果呢?这时需要异步调用的方法带有返回值CompletableFuture
- Oracle的dbf文件迁移
1.背景说明 在Oracle数据库中插入了1.5亿条数据, 并且创建了主键索引, 又插入了1.5亿条数据到另外一张表, 导致数据库表空间暴涨到28G, 由于根目录下只有50G的空间, 数据库文件所在磁 ...
- SpringBoot集成jasperreport实现打印功能
1.jaspersoft studio工具下载地址 下载直通车 2.工具使用方法查看以下链接 工具使用 3.将工具编译后的.jasper文件放到SpringBoot项目的resources/templ ...
- Linux上天之路(十四)之Linux数据处理
主要内容 数据检索 数据排序 数据去重 重定向 1. 数据检索 常和管道协作的命令 – grep grep:用于搜索模式参数指定的内容,并将匹配的行输出到屏幕或者重定向文件中,常和管道协作的命令 – ...
- k8s 理解Service工作原理
什么是service? Service是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法. 简单来说K8s提供了service对象来访问pod.我们在<k8s网络模型与集群通信> ...
- Ubuntu16安装Nvidia驱动(GTX1060显卡)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...