当前位置: 首页>后端>正文

QuickFix

QuickFixJ

时区不对问题

现象

客户端如果不设置时区TimeZone.setDefault(TimeZone.getTimeZone(ZoneOffset.UTC));服务端就无法接收消息

问题原因

客户端在重写Application#toApp/Application#toAdmin时主动修改了SendingTime字段:message.getHeader().setField(new SendingTime(LocalDateTime.now()));。而服务端接并没有设置时区,默认就是UTC时区。也就是说客户端如果不设置UTC时区,发出的时间是北京时间9点,服务端收到后,当前时间是UTC时间1点,然后判断消息是否过期时发现这个消息不应该处理,就没有进行处理。

解决办法

发送时不要改SendingTime,因为quickfix.Session#insertSendingTime会插入一个当前时间对应的UTC时间,服务端也是UTC时间的话,正好能对应上。

原理

服务端逻辑:

# 入异步队列
put:332, LinkedBlockingQueue (java.util.concurrent)
put:40, QueueTrackers (quickfix.mina)
enqueue:203, ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread (quickfix.mina)
onMessage:82, ThreadPerSessionEventHandlingStrategy (quickfix.mina)
processMessage:111, AcceptorIoHandler (quickfix.mina.acceptor)
messageReceived:136, AbstractIoHandler (quickfix.mina)
messageReceived:997, DefaultIoFilterChain$TailFilter (org.apache.mina.core.filterchain)
callNextMessageReceived:641, DefaultIoFilterChain (org.apache.mina.core.filterchain)
access00:48, DefaultIoFilterChain (org.apache.mina.core.filterchain)
messageReceived:1114, DefaultIoFilterChain$EntryImpl (org.apache.mina.core.filterchain)
flush:437, ProtocolCodecFilter$ProtocolDecoderOutputImpl (org.apache.mina.filter.codec)
messageReceived:256, ProtocolCodecFilter (org.apache.mina.filter.codec)
callNextMessageReceived:641, DefaultIoFilterChain (org.apache.mina.core.filterchain)
access00:48, DefaultIoFilterChain (org.apache.mina.core.filterchain)
messageReceived:1114, DefaultIoFilterChain$EntryImpl (org.apache.mina.core.filterchain)
messageReceived:121, IoFilterAdapter (org.apache.mina.core.filterchain)
callNextMessageReceived:641, DefaultIoFilterChain (org.apache.mina.core.filterchain)
fireMessageReceived:634, DefaultIoFilterChain (org.apache.mina.core.filterchain)
# Channel#read
read:539, AbstractPollingIoProcessor (org.apache.mina.core.polling)
access00:68, AbstractPollingIoProcessor (org.apache.mina.core.polling)
process:1242, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
process:1231, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
# nio select
run:683, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
run:64, NamePreservingRunnable (org.apache.mina.util)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)




有效SendingTime校验,默认120s内
isGoodTime:1834, Session (quickfix)
verify:1743, Session (quickfix)
nextLogon:2129, Session (quickfix)
next:1026, Session (quickfix)
next:1204, Session (quickfix)
doRun:222, ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread (quickfix.mina)
run:146, ThreadPerSessionEventHandlingStrategy$ThreadAdapter (quickfix.mina)
run:748, Thread (java.lang)

延伸

客户端、服务端时间相差太大,应该也会导致消息不被处理。

客户端发中文服务端收不到

现象

客户端发送英文服务端能收到,发送中文就收不到。

问题原因

客户端默认采用ISO-8895-1编码,需要修改成UTF-8。客户端checksum与服务端算的checksum不一致。
在server端的event.log日志里可以看到:

20230817-09:47:11: Invalid message: Expected CheckSum=89, Received CheckSum=184 in 8=FIX.4.4?9=83?35=0?34=2?49=client-company-001?50=019782?52=20230817-09:47:11.088?56=Heads?112=?10=184?

解决办法

客户端和服务端都全局调用CharsetSupport.setCharset("UTF_8");,或者在Application#onCreate时调用。

原理

