首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現 SGIP 協議開發聯通短信網關完整指南:下行/上行/狀態報告處理

     編輯:Java 相關知識

SGIP(Short Message Gateway Interface Protocol)是中國聯通短信網關標準協議。本文基於華為 SGIP 開發包,完整示範下行發送、上行接收、狀態報告處理的 Java 實作要點。

協議基礎與開發包

  • 協議版本:SGIP 1.2/2.0
  • 開發包:華為 SGIP API(需商業授權或從合作夥伴獲取)
  • 核心類:SGIPSMProxy、SGIPSubmitMessage、SGIPDeliverMessage、Args

下行發送(MT)實作

public class MtSender {
    // SP 配置(需向聯通申請)
    private static final String SP_NUMBER = "**********";      // 接入號
    private static final String CHARGE_NUMBER = "000000000000000000000"; // 計費號
    private static final String CORP_ID = "*****";             // 企業代碼
    private static final String LOGIN_NAME = "**";             // 登入名
    private static final String LOGIN_PASS = "***";            // 登入密碼
    private static final String HOST = "***.***.***.***";      // 網關 IP
    private static final int PORT = ****;                      // 端口
    
    public static void sendSms(String[] phones, String content) throws Exception {
        Args args = new Args();
        args.set("host", HOST);
        args.set("port", PORT);
        args.set("source-addr", parseNodeId("*******")); // 30000+CorpId 可能超 int
        args.set("login-name", LOGIN_NAME);
        args.set("login-pass", LOGIN_PASS);
        args.set("transaction-timeout", 10);
        args.set("read-timeout", 15);
        
        SGIPSMProxy proxy = new SGIPSMProxy(args);
        if (!proxy.connect(LOGIN_NAME, LOGIN_PASS)) {
            throw new IllegalStateException("登入失敗");
        }
        
        SGIPSubmitMessage msg = new SGIPSubmitMessage(
            SP_NUMBER, CHARGE_NUMBER, phones, CORP_ID, "", "03", "0", "0",
            0, 0, "06", 0, null, null, 1, 0, 0, 15, 0,
            content.getBytes("GB2312").length, content.getBytes("GB2312"), "0"
        );
        
        SGIPMessage resp = proxy.send(msg);
        int status = processSubmitResp(resp);
        if (status != 0) throw new RuntimeException("發送失敗:" + status);
    }
    
    private static int parseNodeId(String s) {
        return new BigInteger(s).intValue(); // 處理 30000+CorpId 超 int 範圍
    }
    
    private static int processSubmitResp(SGIPMessage msg) {
        SGIPSubmitRepMessage rep = (SGIPSubmitRepMessage) msg;
        return rep.getResult(); // 0 成功
    }
}

上行接收(MO)與狀態報告實作

public class MoReceiver extends SGIPSMProxy {
    private static final String SER_HOST = "***.***.***.***";
    private static final int SER_PORT = ****;
    private static final String LOCAL_HOST = "***.***.***.***";
    private static final int LOCAL_PORT = ****;
    
    public MoReceiver(Args args) {
        super(args);
        startService(LOCAL_HOST, LOCAL_PORT); // 本機監聽端口
    }
    
    @Override
    public SGIPMessage onDeliver(SGIPDeliverMessage msg) {
        processDeliver(msg);
        return super.onDeliver(msg); // 返回響應
    }
    
    private void processDeliver(SGIPMessage msg) {
        if (msg instanceof SGIPSubmitRepMessage) {
            // 狀態報告
            handleReport((SGIPSubmitRepMessage) msg);
        } else if (msg instanceof SGIPDeliverMessage) {
            // 上行短信
            SGIPDeliverMessage mo = (SGIPDeliverMessage) msg;
            String phone = mo.getUserNumber();
            String content = mo.getMsgContent(); // 需按 GB2312 解碼
            int cmdId = mo.getCommandId(); // 0: 普通上行
            
            // 業務處理:存庫、推送、異步處理
            processMoSms(phone, content);
        }
    }
    
    private void handleReport(SGIPSubmitRepMessage rep) {
        String msgId = rep.getMsgId();
        int status = rep.getResult();
        // 更新發送記錄狀態
    }
}

關鍵技術難點

難點解決方案
源節點 ID 超 int 範圍BigInteger 解析後 intValue()
GB2312 編碼處理發送 getBytes("GB2312"),接收 new String(bytes, "GB2312")
長連接保活定時發送 ActiveTest 心跳,處理斷線重連
併發發送控制信號量/令牌桶限流,避免超過網關阈值
狀態報告匹配建立 msgId → 發送記錄 映射,異步更新
優先級與費率按業務類型設定 Priority、FeeType、FeeValue

生產環境架構建議

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  業務系統    │────▶│  短信發送服務  │────▶│  SGIP 客戶端  │
└─────────────┘     │  (隊列/重試/   │     │  (連接池/心跳) │
                    │   限流/監控)   │     └──────┬──────┘
                    └──────────────┘            │
                           ▲                    ▼
                    ┌────┴────┐           ┌─────────────┐
                    │  狀態報告 │◀──────────│  聯通 SMG   │
                    │  消費者   │           └─────────────┘
                    └─────────┘
  • 發送服務解耦:業務系統 → 消息隊列 → 發送 Worker
  • 連接池管理:維持多條長連接,輪詢發送
  • 冪等設計:業務層面去重,防止重複發送
  • 監控指標:發送成功率、延遲分佈、隊列積壓、連接狀態

合規與注意事項

  • 需取得聯通 SP 資質、簽署協議、獲取測試/正式環境賬號
  • 內容審核:敏感詞過濾、模板備案、變量驗證
  • 頻率控制:單號碼/單簽名/單模板日發送限制
  • 退訂機制:支援「回TD退訂」等標準指令
  • 資料保留:發送記錄至少保存 6 個月(監管要求)

SGIP 協議雖屬老牌標準,但在聯通短信業務中仍佔主導地位。掌握其協議細節、異常處理、生產級架構模式,是構建穩定短信服務的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved