Git Product home page Git Product logo

cloudhopper-smpp's Issues

How can I retrieve outbound queue full errors ?

Hello @jjlauer first of all thank you for maintaining this great library ๐Ÿ‘

I use the example with persistent connection and it works I can send sms to SMPPSim server.

But if I set the outbound queue size to 10.
Then SMPPSim server send back the following message to notify the smpp client that the outbound queue is full:
SUBMIT_SM_RESP (ESME_RMSGQFUL)

I would like to trigger a small break when this happend so the queue can get free and then I resend the wanted sms in a few minutes.

BUT: it seems my SmppSessionHandler do not get this information.
What method name should I override to handle such smpp message ?

I currently use firePduRequestReceived and I got this working for SmscDeliveryReceipt like a charm. But no way for the rest...

Thank you in advance for your help.

Question : SMPP message concatenation across multiple binds

We have developed an SMPP server based on CloudHopper SMPP library. The system is in production processing a considerable volume of messages everyday.
Customers are allowed to maintain multiple TX binds for a higher throughput and redundancy. Recently we identified that a few of our customers send segmented messages (message parts) over multiple binds. So we receive parts of a single SMS over different binds from the same customer and those are valid (in UDH, Having the same reference number, valid seq no etc). We support concatenation on a bind level, but not across multiple binds.

Is it a standard/good practise to support concatenation for parts sent over multiple binds? Message reference number in the UDH header for concatenated messages should be unique for all binds created by an SMPP gateway? Any thoughts on this are welcome

(http://stackoverflow.com/questions/43198297/smpp-message-concatenation-across-multiple-binds)

Correct way to configure a connection with 5 SMPP sessions (binds)

I cannot understand the comments in the examples and the code

Creates a new default SmppClient.
* @param workerGroup The max number of concurrent sessions expected
* to be active at any time. This number controls the max number of worker
* threads that the underlying Netty library will use. If processing
* occurs in a sessionHandler (a blocking op), be VERY careful
* setting this to the correct number of concurrent sessions you expect.

If I want to connect to a SMSC over 5 binds (smpp sessions) what I am doing is this:

   public void configure(MessageForwardingService  messageForwardingService,
		         MessageLoggingService messageLoggingService) {
	int sessionNum = connectionProperties.get(ConnectionConstants.OPERATOR_CONNECTION_SESSION_NUMBER, 0);

	final SmppClientMessageService smppClientMessageService = new CommXPSmppClientMessageService(operatorName,
			messageForwardingService, messageLoggingService, applicationEventPublisher);
	for (int i = 0; i < sessionNum; i++) {
		OutboundClient client = new OutboundClient(
				connectionProperties.get(ConnectionConstants.OPERATOR_CONNECTION_ENQUIRELINK_TIMER, 10000),
				connectionProperties.get(ConnectionConstants.OPERATOR_CONNECTION_ENQUIRELINK_TIMER, 30000));
		client.initialize(getSmppConnectionConfiguration(i), smppClientMessageService);
		balancedList.set(client, 1);
	}
}

 public OutboundClient(final Integer endquireLinkPeriod, Integer enquireLinkTimeout) {
	            this.enquireLinkPeriod = endquireLinkPeriod;
	           this.enquireLinkTimeout = enquireLinkTimeout;
	            this.enquireLinkExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() {

		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r);
			String name = config.getName();
			t.setName("EnquireLink-" + name);
			return t;
		}
	});

	monitorExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1, new ThreadFactory() {

		private AtomicInteger sequence = new AtomicInteger(0);

		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r);
			t.setName("SmppClientSessionWindowMonitorPool-" + sequence.getAndIncrement());
			return t;
		}
	});

	NioEventLoopGroup group = new NioEventLoopGroup(1);
	clientBootstrap = new DefaultSmppClient(group, monitorExecutor);
}

