2. 建立连接池,线程池中线程从连接池获取一个连接将SOAP报文下发到网元上。
3. 其他线程:SOAP报文读取线程,将生成的SOAP报文文件映射到内存文件,每次读取1w条数据到SOAP报文下发队列,SOAP下发队列数据结构进行
封装,添加信号量,每次数据push_back一条信号量递增
SOAP报文下发线程,独立的线程从SOAP报文下发队列中取数据,等待下发队列的信号,如果有信号则从队列中取数据,构建下发任务
将下发任务压入线程池工作任务队列,同时信号量递减1
SOAP报文保存线程,SOAP报文下发后会收到网元的响应报文,解析模块分析响应报文,获取SOAP发送报文的执行结果,并将执行失败
的SOAP报文进行保存,对执行成功的报文写入日志。
4. 连接池:连接池工厂,连接池,连接器实体
连接池工厂建立连接池名称和连接池实例的映射,管理所有连接池。
连接池管理所有会话连接(IOSession),建立空闲会话队列和使用会话队列,如果空闲队列为空,同时又有新的连接请求,则建立一条新的连接。
连接数不能超过最大连接数,如果已经达到最大连接数,则进入等待状态,当空闲队列空状态取消
AttachHttpHeader() // 附加Http报头
DetachHttpHeader() // 获取Http响应报头
PraseHttpHeader() // 解析Http响应报头
http://www.cnpaf.net/Class/HTTP/200707/20984_2.html
队列采用状态模式,空闲状态
队列包含一个事件,类型转换 *** 作符到事件句柄,当空闲队列为空时,事件变为无信号状态,当变为非空时变为有信号状态。每次出现这种状况都要写日志信息。
加锁时要用自动锁,将锁包装在一个局部变量中,防止死锁的发生。
CMultiLock包装多个同步对象
CSingleLock包装单个同步对象
CSingleLock singleLock(&m_CritSection)// 包装一个临界区
singleLock.Lock() // 尝试给共享资源加锁
if (singleLock.IsLocked()) // 判断共享资源是否被锁住
{
// 开始使用共享资源
// 使用结束,释放共享资源使用权
singleLock.Unlock()
}
CXF本身应该有更方便的方式进行添加,去读读文档。我当时也遇到这个问题,时间太紧我没时间读文档,用了一个很笨很直接的办法:
我当时的场景:对方服务是用.net开发的,我用JAVA&CXF,他自己用.net很顺序地能调通,我用CXF就不行。
我的笨办法:
1、我搞到别人能调通的SOAP报文;
2、抓到我CXF调用发出的报文;
3、比较两者之不同;
4、然后自己在拦截器中把差的报文节点补齐;
5、搞定。(看起来复杂,其实没花多少时间)
代码虽然还一翻就找到了,附上希望给你一点思路。
public class HeaderIntercepter extends AbstractPhaseInterceptor<SoapMessage>{
public static final String xml_namespaceUR_att = "http://tempuri.org/"
public static final String xml_head_el = "RoadSoapHeader"
public static final String xml_userID_el = "UserID"
public static final String xml_password_el = "PassWord"
public static final String userId = ""
public static final String password= ""
public RoadHeaderIntercepter() {
super(Phase.WRITE)
}
/**
* @param message
* @throws Fault
* @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message)
*/
@Override
public void handleMessage(SoapMessage message) throws Fault {
QName qname = new QName(xml_head_el)
Document doc = DOMUtils.createDocument()
Element userIdElement = doc.createElement(xml_userID_el)
userIdElement.setTextContent(userId)
Element passwordElement = doc.createElement(xml_password_el)
passwordElement.setTextContent(password)
Element root = doc.createElementNS(xml_namespaceUR_att, xml_head_el)
root.appendChild(userIdElement)
root.appendChild(passwordElement)
//XMLUtils.printDOM(root)SoapHeader head = new SoapHeader(qname, root)
List<Header>headers = message.getHeaders()
headers.add(head)
}
}
<jaxws:client id="client"
serviceClass="xxx.RoadAskOutServiceSoap"
address="${address}/RoadAskOutService.asmx">
<jaxws:outInterceptors>
<bean class="xxx.HeaderIntercepter"></bean>
</jaxws:outInterceptors>
</jaxws:client>
易语言协议头的添加可以通过在代码中添加一些特殊的头部信息实现。一般的头部信息包括:版本号、消息类型、会话ID、消息序号和消息体长度等,其中版本号可以是当前最新版本号,消息类型可以根据消息的不同而定义不同的类型,会话ID可以由客户端分配,消息序号可以由客户端提供,消息体长度可以根据消息的长度来计算。这些头部信息的添加可以通过易语言的提供的一些函数进行添加,如ByteToStr、StrToByte等函数。另外,还可以通过自定义函数来添加协议头,通过对消息的解析和处理来实现,这样可以更灵活的处理消息中的不同类型。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)