需要用到的java库有:
Apache mina : http://mina.apache.org
Spring: http://www.springframework.org/
smppapi http://smppapi.sourceforge.net/
commons ssl: http://juliusdavies.ca/commons-ssl/
- package com.lizongbo.smpp.server;
- import org.apache.mina.filter.LoggingFilter;
- import com.lizongbo.smpp.server.codec.SMPPProtocolCodecFactory;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.common.DefaultIoFilterChainBuilder;
- import java.net.InetSocketAddress;
- import org.apache.mina.common.IoAcceptorConfig;
- import org.apache.mina.transport.socket.nio.SocketAcceptor;
- import org.apache.mina.common.IoAcceptor;
- import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
- import java.io.IOException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import java.util.Set;
- import org.apache.mina.common.IoSession;
- import ie.omk.smpp.*;
- import ie.omk.smpp.message.*;
- import ie.omk.smpp.util.PacketFactory;
- import java.util.*;
- import com.lizongbo.smpp.server.handlers.*;
- /**
- *
- *Title: java smsc server
- *
- *Description: smpp短消息中心
- *
- *Copyright: Copyright (c) 2007
- *
- *Company: http://618119.com
- *
- * @author lizongbo
- * @version 1.0
- */
- public class Main {
- public static void main(String[] args) {
- //以 spring配置方式启动
- ApplicationContext context = new ClassPathXmlApplicationContext(
- “classpath*:/springmina.xml”);
- IoAcceptor acceptor = (IoAcceptor) context.getBean(”ioAcceptor”);
- test(acceptor);
- }
- //普通方式启动
- public static void commonmain(String[] args) throws IOException {
- IoAcceptor acceptor = new SocketAcceptor();
- IoAcceptorConfig config = new SocketAcceptorConfig();
- DefaultIoFilterChainBuilder chain = config.getFilterChain();
- chain.addLast(”logger”, new LoggingFilter());
- chain.addLast(”codec”,
- new ProtocolCodecFilter(new SMPPProtocolCodecFactory()));
- chain.addLast(”threadpool”,
- new org.apache.mina.filter.executor.ExecutorFilter());
- InetSocketAddress serverAddr = new InetSocketAddress(5432);
- SMPPServerSessionHandler handler = new SMPPServerSessionHandler();
- Map<long> handles = new HashMap</long><long> ();
- handles.put(Long.valueOf(0×00000002), new BindTransmitterHandler());
- handles.put(Long.valueOf(0×00000001), new BindReceiverHandler());
- handles.put(Long.valueOf(0×00000004), new SubmitSMHandler());
- handles.put(Long.valueOf(0×00000006), new UnbindHandler());
- handles.put(Long.valueOf(0×80000005), new DeliverSMRespHandler());
- acceptor.bind(serverAddr, handler, config);
- System.out.println(”Listening on port ” + 5432);
- test(acceptor);
- }</long>
- private static void test(IoAcceptor acceptor) throws
- InvalidParameterValueException {
- try {
- Thread.sleep(20000);
- }
- catch (InterruptedException ex) {
- }
- Set<iosession> ss = acceptor.getManagedSessions(new InetSocketAddress(5432));
- System.out.println(”ss.size() == ” + ss.size());
- if (ss.size() > 0) {
- //模拟主动下发一条消息状态报告
- DeliverSM rs = null;
- try {
- rs = (DeliverSM) PacketFactory.newInstance(SMPPPacket.DELIVER_SM);
- }
- catch (BadCommandIDException ex1) {
- }
- //这里还有很多字段没填,需要补上
- rs.setSequenceNum(9999);
- rs.setMessageId(”618119″);
- rs.setServiceType(”aaa”);
- rs.setSource(new Address(0, 0, “618119″));
- rs.setDestination(new Address(0, 0, “10086″));
- rs.setEsmClass(0);
- rs.setProtocolID(0);
- rs.setPriority(0);
- rs.setRegistered(0);
- rs.setReplaceIfPresent(0);
- rs.setDataCoding(15);
- rs.setDefaultMsg(1);
- rs.setMessage(”succ”.getBytes());
- System.out.println(”主动发回一个消息应答”);
- ss.iterator().next().write(rs);
- }
- }</iosession>
- }
package com.lizongbo.smpp.server;
import org.apache.mina.filter.LoggingFilter;
import com.lizongbo.smpp.server.codec.SMPPProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.common.DefaultIoFilterChainBuilder;
import java.net.InetSocketAddress;
import org.apache.mina.common.IoAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import java.io.IOException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Set;
import org.apache.mina.common.IoSession;
import ie.omk.smpp.*;
import ie.omk.smpp.message.*;
import ie.omk.smpp.util.PacketFactory;
import java.util.*;
import com.lizongbo.smpp.server.handlers.*;
/**
*
*Title: java smsc server
*
*Description: smpp短消息中心
*
*Copyright: Copyright (c) 2007
*
*Company: http://618119.com
*
* @author lizongbo
* @version 1.0
*/
public class Main {
public static void main(String[] args) {
//以 spring配置方式启动
ApplicationContext context = new ClassPathXmlApplicationContext(
“classpath*:/springmina.xml”);
IoAcceptor acceptor = (IoAcceptor) context.getBean(”ioAcceptor”);
test(acceptor);
}
//普通方式启动
public static void commonmain(String[] args) throws IOException {
IoAcceptor acceptor = new SocketAcceptor();
IoAcceptorConfig config = new SocketAcceptorConfig();
DefaultIoFilterChainBuilder chain = config.getFilterChain();
chain.addLast(”logger”, new LoggingFilter());
chain.addLast(”codec”,
new ProtocolCodecFilter(new SMPPProtocolCodecFactory()));
chain.addLast(”threadpool”,
new org.apache.mina.filter.executor.ExecutorFilter());
InetSocketAddress serverAddr = new InetSocketAddress(5432);
SMPPServerSessionHandler handler = new SMPPServerSessionHandler();
Map<long> handles = new HashMap</long><long> ();
handles.put(Long.valueOf(0×00000002), new BindTransmitterHandler());
handles.put(Long.valueOf(0×00000001), new BindReceiverHandler());
handles.put(Long.valueOf(0×00000004), new SubmitSMHandler());
handles.put(Long.valueOf(0×00000006), new UnbindHandler());
handles.put(Long.valueOf(0×80000005), new DeliverSMRespHandler());
acceptor.bind(serverAddr, handler, config);
System.out.println(”Listening on port ” + 5432);
test(acceptor);
}</long>
private static void test(IoAcceptor acceptor) throws
InvalidParameterValueException {
try {
Thread.sleep(20000);
}
catch (InterruptedException ex) {
}
Set<iosession> ss = acceptor.getManagedSessions(new InetSocketAddress(5432));
System.out.println(”ss.size() == ” + ss.size());
if (ss.size() > 0) {
//模拟主动下发一条消息状态报告
DeliverSM rs = null;
try {
rs = (DeliverSM) PacketFactory.newInstance(SMPPPacket.DELIVER_SM);
}
catch (BadCommandIDException ex1) {
}
//这里还有很多字段没填,需要补上
rs.setSequenceNum(9999);
rs.setMessageId(”618119″);
rs.setServiceType(”aaa”);
rs.setSource(new Address(0, 0, “618119″));
rs.setDestination(new Address(0, 0, “10086″));
rs.setEsmClass(0);
rs.setProtocolID(0);
rs.setPriority(0);
rs.setRegistered(0);
rs.setReplaceIfPresent(0);
rs.setDataCoding(15);
rs.setDefaultMsg(1);
rs.setMessage(”succ”.getBytes());
System.out.println(”主动发回一个消息应答”);
ss.iterator().next().write(rs);
}
}</iosession>
}
spring 的xml配置文件:
- <?xml version=”1.0″ encoding=”UTF-8″?>
- <beans xmlns=”http://www.springframework.org/schema/beans/--escaped_anchor:e3d7b21df466d13b15e011f977f36957---beans-2.0.xsd
- http://www.springframework.org/schema/aop/--escaped_anchor:e3d7b21df466d13b15e011f977f36957---aop-2.0.xsd
- http://www.springframework.org/schema/util/--escaped_anchor:e3d7b21df466d13b15e011f977f36957---util-2.0.xsd “>
- <util:constant id=”ie.omk.smpp.message.SMPPPacket.BIND_TRANSMITTER”/>
- <bean id=”com.lizongbo.smpp.server.handlers.BindTransmitterHandler”/>
- <bean id=”com.lizongbo.smpp.server.handlers.BindReceiverHandler”/>
- <bean id=”com.lizongbo.smpp.server.handlers.SubmitSMHandler”/>
- <bean id=”com.lizongbo.smpp.server.handlers.UnbindHandler”/>
- <bean id=”com.lizongbo.smpp.server.handlers.DeliverSMRespHandler”/>
- <util:map id=”handlers” key-type=”java.lang.Long”>
- <!– Integer.decode(”0×80000005″)要出错,被迫用Long类型 –>
- <entry key=”0×00000002″>
- <ref local=”com.lizongbo.smpp.server.handlers.BindTransmitterHandler”/>
- </entry>
- <entry key=”0×00000001″>
- <ref local=”com.lizongbo.smpp.server.handlers.BindReceiverHandler”/>
- </entry>
- <entry key=”0×00000004″>
- <ref local=”com.lizongbo.smpp.server.handlers.SubmitSMHandler”/>
- </entry>
- <entry key=”0×00000006″>
- <ref local=”com.lizongbo.smpp.server.handlers.UnbindHandler”/>
- </entry>
- <entry key=”0×80000005″>
- <ref local=”com.lizongbo.smpp.server.handlers.DeliverSMRespHandler”/>
- </entry>
- </util:map>
- <bean class=”org.springframework.beans.factory.config.CustomEditorConfigurer”>
- <property name=”customEditors”>
- <map>
- <entry key=”java.net.SocketAddress”>
- <bean class=”org.apache.mina.integration.spring.InetSocketAddressEditor”/>
- </entry>
- </map>
- </property>
- </bean>
- <!– The IoHandler delegate implementation –>
- <bean id=”smppHandler” class=”com.lizongbo.smpp.server.SMPPServerSessionHandler”>
- <property name=”handles”>
- <ref local=”handlers”/>
- </property>
- <property name=”readerIdleTimeout”>
- <value>600</value>
- </property>
- </bean>
- <!– The protocol codec factory for smpp –>
- <bean id=”smppProtocolCodecFactory” class=”com.lizongbo.smpp.server.codec.SMPPProtocolCodecFactory”> </bean>
- <bean id=”smppFilterThreadPoolFactory” class=”org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean”>
- <property name=”corePoolSize” value=”10″/>
- <property name=”maxPoolSize” value=”100″/>
- <property name=”keepAliveSeconds” value=”30″/>
- </bean>
- <bean id=”smppFilterChainBuilder” class=”org.apache.mina.integration.spring.DefaultIoFilterChainBuilderFactoryBean”>
- <property name=”filters”>
- <list>
- <bean class=”org.apache.mina.filter.executor.ExecutorFilter”>
- <constructor-arg>
- <ref bean=”smppFilterThreadPoolFactory”/>
- </constructor-arg>
- </bean>
- <bean class=”org.apache.mina.filter.codec.ProtocolCodecFilter”>
- <constructor-arg ref=”smppProtocolCodecFactory”/>
- </bean>
- <bean class=”org.apache.mina.filter.LoggingFilter”/>
- </list>
- </property>
- <property name=”filterNamePrefix” value=”smppFilterPool”/>
- </bean>
- <bean id=”smppThreadModel” class=”org.apache.mina.integration.spring.ExecutorThreadModelFactoryBean”>
- <property name=”serviceName” value=”smppService”/>
- <property name=”executor”>
- <bean class=”org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean”>
- <property name=”corePoolSize” value=”6″/>
- <property name=”maxPoolSize” value=”10″/>
- <property name=”keepAliveSeconds” value=”30″/>
- </bean>
- </property>
- </bean>
- <bean id=”smppSocketAcceptorConfig” class=”org.apache.mina.transport.socket.nio.SocketAcceptorConfig”>
- <property name=”filterChainBuilder” ref=”smppFilterChainBuilder”/>
- <property name=”threadModel” ref=”smppThreadModel”/>
- <property name=”reuseAddress” value=”true”/>
- </bean>
- <bean id=”threadExecutor” class=”java.util.concurrent.Executors” factory-method=”newCachedThreadPool”/>
- <bean id=”ioAcceptor” class=”org.apache.mina.integration.spring.IoAcceptorFactoryBean”>
- <property name=”target”>
- <bean class=”org.apache.mina.transport.socket.nio.SocketAcceptor”>
- <constructor-arg index=”0″>
- <value>3</value>
- </constructor-arg>
- <constructor-arg index=”1″>
- <ref bean=”threadExecutor”/>
- </constructor-arg>
- </bean>
- </property>
- <property name=”bindings”>
- <list>
- <bean class=”org.apache.mina.integration.spring.Binding”>
- <property name=”address” value=”:5432″/>
- <property name=”handler” ref=”smppHandler”/>
- <property name=”serviceConfig” ref=”smppSocketAcceptorConfig”/>
- </bean>
- </list>
- </property>
- </bean>
- <!– SMSC BEANS –>
- <bean id=”smscFilterThreadPoolFactory” class=”org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean”>
- <property name=”corePoolSize” value=”10″/>
- <property name=”maxPoolSize” value=”100″/>
- <property name=”keepAliveSeconds” value=”30″/>
- </bean>
- <bean id=”smscFilterChainBuilder” class=”org.apache.mina.integration.spring.DefaultIoFilterChainBuilderFactoryBean”>
- <property name=”filters”>
- <list>
- <bean class=”org.apache.mina.filter.codec.ProtocolCodecFilter”>
- <constructor-arg ref=”smppProtocolCodecFactory”/>
- </bean>
- <bean class=”org.apache.mina.filter.executor.ExecutorFilter”>
- <constructor-arg>
- <ref bean=”smscFilterThreadPoolFactory”/>
- </constructor-arg>
- </bean>
- <bean class=”org.apache.mina.filter.LoggingFilter”/>
- </list>
- </property>
- <property name=”filterNamePrefix” value=”smscFilterPool”/>
- </bean>
- <bean id=”smscThreadModel” class=”org.apache.mina.integration.spring.ExecutorThreadModelFactoryBean”>
- <property name=”serviceName” value=”smscService”/>
- <property name=”executor”>
- <bean class=”org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean”>
- <property name=”corePoolSize” value=”6″/>
- <property name=”maxPoolSize” value=”10″/>
- <property name=”keepAliveSeconds” value=”30″/>
- </bean>
- </property>
- </bean>
- <bean id=”smscSocketConnectorConfig” class=”org.apache.mina.transport.socket.nio.SocketConnectorConfig”>
- <property name=”filterChainBuilder” ref=”smscFilterChainBuilder”/>
- <property name=”threadModel” ref=”smscThreadModel”/>
- </bean>
- </beans>