# 消息放入异步队列
offer:327, ConcurrentLinkedQueue (java.util.concurrent)
offer:226, DefaultIoSessionDataStructureFactory$DefaultWriteRequestQueue (org.apache.mina.core.session)
write:433, AbstractPollingIoProcessor (org.apache.mina.core.polling)
write:68, AbstractPollingIoProcessor (org.apache.mina.core.polling)
write:278, SimpleIoProcessorPool (org.apache.mina.core.service)
write:80, SimpleIoProcessorPool (org.apache.mina.core.service)
filterWrite:895, DefaultIoFilterChain$HeadFilter (org.apache.mina.core.filterchain)
callPreviousFilterWrite:744, DefaultIoFilterChain (org.apache.mina.core.filterchain)
access00:48, DefaultIoFilterChain (org.apache.mina.core.filterchain)
filterWrite:1132, DefaultIoFilterChain$EntryImpl (org.apache.mina.core.filterchain)
# 调用DemuxingProtocolEncoder#encode -> FIXMessageEncoder#encode将字符串转成bytes
# 编码由CharsetSupport#getCharset提供,默认ISO-8859-1
# 想修改需要CharsetSupport.setCharset(StandardCharsets.UTF_8.name());
# 可以考虑在onCreate处调用,或者全局调用一次
filterWrite:345, ProtocolCodecFilter (org.apache.mina.filter.codec)
callPreviousFilterWrite:744, DefaultIoFilterChain (org.apache.mina.core.filterchain)
access00:48, DefaultIoFilterChain (org.apache.mina.core.filterchain)
filterWrite:1132, DefaultIoFilterChain$EntryImpl (org.apache.mina.core.filterchain)
filterWrite:1020, DefaultIoFilterChain$TailFilter (org.apache.mina.core.filterchain)
callPreviousFilterWrite:744, DefaultIoFilterChain (org.apache.mina.core.filterchain)
# 责任链
fireFilterWrite:737, DefaultIoFilterChain (org.apache.mina.core.filterchain)
# 这里还会检查Channel连通性
write:570, AbstractIoSession (org.apache.mina.core.session)
write:515, AbstractIoSession (org.apache.mina.core.session)
# 异步写到mina
send:63, IoSessionResponder (quickfix.mina)
# 输出outgoing日志
send:2661, Session (quickfix)
# 插入header字段,调用Application#toAdmin、Application#toApp
# 登陆成功了才能调用send
sendRaw:2590, Session (quickfix)
send:2648, Session (quickfix)
sendToTarget:681, Session (quickfix)
# 获取异步队列数据并write buffer
flushNow:997, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
flush:921, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
run:688, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
run:64, NamePreservingRunnable (org.apache.mina.util)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)

服务端解码:

getMessageString:250, FIXMessageDecoder (quickfix.mina.message)
parseMessage:221, FIXMessageDecoder (quickfix.mina.message)
decode:105, FIXMessageDecoder (quickfix.mina.message)
doDecode:199, DemuxingProtocolDecoder (org.apache.mina.filter.codec.demux)
decode:180, CumulativeProtocolDecoder (org.apache.mina.filter.codec)
messageReceived:253, ProtocolCodecFilter (org.apache.mina.filter.codec)
callNextMessageReceived:641, DefaultIoFilterChain (org.apache.mina.core.filterchain)
access00:48, DefaultIoFilterChain (org.apache.mina.core.filterchain)
messageReceived:1114, DefaultIoFilterChain$EntryImpl (org.apache.mina.core.filterchain)
messageReceived:121, IoFilterAdapter (org.apache.mina.core.filterchain)
callNextMessageReceived:641, DefaultIoFilterChain (org.apache.mina.core.filterchain)
fireMessageReceived:634, DefaultIoFilterChain (org.apache.mina.core.filterchain)
read:539, AbstractPollingIoProcessor (org.apache.mina.core.polling)
access00:68, AbstractPollingIoProcessor (org.apache.mina.core.polling)
process:1242, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
process:1231, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
run:683, AbstractPollingIoProcessor$Processor (org.apache.mina.core.polling)
run:64, NamePreservingRunnable (org.apache.mina.util)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)

https://www.xamrdz.com/backend/3p41937957.html

相关文章: