- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个项目使用 Cloudhopper 5.0.6 库来保持 SMPP 连接(3.4 版本)并发送或接收 PDU。我需要修改默认 PDUResopnse,因此,自定义 PDU 处理是通过以下方式扩展 DefaultSmppSessionHandler 来组织的:
public class SmppSessionHandlerController extends DefaultSmppSessionHandler {
@Override
public PduResponse firePduRequestReceived(PduRequest pduRequest) {
PduRequestHandler pduReqHandler = pduRequestHandler;
PduResponse resultPduResponse = pduRequest.createResponse();
return processDefaultPduResponse(resultPduResponse);
}
private PduResponse processDefaultPduResponse(PduResponse pduResponse) {
//do some transformations here on pduResponse...
return pduResponse;
}
}
它仅适用于以下目的:
现在我需要添加延迟的 PDU 响应发送,问题就在这里开始了。我的第一次尝试是这样的:
@Override
public PduResponse firePduRequestReceived(PduRequest pduRequest) {
PduRequestHandler pduReqHandler = pduRequestHandler;
PduResponse resultPduResponse = pduRequest.createResponse();
return processDefaultPduResponse(resultPduResponse);
}
private PduResponse processDefaultPduResponse(PduResponse pduResponse) {
try {
Thread.sleep(responseDelay);
} catch (InterruptedException e) {
throw new RuntimeException("Response delay interrupted", e);
}
return pduResponse;
}
添加了当前线程的 hibernate 以延迟发送响应,因此调用线程被保留 responseDelay 毫秒。如果此 session 没有同时发出更多请求,则此方法可以正常工作。在同一 session 中添加一些 submit_sm 负载导致错误:
com.cloudhopper.smpp.type.SmppTimeoutException: Unable to get response within [10000 ms]
at com.cloudhopper.smpp.impl.DefaultSmppSession.sendRequestAndGetResponse(DefaultSmppSession.java:471) ~[ch-smpp-5.0.6.jar:5.0.6]
at com.cloudhopper.smpp.impl.DefaultSmppSession.enquireLink(DefaultSmppSession.java:439) ~[ch-smpp-5.0.6.jar:5.0.6]
在 coudhopper 源中搜索后我发现了问题,它是 DefaultSmppSession 类中任何操作的独占窗口锁定:
future = sendWindow.offer(pdu.getSequenceNumber(), pdu, timeoutMillis, configuration.getRequestExpiryTimeout(), synchronous);
问题出在 com.cloudhopper.commons.util.windowing.Window 类中,该类使用独占锁来执行任何操作,因此不可能在一个线程中返回 PRUResponse 并发出请求之前等待来自另一个。
接下来的尝试是返回 null 作为请求处理(丢弃请求而不发送任何响应)并使用 com.cloudhopper.smpp.SmppSession.sendResponsePdu(pduResponse) 方法。这种方法工作了一段时间,但总是以以下异常结束:
com.cloudhopper.smpp.type.SmppChannelException: null
at com.cloudhopper.smpp.impl.DefaultSmppSession.sendResponsePdu(DefaultSmppSession.java:581) ~[ch-smpp-5.0.6.jar:5.0.6]
at com.svzn.autotest.smppclient.impl.cloudhopper.SmppSendingManager.sendPduResponse(SmppSendingManager.java:84) ~[smpp-client-1.0.1.jar:na]
at com.svzn.autotest.smppclient.impl.cloudhopper.util.SendPduCommand.sendPduResponse(SendPduCommand.java:80) [smpp-client-1.0.1.jar:na]
at com.svzn.autotest.smppclient.impl.cloudhopper.SmppClientImpl.sendPduResponse(SmppClientImpl.java:91) [smpp-client-1.0.1.jar:na]
at com.svzn.autotest.example.testng_aggr.lib.smpp.event.BaseEventProcessor$1.run(BaseEventProcessor.java:62) [test-classes/:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) [na:1.6.0_37]
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) [na:1.6.0_37]
at java.util.concurrent.FutureTask.run(FutureTask.java:138) [na:1.6.0_37]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98) [na:1.6.0_37]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206) [na:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_37]
at java.lang.Thread.run(Thread.java:662) [na:1.6.0_37]
Caused by: org.jboss.netty.handler.timeout.WriteTimeoutException: null
at org.jboss.netty.handler.timeout.WriteTimeoutHandler.<clinit>(WriteTimeoutHandler.java:79) ~[netty-3.9.0.Final.jar:na]
at com.cloudhopper.smpp.impl.DefaultSmppClient.createSession(DefaultSmppClient.java:259) ~[ch-smpp-5.0.6.jar:5.0.6]
at com.cloudhopper.smpp.impl.DefaultSmppClient.doOpen(DefaultSmppClient.java:226) ~[ch-smpp-5.0.6.jar:5.0.6]
at com.cloudhopper.smpp.impl.DefaultSmppClient.bind(DefaultSmppClient.java:193) ~[ch-smpp-5.0.6.jar:5.0.6]
at com.svzn.autotest.smppclient.impl.cloudhopper.tasks.RebindTask.run(RebindTask.java:37) ~[smpp-client-1.0.1.jar:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) [na:1.6.0_37]
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) [na:1.6.0_37]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) [na:1.6.0_37]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) [na:1.6.0_37]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180) [na:1.6.0_37]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoo
lExecutor.java:204) [na:1.6.0_37
]
... 3 common frames omitted
不知道如何修复此错误或以其他方式在同一 session 中发送异步 PDUResponse。你对此有什么想法吗?
最佳答案
终于找到问题了。问题出在不正确的同步块(synchronized block)中,它以通常的方式阻止了并行异步事件处理(发送 pdu 响应)以及处理请求和响应而没有处理。
完全可以调用com.cloudhopper.smpp.SmppSession.sendResponsePdu(pduResponse)一个线程中的方法,并通过从另一个线程扩展 DefaultSmppSessionHandler 来处理请求和响应。一切都将在同一个 session 中处理。
更新:这是我用来处理 pdu 请求的实现:
public class SmppSessionHandlerController extends DefaultSmppSessionHandler {
private static final Logger log = LoggerFactory.getLogger(SmppSessionHandlerController.class);
private volatile PduHandler pduHandler;
private PduResponseHandler pduResponseHandler;
private PduRequestHandler pduRequestHandler;
public SmppSessionHandlerController() {
super(log);
}
public PduHandler getPduHandler() {
return pduHandler;
}
public void setPduHandler(PduHandler pduHandler) {
this.pduHandler = pduHandler;
}
public PduResponseHandler getPduResponseHandler() {
return pduResponseHandler;
}
public void setPduResponseHandler(PduResponseHandler pduResponseHandler) {
this.pduResponseHandler = pduResponseHandler;
}
public PduRequestHandler getPduRequestHandler() {
return pduRequestHandler;
}
public void setPduRequestHandler(PduRequestHandler pduRequestHandler) {
this.pduRequestHandler = pduRequestHandler;
}
@Override
public void fireExpectedPduResponseReceived(PduAsyncResponse pduAsyncResponse) {
log.trace("Handling response PDU: {}", pduAsyncResponse);
pduAsyncResponse.getResponse().setReferenceObject(pduAsyncResponse.getRequest().getReferenceObject());
processPduResponse(pduAsyncResponse.getResponse());
}
@Override
public void fireUnexpectedPduResponseReceived(PduResponse pduResponse) {
log.warn("Handling unexpected response PDU: {}", pduResponse);
processPduResponse(pduResponse);
}
@Override
public boolean firePduReceived(Pdu pdu) {
PduHandler currPduHandler = pduHandler;
if (currPduHandler != null) {
SmppPdu smppPdu = PduToApiConverter.convertToApiObject(pdu);
currPduHandler.handlePduReceived(smppPdu);
}
// default handling is to accept pdu for processing up chain
return true;
}
public void firePduRequestExpired(PduRequest pduRequest) {
super.firePduRequestExpired(pduRequest);
}
private void processPduResponse(PduResponse pduResponse) {
HandlersContextHelper referenceObj = (HandlersContextHelper) pduResponse.getReferenceObject();
if (referenceObj != null) {
referenceObj.getSequenceIdHolder().addReceivedSequenceId(pduResponse.getSequenceNumber());
}
PduResponseHandler pduRespHandler = pduResponseHandler;
if (pduRespHandler != null) {
SmppPduResponse smppPduResponse = PduToApiConverter.convertToApiResponse(pduResponse);
if (smppPduResponse != null) {
pduRespHandler.handlePduResponse(smppPduResponse);
}
}
if (referenceObj != null) {
referenceObj.getSequenceIdHolder().checkSentAndReceivedClosed();
}
}
@Override
public PduResponse firePduRequestReceived(PduRequest pduRequest) {
PduRequestHandler pduReqHandler = pduRequestHandler;
PduResponse resultPduResponse = pduRequest.createResponse();
if (pduReqHandler == null) {
return resultPduResponse;
}
PduResponse defaultPduResponse = pduRequest.createResponse();
SmppPduRequest smppPduRequest = PduToApiConverter.convertToApiRequest(pduRequest);
SmppPduResponse defaultSmppPduResponse = PduToApiConverter.convertToApiResponse(defaultPduResponse);
if (smppPduRequest == null || defaultSmppPduResponse == null) {
return resultPduResponse;
}
SmppPduResponse resultSmppPduResponse = pduReqHandler.handlePduRequest(smppPduRequest, defaultSmppPduResponse);
if (resultSmppPduResponse == null) {
return null;
}
PduResponse convertedPduResponse = ApiToPduConverter.convertToPduResponse(resultSmppPduResponse);
if (convertedPduResponse == null) {
return resultPduResponse;
}
if (!resultPduResponse.getClass().isAssignableFrom(convertedPduResponse.getClass())) {
return resultPduResponse;
}
return convertedPduResponse;
}
}
Wich 是这样添加到 clowdhopper smpp 客户端的
SmppSession session = smppClient.bind(SmppSessionConfiguration_instance, SmppSessionHandlerController_instance );
我为 PduHandler PduRequestHandler 和 PduResponseHandler 定义了自定义接口(interface),它们处理 smpp 事件的特殊情况,您可以看到 SmppSessionHandlerController 只是将调用委托(delegate)给其中之一。
使用方法
public PduResponse firePduRequestReceived(PduRequest pduRequest)
defiend 在 SmppSessionHandler 中,您可以在同步模式下发送您想要的任何响应。如果您想在异步模式下执行此操作,请返回 null pduResponse 并使用 SmppSession.sendResponsePdu(Pdu) 而不是当前或任何其他线程。
关于java - 使用 cloudhopper 发送异步 PDU 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24702356/
我已经通过此链接从 github 下载了源代码:https://github.com/twitter/cloudhopper-smpp然而,当我尝试在 Netbeans 中构建它时,我收到两个错误,如
我正在尝试使用 CloudHopper lib 使用 SMPP 发送阿拉伯短信,但我遇到了字符出现的问题 (??????) msg = "\u0627\u062E\u062A\u063
我已经通过这个链接从 github 下载了源代码:https://github.com/twitter/cloudhopper-smpp 假设我想测试在客户端之间接收消息,所以我创建了一个服务器和 2
我有CloudHopper SMPP服务器,此时我可以收到一条简单的短信。 if (pduRequest.getCommandId() == SmppConstants.CMD_ID_SUBMIT_S
我正在尝试在使用 SMPP 协议(protocol)的 viva 网络上检索我的剩余信用额度我已经使用云漏斗实现来发送短信,但我无法检索我的剩余余额详细信息:请需要您的帮助 最佳答案 SMPP协议(p
我有 SMPP 服务器,使用 CloudHoper。当我收到消息时,我应该返回一份递送报告。请告诉我,我该怎么做? 此时我返回SubmitSmResp... 最佳答案 当然,您仍然需要像现在一样使用
我有一个项目使用 Cloudhopper 5.0.6 库来保持 SMPP 连接(3.4 版本)并发送或接收 PDU。我需要修改默认 PDUResopnse,因此,自定义 PDU 处理是通过以下方式扩展
如何使用Twitter cloudhopper? 我获取了源代码并尝试将演示代码作为 Java 应用程序运行,但我不知道如何测试它。 有没有cloudhopper的教程? 最佳答案 这个库的实现利用非
我正在寻找一种将 SMPP 错误代码从服务器发送到连接的客户端的方法。我的流程是:1.客户端发送短信到我的服务器2.我将其发送到另一个系统3.当我收到消息状态时(最多可能需要 72 小时)我想将结果发
我是一名优秀的程序员,十分优秀!