public void initialize(SmppSessionConfiguration config, SmppClientMessageService smppClientMessageService) {
	this.config = config;
	logger = LoggerFactory.getLogger(OutboundClient.class.getCanonicalName() + config.getName());
	//
	// setup configuration for a client session
	//
	sessionHandler = new ClientSmppSessionHandler(this, smppClientMessageService);
}`

Then I get each of the balancedList sessions and I submitMessages.
To my mind this is creating 5 different DefaultClients with 1 thread each. Somehow though this seems counter intuitive and I am not sure it is correct.

It works and I had great success submitting with over 200 TPS but I am worried since I started facing an issue with very heavy load for incoming messages. Is the problem related to using the sessions incorrectly or should I look elsewhere for the issue?

I know that opening an issue might not be ideal but given the limited documentation I have found on cloudhopper I thought this could be a good opportunity to add some explanation to the code samples.

Adding user control of the local bind address?

We're using DefaultSmppClient to bind to SMSCs. However, we also need to specify the local interface used when creating a session. The Netty bootstrap client used for creating a channel to the remote host has the option to use a specific local address, if one is provided, but this cannot be used currently because clientBootstrap is a private member of DefaultSmppClient.

Would it be possible for you to provide a way for users to set the local bind addresses, in addition to the remote host?

Thanks.

Cloudhopper SMPP Error codes

As part of PDU parameter validation, the current implementation of library is not able to distinguish and throw error codes based on SMPP Standards and instead throws exception . How do we manage to throw error codes described by SMPP Standards

Square Brackets is not Working

Hi,
When a sms text containing [][][][][] (More than 1 open & Close Square bracket), the message content is getting trimmed and getting only [].

SMPP Proxy/Load balancer

We are looking at a high throughput based SMPP Proxy/Load balancer that ESMEs can connect to and requests can be relayed to multiple SMPP Servers running underneath. Is it possible to achieve this via cloudhopper-smpp. This is not an issue but trying to find out ways to do the same

Bug: network_error_code is an octet string which might as a string might have more than 3 characters

In DeliveryReceipt, the value of a network_error_code is regarded invalid if it has more than 3 characters when converted to a string. However, the SMPP protocol allows more than 3 characters: the actual requirement is that we have an octet string of size three. When converted to a string, we might have more than three characters: eg, 0423 0003 0308 0200 is a valid hex network_error_code TLV, which will give err:2050, and a DeliveryReceiptException is thrown.

I don't see a straightforward way to fix this, because the DeliveryReceipt class is based upon parsing a string.

.NET Port

Any .NET Port of cloudhopper-smpp?

Split library into modules; extract bindings for netty3, netty4, etc.

This library was originally created when Netty was a young project. Netty-4 introduced so many backwards compat issues, that its almost an entirely new library in some ways. While we even had Netty's main author (Trustin) help port ch-smpp from netty-3 to netty-4, Twitter's applications still use the netty-3 branch.

Maintaining this project with two branches is cumbersome. Plus, there are possibly good uses of ch-smpp with different pluggable network bindings -- e.g. blocking I/O, xnio from jboss, netty-3, and netty-4.

The idea would be to split up ch-smpp into modules. Something like core, netty3, and netty4 for now. There already are interfaces in the library with implementations. Users of the library would simply pull in ch-smpp-core and pick the network layer bindings they wanted. All unit tests should verify each different binding works. I'm guessing the easiest method would be to add a 4th module called "tests", and possibly use JUnit parameterized runners to verify each binding passes the same tests.

Anyone from the community looking to take on this pretty extensive project?

Writing data on closed socket causes unnecessary exception in Netty

public class DefaultSmppSession ...

public void sendResponsePdu(PduResponse pdu) throws RecoverablePduException, UnrecoverablePduException, SmppChannelException, InterruptedException {
...
        // write the pdu out & wait timeout amount of time
        ChannelFuture channelFuture = this.channel.writeAndFlush(buffer);
        if(configuration.getWriteTimeout() > 0){
            channelFuture.await(configuration.getWriteTimeout());
        } else {
            channelFuture.await();
        }

Line 518-523 in master branch at October 4, 2017

By adding a simple test before writing to the socket, the long exception will be avoided
For example add the following code just before:

        if (!this.channel.isOpen()) {
            logger.info("Channel closed.");
            return;
        }

Exception

2017-10-03 12:52:49.809 ERROR 16945 --- [cation.SMPP.csn] c.c.smpp.impl.DefaultSmppSession         : Unable to cleanly return response PDU: {}

com.cloudhopper.smpp.type.SmppChannelException: null
	at com.cloudhopper.smpp.impl.DefaultSmppSession.sendResponsePdu(DefaultSmppSession.java:573) ~[ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at com.cloudhopper.smpp.impl.DefaultSmppSession.firePduReceived(DefaultSmppSession.java:606) ~[ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at com.cloudhopper.smpp.channel.SmppSessionWrapper.channelRead0(SmppSessionWrapper.java:48) [ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at com.cloudhopper.smpp.channel.SmppSessionWrapper.channelRead0(SmppSessionWrapper.java:36) [ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at com.cloudhopper.smpp.channel.SmppSessionLogger.channelRead(SmppSessionLogger.java:104) [ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at com.cloudhopper.smpp.channel.SmppSessionThreadRenamer.channelRead(SmppSessionThreadRenamer.java:89) [ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at com.cloudhopper.smpp.channel.LoggingChannelInboundHandlerAdapter.channelRead(LoggingChannelInboundHandlerAdapter.java:94) [ch-smpp-6.0.0-netty4-beta-3.jar!/:6.0.0-netty4-beta-3]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:527) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:481) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) [netty-all-4.1.7.Final.jar!/:4.1.7.Final]
	at java.lang.Thread.run(java.base@9-internal/Thread.java:804) [na:na]
Caused by: java.nio.channels.ClosedChannelException: null
	at io.netty.channel.AbstractChannel$AbstractUnsafe.write(...)(Unknown Source) ~[netty-all-4.1.7.Final.jar!/:4.1.7.Final]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.