Basic Server Example
A complete example of an SMPP server that accepts messages and logs them.
Full Example
package io.smppgateway.example;
import io.smppgateway.smpp.server.SmppServer;
import io.smppgateway.smpp.server.SmppServerHandler;
import io.smppgateway.smpp.server.SmppServerSession;
import io.smppgateway.smpp.pdu.*;
import io.smppgateway.smpp.types.CommandStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
public class BasicServer {
private static final Logger log = LoggerFactory.getLogger(BasicServer.class);
public static void main(String[] args) throws Exception {
SmppServer server = SmppServer.builder()
.port(2775)
.systemId("example-smsc")
.maxConnections(100)
.windowSize(50)
.requestTimeout(Duration.ofSeconds(30))
.handler(new ExampleHandler())
.build();
server.start();
log.info("SMPP Server started on port 2775");
// Graceful shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
log.info("Shutting down...");
server.stop();
server.destroy();
}));
// Keep running
Thread.currentThread().join();
}
}
class ExampleHandler implements SmppServerHandler {
private static final Logger log = LoggerFactory.getLogger(ExampleHandler.class);
// Simple credential store
private static final ConcurrentHashMap<String, String> credentials = new ConcurrentHashMap<>();
static {
credentials.put("testuser", "password123");
credentials.put("esme1", "secret456");
}
// Message ID generator
private final AtomicLong messageIdCounter = new AtomicLong(1);
@Override
public BindResult authenticate(SmppServerSession session,
String systemId,
String password,
PduRequest<?> bindRequest) {
log.info("Bind request from {} (system_id: {})",
session.getRemoteAddress(), systemId);
String expectedPassword = credentials.get(systemId);
if (expectedPassword == null) {
log.warn("Unknown system_id: {}", systemId);
return BindResult.failure(CommandStatus.ESME_RINVSYSID);
}
if (!expectedPassword.equals(password)) {
log.warn("Invalid password for system_id: {}", systemId);
return BindResult.failure(CommandStatus.ESME_RINVPASWD);
}
log.info("Authentication successful for: {}", systemId);
return BindResult.success();
}
@Override
public SubmitSmResult handleSubmitSm(SmppServerSession session,
SubmitSm submitSm) {
String messageId = String.format("%016X", messageIdCounter.getAndIncrement());
log.info("SubmitSm received:");
log.info(" From: {}", submitSm.sourceAddress().address());
log.info(" To: {}", submitSm.destAddress().address());
log.info(" Message: {}", new String(submitSm.shortMessage()));
log.info(" Message ID: {}", messageId);
return SubmitSmResult.success(messageId);
}
@Override
public void sessionCreated(SmppServerSession session) {
log.info("Session created: {} from {}",
session.getSessionId(), session.getRemoteAddress());
}
@Override
public void sessionBound(SmppServerSession session) {
log.info("Session bound: {} as {} ({})",
session.getSessionId(),
session.getSystemId(),
session.getBindType());
}
@Override
public void sessionDestroyed(SmppServerSession session) {
log.info("Session destroyed: {}", session.getSessionId());
}
}