1. Californium ÏîÄ¿¼ò½é
Californium ÊÇÒ»¿î»ùÓÚJavaʵÏÖµÄCoap¼¼Êõ¿ò¼Ü£¬¸ÃÏîĿʵÏÖÁËCoapÐÒéµÄ¸÷ÖÖÇëÇóÏìÓ¦¶¨Ò壬֧³ÖCON/NON²»Í¬µÄ¿É¿¿ÐÔ´«Êäģʽ¡£
Californium »ùÓÚ·Ö²ãÉè¼ÆÇҸ߶ȿÉÀ©Õ¹£¬ÆäÄÚ²¿Ä£¿éÉè¼Æ¼°½Ó¿Ú¶¨Òå´æÔÚÐí¶àѧϰ֮´¦£»
ÖµµÃÒ»ÌáµÄÊÇ£¬ÔÚͬÀàÐ굀 Coap¼¼ÊõʵÏÖÖУ¬CaliforniumµÄÐÔÄܱíÏÖÊDZȽÏÍ»³öµÄ£¬ÈçÏÂͼ£º

¸ü¶àµÄÊý¾Ý¿ÉÒԲο¼Californium-¿ÉÀ©Õ¹ÔÆ·þÎñ°×ƤÊé
±¾ÎÄÒÔ¿ò¼ÜµÄÔ´Âë·ÖÎöΪÖ÷£¬ÆäËûÄÚÈݲ»×öÕ¹¿ª¡£
2. ÏîÄ¿½á¹¹
ĿǰCalifornium ÏîÄ¿Îȶ¨°æ±¾Îª 2.0.0-M2£¬ÏîÄ¿µÄÍйܵØÖ·ÔÚ£º
https://github.com/eclipse/californium
Ä£¿é˵Ã÷
~.californium-core
californium ºËÐÄÄ£¿é£¬¶¨ÒåÁËһϵÁÐÐÒéÕ»ºËÐĽӿڣ¬²¢ÌṩÁËCoapÐÒéÕ»µÄÍêÕûʵÏÖ£¬
~.element-connector
´ÓcoreÄ£¿é°þÀëµÄÁ¬½ÓÆ÷Ä£¿é£¬ÓÃÓÚ³éÏóÍøÂç´«Êä²ãµÄ½Ó¿Ú£¬Ê¹µÃcoap¿ÉÒÔͬʱÔËÐÐÓÚudpºÍtcp¶àÖÖ´«ÊäÐÒéÖ®ÉÏ£»
~.scandium-core
Coap over DTLS Ö§³ÖÄ£¿é£¬ÌṩÁËDTLS ´«ÊäµÄConnectorʵÏÖ£»
~.californium-osgi
californium µÄosgi ·â×°Ä£¿é£»
~.californium-proxy
coap ´úÀíÄ£¿é£¬ÓÃÓÚÖ§³Öcoap2coap¡¢coap2http¡¢http2coapµÄת»»£»
~.demo-xxx
ÑùÀý³ÌÐò£»
ÆäÖУ¬californium-coreºÍelement-connectorÊÇcoap¼¼ÊõʵÏÖ×î¹Ø¼üµÄÄ£¿é£¬ºóÃæµÄ·ÖÎö½«Î§ÈÆÕâÁ½¸öÄ£¿é½øÐС£
3. ·Ö²ãÉè¼Æ

Californiium ¶¨ÒåÁËÈý²ã¼Ü¹¹£º
1 ÍøÂç²ã£¬¸ºÔð´¦Àí¶Ë¿Ú¼àÌý£¬ÍøÂçÊý¾ÝÊÕ·¢£»
2 ÐÒé²ã£¬¸ºÔðCoapÐÒéÊý¾Ý°ü½âÎö¼°·â×°£¬ÊµÏÖÏûÏ¢µÄ·ÓÉ¡¢¿É¿¿ÐÔ´«Êä¡¢Token´¦Àí¡¢¹Û²ìÕßÄ£Ð͵ȵȣ»
3 Âß¼²ã£¬¸ºÔð Resource¶¨ÒåºÍÓ³É䣬һ¸öResource ¶ÔÓ¦Ò»¸öURL£¬¿É¶ÀÁ¢ÊµÏÖCoap ÇëÇó´¦Àí¡£
Òì²½Ï̳߳Ø
Èý²ã¼Ü¹¹Öж¼¿ÉÒÔÖ§³Ö¶ÀÁ¢µÄÏ̳߳أ¬ÆäÖÐÍøÂç²ãÓëÐÒé²ãµÄÏ̳߳ر£³Ö¶ÀÁ¢£»
Âß¼²ã¿ÉΪÿ¸öResourceÖ¸¶¨¶ÀÁ¢µÄÏ̳߳أ¬²¢Ö§³Ö¸¸¼¶¼Ì³ÐµÄ»úÖÆ£¬¼´µ±Ç°ResourceÈôûÓж¨ÒåÔòÑØÓø¸¼¶ResourceÏ̳߳أ»
ÈôÂß¼²ãδָ¶¨Ï̳߳أ¬ÔòĬÈÏʹÓÃÐÒé²ãµÄÏ̳߳ء£
4. °ü½á¹¹·ÖÎö
4.1 californium-core

core Ä£¿é¶¨ÒåÁËÐÒéÕ»Ïà¹ØµÄËùÓйؼü½Ó¿Ú£¬¸ù¾Ý¹¦ÄÜÖ°ÔðµÄ²»Í¬²ð·ÖΪ¶à¸ö×Ó package£»
¸ù¼¶ package¶¨ÒåµÄÊÇCoapÓ¦ÓõÄһЩÈë¿ÚÀ࣬ÈçClient/ServerʵÏÖ¡¢°üÀ¨Ó¦ÓòãCoapResourceµÄ¶¨Òå¡£
4.1.1 package-coap
ʵÏÖ coapÐÒé RFC7252 ʵÌ嶨Ò壬°üÀ¨ÏûÏ¢ÀàÐÍ¡¢ÏûϢͷ¡¢Observe»úÖÆµÈ¡£
¾ßÌ嶨Òå¼ûÏÂͼ

Coap ÏûÏ¢»®·ÖΪRequest/Response/EmptyMessage ÈýÀࣻ
MessageObserver ½Ó¿ÚÓÃÓÚʵÏÖÏûÏ¢µÄ״̬¸ú×Ù£¬ÈçÖØ´«¡¢È·Èϵȡ£
4.1.2 package-network
network ÊÇÐÒéÕ»ºËÐÄ»úÖÆÊµÏֵĹؼüÄ£¿é£¬Æäº¸ÇÁËÍøÂç´«Êä¼°ÐÒé²ãµÄ¶¨Ò弰ʵÏÖ£»
Ä£¿éʵÏÖÁËһЩ¹Ø¼ü½Ó¿Ú¶¨Ò壬Èç½«ÍøÂç´«Êä¶Ëµã³éÏóΪEndpoint£¬¸ù¾ÝÇëÇóÏìÓ¦µÄ¹ØÁªÄ£ÐͶ¨ÒåÁËExchangeµÈ¡£
ÐÒéÕ»µÄ·Ö²ã¶¨Òå¡¢ÏûÏ¢±à½âÂë¡¢À¹½Ø´¦ÀíÒ²ÓÉnetwork°üÌṩ¡£
endpoins¶¨Òå

Endpoint ¶¨ÒåΪһ¸ö¶Ëµã£¬Í¨³£ÓëÒ»¸öIPºÍ¶Ë¿Ú¶ÔÓ¦£¬ÆäÆÁ±ÎÁËclientºÍserver½»»¥Ê±µÄÍøÂç´«Êäϸ½Ú¡£
¶ÔÓÚclientÀ´Ëµ£¬Endpoint´ú±íͨѶµÄ·þÎñ¶ËµØÖ·¶Ë¿Ú£»¶ø¶ÔÓÚserverÀ´ËµÔò´ú±íÁ˰󶨼àÌýµÄµØÖ·¼°¶Ë¿Ú¡£
CoapEndpointʵÏÖÁËEndpoint½Ó¿Ú£¬Í¨¹ýRawDataChannel(¼ûelements-connector²¿·Ö)½Ó¿ÚʵÏÖÏûÏ¢½ÓÊÕ£¬Í¨¹ýOutbox½Ó¿ÚʵÏÖÏûÏ¢·¢ËÍ¡£
ͨ³£CoapEndpoint »á¹ØÁªÒ»¸öConnector£¬ÒÔʵÏÖ´«Êä²ãµÄÊÕ·¢£»
CoapStack¶ÔÓ¦ÁËÐÒéÕ»½Ó¿Ú£¬ÓÃÓÚ´¦ÀíCoapEndpointÉϲãµÄÏûÏ¢Á´Â·£»
³ý´ËÖ®Í⣬CoapEndpoint »¹Ó¦¸Ã°üÀ¨ÏûÏ¢±à½âÂë¡¢À¹½Ø´¦ÀíµÈ¹¦ÄÜ¡£
exchange¶¨Òå

ExchangeÃèÊöÁËÇëÇó-ÏìӦģÐÍ£¬Ò»¸öExchange»á¶ÔÓ¦Ò»¸öRequest£¬ÏàÓ¦µÄResponse£¬ÒÔ¼°µ±Ç°µÄEndpoint£»
ExchangeObserverÓÃÓÚʵÏÖ¶ÔExchange״̬µÄ±ä¸ü¼àÌý£»
Exchange ͨ³£´æÔÚÓÚÁ½ÖÖ³¡¾°£º
1 ·¢ËÍÇëÇóºó³õʼ»¯²¢´æ´¢£¬µ±½ÓÊÕµ½¶ÔÓ¦µÄÏìÓ¦Ö®ºó±ä¸üΪcompleted(Ö´ÐÐÇåÀí¹¤×÷)¡£
2 ½ÓÊÕÇëÇóºó³õʼ»¯²¢´æ´¢£¬µ±·¢ËÍÏìӦʱִÐÐÇåÀí£»
matcher¶¨Òå

Matcher ÊÇÓÃÓÚʵÏÖExchange Éú³É¼°Ïú»ÙµÄÄ£¿é£¬ÌṩÁ˼¸¸öÊÕ·¢½Ó¿Ú£»
ÓÃÓÚÏûÏ¢ÔÚ½øÈëÐÒéÕ»CoapStack´¦Àí֮ǰÍê³ÉÅä¶Ô´¦Àí£»
messagetool¶¨Òå

MessageExchangeStore ʵÏÖÁËExchangeµÄ²éѯ¡¢´æ´¢£»
MessageIdProvider ÓÃÓÚÌṩCoapÏûÏ¢µÄMID£¬Ò»¸öMID´ú±íÁËÒ»¸öΨһµÄÏûÏ¢(ÔÚÏûÏ¢ÉúÃüÖÜÆÚÄÚ)£»
TokenProvider ÓÃÓÚÌṩCoapÏûÏ¢µÄToken£¬¶øRequest¼°Responseͨ¹ýTokenʵÏÖÆ¥Å䣻
network×ÓÄ£¿é

package-config
Ìá¹©ÍøÂç²ÎÊýÅäÖö¨Òå
package-deduplication
ÌṩÏûÏ¢È¥ÖØ»úÖÆµÄʵÏÖ
package-interceptors
ÌṩÏûÏ¢´«ÊäÀ¹½ØÆ÷¶¨Òå
package-serialization
ÌṩÏûÏ¢°üµÄ½âÎö¼°±àÂëʵÏÖ
package-stack
ÌṩÐÒéÕ»·Ö²ã¶¨Ò弰ʵÏÖ
4.1.3 package-server
Ó¦Óòã server¶ËʵÏÖµÄһЩ¶¨Ò壬°üÀ¨Server½Ó¿Ú¡¢Resource¶¨Òå¡£

CoapServer ¿É°üº¬¶à¸öEndpoint£¬ÌåÏÖΪһ¸öCoap·þÎñ¿É¼ÜÉèÔÚ¶à¸ö´«Êä¶Ë¿ÚÖ®ÉÏ£»
MessageDeliverer ÊÇÏûϢ·ÓɵĽӿڣ¬ServerMessageDelivery ʵÏÖÁ˸ù¾Ýuri ²éÕÒResourceµÄ¹¦ÄÜ£»
ConcurrentCoapResourceÔòΪResource ÌṩÁËÒ»¸ö¶ÀÁ¢Ï̳߳صÄÖ´Ðз½Ê½¡£
4.1.4 package-observe
Ó¦Óòã observe»úÖÆµÄ¶¨Ò壬ÈçÏÂͼ

ObserveRelation ¶¨ÒåÒ»¸ö¹Û²ì¹ØÏµ£¬¶ÔÓ¦Ò»¸ö¹Û²ìÕß¼´¹Û²ìÄ¿±êResource£»
ObserveEndpoint ¶¨ÒåÁËÒ»¸ö¹Û²ìÕ߶˵㣬²¢°üº¬Ò»¸ö¹ØÏµÁбí(Ò»¸ö¹Û²ìÕß¿ÉÒÔ¹Û²ì¶à¸öResource)£»
ObserveManager ÓÉCoapServer³ÖÓУ¬ÓÃÓÚ¹ÜÀí¹Û²ìÕ߶˵ãÁÐ±í£»
CoapResource Ò²»á³ÖÓÐÒ»¸öRelation¼¯ºÏÒÔʵÏÖ¸ú×Ù£»Æäͨ¹ýObserveRelationFilter½Ó¿Ú¾ö¶¨ÊÇ·ñ½ÓÊÜÀ´×Ô¹Û²ìÕßµÄ×¢²áÇëÇó£»
4.2 elements-connector

connector Ä£¿éÓÉcoreÄ£¿é°þÀ룬ÓÃÓÚʵÏÖÍøÂç´«Êä²ãµÄ³éÏó£¬ÕâʹµÃCoapÐÒé¿ÉÒÔÔËÐÐÓÚUDP¡¢TCP¡¢DTLSµÈ¶àÖÖÐÒéÖ®ÉÏ¡£
Connector¶¨ÒåÁËÁ¬½ÓÆ÷ÐèʵÏÖµÄÏà¹Ø·½·¨£¬°üÀ¨Æô¶¯Í£Ö¹¡¢Êý¾ÝµÄÊÕ·¢£»
RawData°üº¬ÁËÍøÂçÏûÏ¢°üµÄÔʼ×Ö½ÚÊý¾Ý£¬Æä½âÎöºÍ±àÂëÐèÒª½»ÓÉÉϲãÐÒéʵÏÖ£»
CorrelationContext ÃèÊöÁËÉÏÏÂÎÄ£¬ÓÃÓÚÖ§³Ö´«ÊäÐÒéµÄһЩ»á»°Êý¾Ý¶Áд£¬ÈçDTLS»á»°¡£
4.3. ºËÐĽӿÚ
ÏÂÃæÄâÓÃÒ»ÕŹØÏµÍ¼¸ÅÀ¨Californium ¿ò¼ÜµÄȫò(²¿·ÖÄÚÈÝδÌåÏÖ)£º

Óë·Ö²ãÉè¼Æ¶ÔÓ¦£¬¿ò¼Ü·ÖΪ transport ´«Êä²ã¡¢protocol ÐÒé²ã¡¢logic Âß¼²ã¡£
transport ´«Êä²ã£¬ÓÉConnector Ìṩ´«Êä¶Ë¿ÚµÄ³éÏó£¬UDPConnectorÊÇÆäÖ÷ҪʵÏÖ£»
Êý¾Ý°üͨ¹ýRawData¶ÔÏó·â×°£»¸Ã²ã»¹ÌṩÁËCorrelationContext ʵÏÖ´«Êä²ã»á»°Êý¾ÝµÄ¶Áд֧³Ö¡£
protocol ÐÒé²ã£¬ÌṩÁËCoap ÐÒéÕ»»úÖÆµÄÍêÕûʵÏÖ£»CoapEndpointÊǺËÐĵIJÙ×÷À࣬Êý¾ÝµÄ±à½âÂëͨ¹ý
DataSerializer¡¢DataParserʵÏÖ£¬MessageInterceptorÌṩÁËÏûÏ¢ÊÕ·¢µÄÀ¹½Ø¹¦ÄÜ£¬Request/ResponseµÄÓ³Éä´¦Àí
ÓÉ MatcherʵÏÖ£¬Exchange ÃèÊöÁËÓ³ÉäÄ£ÐÍ£»ÐÒéÕ»CoapStack ÊÇÒ»¸ö·Ö²ãµÄÄÚºËʵÏÖ£¬ÔÚÕâÀïÍê³É·Ö¿é¡¢ÖØ´«µÈ»úÖÆ¡£
logic Âß¼²ã£¬¶¨ÒåÁËCoapClient¡¢CoapServerµÄÈë¿Ú£¬°üÀ¨ÏûÏ¢µÄ·ÓÉ»úÖÆ£¬ResourceµÄ¼Ì³Ð»úÖÆ£»
Observe»úÖÆµÄ¹ØÏµÎ¬»¤¡¢×´Ì¬¹ÜÀíÓÉObserveManagerÌṩÈë¿Ú¡£
5. ¹Ø¼ü»úÖÆ
5.1 ÐÒéÕ»£»
californium-core ²ÉÓÃÁË·Ö²ã½Ó¿ÚÀ´¶¨ÒåÐÒéÕ»£¬ÆäÖÐCoapStack ÃèÊöÕû¸öÕ»¶ÔÏó£¬LayerÔò¶ÔÓ¦·Ö²ãµÄ´¦Àí£»
ÕâÏ൱ÓÚ²ÉÓÃÁ˹ýÂËÆ÷ģʽ£¬·Ö²ãµÄ¶¨ÒåʹµÃÌØÐԼ以²»Ó°Ï죬×ÓÄ£¿é¿É±£³Ö¶ÀÁ¢µÄ¹Ø×¢µã£»
CoapStack¶¨ÒåÈçÏ£º
public interface CoapStack {
// delegate to top
void sendRequest(Request request);
// delegate to top
void sendResponse(Exchange exchange, Response response);
...
// delegate to bottom
void receiveRequest(Exchange exchange, Request request);
// delegate to bottom
void receiveResponse(Exchange exchange, Response response); |
½Ó¿Ú°üÀ¨Á˼¸¸öÏûÏ¢ÊÕ·¢º¯Êý£¬¶øLayerÒ²¶¨ÒåÁËÒ»ÑùµÄ½Ó¿Ú¡£
Ò»¸öCoapUdpStack °üÀ¨µÄ·Ö²ãÈçÏÂͼ£º

CoapUdpStack ¹¹Ô캯ÊýÓë´Ë¶ÔÓ¦£º
public CoapUdpStack(final NetworkConfig config, final Outbox outbox) {
...
Layer layers[] = new Layer[] {
new ExchangeCleanupLayer(),
new ObserveLayer(config),
new BlockwiseLayer(config),
reliabilityLayer };
setLayers(layers);
} |
StackTopLayerºÍStackBottomLayerÓÉ»ù´¡ÀàBaseCoapStackÌṩ£¬ÊµÏÖÁËÐÒéÕ»¶¥²ãºÍµ×²ãÂß¼£»
MessageDeliverÊǽººÏÓ¦ÓòãµÄ½Ó¿Ú£¬Æä´ÓStackTopLayerÊÕµ½CoapÏûÏ¢Ö®ºó½«¼ÌÐø·Ö·¢µ½Resource£»
StackBottomLayerÔò½ººÏÁË´«Êä²ã£¬Í¨¹ýInbox/Outbox½Ó¿ÚʵÏÖÓëConnectorµÄ½»»¥¡£
ÆäËûLayerµÄ¹¦ÄÜ
ExchangeCleanLayer ÌṩExchangeÇåÀí¹¦ÄÜ£¬µ±È¡ÏûÇëÇóʱ´¥·¢ExchangeµÄÇåÀí¹¦ÄÜ£»
ObserveLayer ÌṩCoap Observe»úÖÆÊµÏÖ£»
BlockwiseLayer ÌṩCoap ·Ö¿é´«Êä»úÖÆÊµÏÖ£»
ReliabilityLayer Ìṩ¿É¿¿ÐÔ´«Ê䣬ʵÏÖ×Ô¶¯ÖØ´«»úÖÆ£»
5.2 ExchangeÉúÃüÖÜÆÚ
Exchange¶ÔÓ¦ÓÚÇëÇó/ÏìӦģÐÍ£¬ÆäÉúÃüÖÜÆÚÒ²Óɽ»»¥Ä£Ð;ö¶¨£¬Ò»°ãÔÚÏìÓ¦½áÊøÖ®ºóExchange±ã²»ÔÙ´æ»î£»
È»¶øÔÚObserve³¡¾°ÏÂÀýÍ⣬һµ©Æô¶¯ÁËObserveÇëÇó£¬Exchange»áÒ»Ö±´æ»îÖ±µ½Observe±»È¡Ïû»òÖжϡ£
1 LocalExchange£¬¼´±¾µØµÄExchange£¬ ¶ÔÓ¦ÓÚ±¾µØÇëÇó¶Ô·½ÏìÓ¦µÄ½»»¥¡£
BaseCoapStack.StackTopLayerʵÏÖÁ˳õʼ»¯£º
public void sendRequest(final Request request) {
Exchange exchange = new Exchange(request, Origin.LOCAL);
... |
µ±½ÓÊÕÏìӦʱ½øÐÐÏú»Ù£¬observeÀàÐ͵ÄÇëÇóÔÚÕâÀï±»ºöÂÔ£º
public void receiveResponse(final Exchange exchange, final Response response) {
if (!response.getOptions().hasObserve()) {
exchange.setComplete();
} |
UdpMatcher ʵÏÖÁËÏú»Ù¶¯×÷£º
UdpMatcher--
public void sendRequest(final Exchange exchange, final Request request) {
exchange.setObserver(exchangeObserver);
exchangeStore.registerOutboundRequest (exchange);
if (LOGGER.isLoggable(Level.FINER)) { |
ÕâÊÇÔÚ·¢ËÍÇëÇóʱΪExchangeÌí¼Ó¹Û²ìÕß½Ó¿Ú£¬µ±exchangeÖ´ÐÐcomplete²Ù×÷ʱ´¥·¢¾ßÌåµÄÏú»Ù¹¤×÷£º
UdpMatcher.ExchangeObserverImpl--
if (exchange.getOrigin() == Origin.LOCAL) {
// this endpoint created the Exchange by issuing a request
KeyMID idByMID = KeyMID.fromOutboundMessage (exchange.getCurrentRequest());
KeyToken idByToken = KeyToken.fromOutboundMessage (exchange.getCurrentRequest());
exchangeStore.remove(idByToken);
// in case an empty ACK was lost
exchangeStore.remove(idByMID);
... |
ÖµµÃһ˵µÄÊÇ£¬californium´óÁ¿²ÉÓÃÁ˹۲ìÕßÉè¼ÆÄ£Ê½£¬ÕâÖÖ·½·¨ÔÚÉè¼ÆÒì²½ÏûÏ¢»úÖÆÊ±·Ç³£ÓÐÓÃ.
´ËÍ⣬requestµÄÈ¡Ïû¡¢ÖжϲÙ×÷(RSTÐźÅ)¡¢´«ÊäµÄ³¬Ê±¶¼»áµ¼ÖÂexchangeÉúÃüÖÜÆÚ½áÊø¡£
LocalExchangeµÄÉúÃüÖÜÆÚÈçÏÂͼ£º

2 RemoteExchange£¬¼´Ô¶³ÌµÄExchange£¬¶ÔÓ¦ÓÚ±¾µØ½ÓÊÕÇëÇó²¢·µ»ØÏìÓ¦µÄ½»»¥¡£
UdpMatcherʵÏÖÁËÔ¶³ÌExchangeµÄ³õʼ»¯£º
UdpMatcher--
public Exchange receiveRequest(final Request request) {
...
KeyMID idByMID = KeyMID.fromInboundMessage(request);
if (!request.getOptions().hasBlock1() && !request.getOptions(). hasBlock2()) {
Exchange exchange = new Exchange(request, Origin.REMOTE);
Exchange previous = exchangeStore.findPrevious(idByMID, exchange);
if (previous == null) {
exchange.setObserver(exchangeObserver);
... |
ÔÚ·¢ËÍÏìӦʱ£¬Exchange±»Ïú»Ù£¬ÈÔÈ»ÓÉUdpMatcherʵÏÖ£º
UdpMatcher--
public void sendResponse(final Exchange exchange, final Response response) {
response.setToken(exchange. getCurrentRequest().getToken());
...
// Only CONs and Observe keep the exchange active (CoAP server side)
if (response.getType() != Type.CON && response.isLast()) {
exchange.setComplete();
} |
×¢Òâµ½ÕâÀï¶Ôresponse½øÐÐÁËlastÊôÐÔµÄÅжϣ¬¸ÃÊôÐÔĬÈÏΪtrue£¬¶øObserveLayer½«ÆäÖÃΪfalse£¬Ê¹µÃobserveÏìÓ¦²»»áµ¼ÖÂExchange½áÊø£º
ObserveLayer--
public void sendResponse(final Exchange exchange, Response response) {
...
response.setLast(false); |
Á¬½ÓÖжÏ(RSTÐźÅ)¡¢´«Ê䳬ʱ»áµ¼ÖÂExchangeµÄ½áÊø£¬´ËÍâÓɿͻ§¶Ë·¢ÆðµÄobserveÈ¡ÏûÇëÇóÒ²»á²úÉúÒ»ÑùµÄ½á¹û¡£
RemoteExchangeµÄÉúÃüÖÜÆÚÈçÏÂͼËùʾ£º

5.3 ·Ö¿é´«Ê䣻
·Ö¿é´«ÊäÒ»°ãÓÃÓÚ·¢ËͽϴóµÄÇëÇóÌå»ò½ÓÊܽϴóµÄÏìÓ¦Ì壬±ÈÈçÉÏ´«ÏÂÔØ¹Ì¼þ°ü³¡¾°£¬ÓÉÓÚÊܵ½MTUµÄÏÞÖÆ£¬ÐèҪʵÏÖ·Ö¿é´«Ê䣻
Coap¶¨ÒåÁË·Ö¿é´«ÊäµÄ·½Ê½£¬²ÉÓÃBlock1/Block2»úÖÆ
OptionÑ¡Ïî
BlockOptionÊÇÓÃÓÚÃèÊö·Ö¿éÐÅÏ¢µÄÑ¡ÏîÀàÐÍ£¬Ñ¡ÏîֵΪ0-3¸ö×Ö½Ú£¬±àÂë°üº¬ÁË3¸ö×ֶΣºµ±Ç°·Ö¿é±àºÅ£»ÊÇ·ñ½áÊø£»µ±Ç°·Ö¿é´óС¡£
ÎªÇø·ÖÇëÇóºÍÏìÓ¦µÄ²»Í¬£¬·Ö±ðÓÐblock1ºÍblock2 Á½¸öÑ¡Ï
block1£ºÓÃÓÚ·¢ËÍPOST/PUTÇëÇóʱ´«Êä½Ï´óµÄÄÚÈÝÌ壻
block2£ºÓÃÓÚÏìÓ¦GET/POST/PUTÇëÇóʱ´«Êä½Ï´óµÄÄÚÈÝÌ壻
size1£ºÖ¸Ê¾ÇëÇóÌåµÄ×Ü´óС£»
size2£ºÖ¸Ê¾ÏìÓ¦ÌåµÄ×Ü´óС£»
ÅäÖÃÑ¡Ïî
maxMessageSize£ºÏûÏ¢´óСãÐÖµ£¬µ±·¢Ë͵ÄÏûÏ¢´óÓÚ¸ÃãÐֵʱÐè²ÉÓ÷ֿ鴫Ê䣬¸ÃÖµ±ØÐëСÓÚMTU£»
preferredBlockSize£ºÓÃÓÚָʾ·Ö¿éµÄ´óС£»
maxResourceBodySize£º×î´ó×ÊÔ´ÄÚÈÝÌå´óС£¬ÓÃÓÚÏÞÖÆ½ÓÊÕµÄÇëÇó»òÏìÓ¦µÄ×Ü´óС£¬Èô³¬¹ý½«Ìáʾ´íÎó»òÈ¡Ïû´¦Àí£»
blockLifeTime£º·Ö¿é´«ÊäµÄÉúÃüÖÜÆÚʱ³¤£¬Èô³¬¹ý¸Ãʱ³¤·Ö¿é´«ÊäδÍê³ÉÔòÊÓΪʧ°Ü£»
BlockwiseLayerʵÏÖÁË·Ö¿é´«ÊäµÄÍêÕûÂß¼£¬ÆäÖÐsendRequestµÄ´úÂëÆ¬¶Î£º
public void sendRequest( final Exchange exchange, final Request request) {
BlockOption block2 = request. getOptions().getBlock2();
if (block2 != null && block2.getNum() > 0) {
//Ó¦ÓòãÖ¸¶¨µÄ·Ö¿é..
} else if (requiresBlockwise(request)) {
//×Ô¶¯¼ÆËã·Ö¿é
startBlockwiseUpload(exchange, request);
} else {
//²»ÐèÒª·Ö¿é
exchange.setCurrentRequest(request);
lower().sendRequest(exchange, request);
}
}
...
//ʵÏÖ·Ö¿éãÐÖµÅжÏ
private boolean requiresBlockwise (final Request request) {
boolean blockwiseRequired = false;
if (request.getCode() == Code.PUT || request.getCode() == Code.POST) {
blockwiseRequired = request .getPayloadSize() > maxMessageSize;
}
...
//startBlockwiseUploadʵÏÖÁËrequest·Ö¿éÂß¼£¬Í¨¹ýÔÚÇëÇóµÄOptionÖмÓÈëBlock1×÷Ϊ±êʶ
private void startBlockwiseUpload (final Exchange exchange, final Request request) {
BlockwiseStatus status = findRequestBlockStatus(exchange, request);
final Request block = getNextRequestBlock(request, status);
block.getOptions().setSize1( request.getPayloadSize());
...
lower().sendRequest(exchange, block);
} |
½ÓÊն˼ì²âRequestµÄBlock1Ñ¡Ï·µ»ØcontinueÏìÓ¦Â룬ֱµ½ËùÓзֿ鴫ÊäÍê³Éºó½øÐÐ×é×°½»ÓÉÉϲ㴦Àí£º
private void handleInboundBlockwiseUpload (final BlockOption block1, final Exchange exchange, final Request request) {
//¼ì²éÊÇ·ñ³¬¹ýÏÞÖÆ
if (requestExceedsMaxBodySize(request)) {
Response error = Response.createResponse (request, ResponseCode.REQUEST_ENTITY_TOO_LARGE);
error.setPayload(String.format("body too large, can process %d bytes max", maxResourceBodySize));
error.getOptions().setSize1( maxResourceBodySize);
lower().sendResponse( exchange, error);
} else {
...
if (block1.getNum() == status.getCurrentNum()) {
if (status.hasContentFormat( request.getOptions().getContentFormat())) {
status.addBlock( request.getPayload());
status.setCurrentNum( status.getCurrentNum() + 1);
if ( block1.isM() ) {
//´æÔÚºóÃæµÄblock£¬·µ»ØContinueÏìÓ¦
Response piggybacked = Response.createResponse (request, ResponseCode.CONTINUE);
piggybacked.getOptions().setBlock1( block1.getSzx(), true, block1.getNum());
piggybacked.setLast(false);
exchange.setCurrentResponse(piggybacked);
lower().sendResponse(exchange, piggybacked);
} else {
...
//ÒѾÍê³É£¬×é×°ºó½»ÓÉÉϲ㴦Àí
Request assembled = new Request( request.getCode());
assembled.setSenderIdentity( request.getSenderIdentity());
assembleMessage(status, assembled);
upper().receiveRequest( exchange, assembled);
} |
Òò´Ë£¬Ò»¸öÇëÇóÌå·Ö¿é´«ÊäÁ÷³ÌÈçÏÂͼËùʾ£º

ÏìÓ¦Ìå·Ö¿é´«ÊäµÄÂß¼Óë´ËÀàËÆ£¬½»»¥Á÷³ÌÈçÏÂͼ£º

5.4 ÏûÏ¢ÖØ´«£»
CoapÏûÏ¢Ö§³ÖÖØ´«»úÖÆ£¬µ±·¢ËÍCONÀàÐ͵ÄÏûϢʱ£¬ÒªÇó½ÓÊÕ¶ËÏìÓ¦¶ÔÓ¦µÄACKÏûÏ¢£»Èç¹ûÔÚÖ¸¶¨Ê±¼äÄÚûÓÐÊÕµ½ÏìÓ¦£¬Ôò½øÐÐÖØ´«¡£
»ù´¡ÏûÏ¢ÖØ´«ÓÉReliabilityLayerʵÏÖ£¬sendRequest ´úÂëÆ¬¶Î£º
if (request.getType() == null) {
request.setType(Type.CON);
}
if (request.getType() == Type.CON) {
prepareRetransmission(exchange, new RetransmissionTask (exchange, request) {
public void retransmit() {
sendRequest(exchange, request);
}
});
}
lower().sendRequest(exchange, request); |
µ±·¢ËÍCONÀàÐÍÏûϢʱ£¬Í¨¹ý prepareRetransmissionº¯ÊýʵÏÖÖØ´«×¼±¸£º
int timeout;
if (exchange.getFailedTransmissionCount() == 0) {
timeout = getRandomTimeout(ack_timeout, (int) (ack_timeout * ack_random_factor));
} else {
timeout = (int) (ack_timeout_scale * exchange. getCurrentTimeout());
}
exchange.setCurrentTimeout(timeout);
ScheduledFuture<?> f = executor.schedule(task, timeout, TimeUnit.MILLISECONDS);
exchange.setRetransmissionHandle(f); |
exchange.getFailedTransmissionCount() ·µ»Ø0 ´ú±íµÚÒ»´Î´«Ê䣬²ÉÓõij¬Ê±Ê±¼äÊÇ£º
**timeout = random(ack_timeout, act_timeout*ack_random_factor)**
//ÆäÖÐack_timeout(³¬Ê±Æðʼֵ)¡¢ack_random_factor(Ëæ»úÒò×Ó)ÓÉÅäÖÃÎļþÌṩ£»
ºóÐøµÄÖØ´«Ê±¼ä½«ÓÉÉÏÒ»´ÎµÄtimeoutºÍack_timeout_scaleϵÊý¾ö¶¨£º
timeout = timeout * ack_timeout_scale
µ±½ÓÊÕACKʱ£¬ÓбØÒªÈ¡ÏûÖØ´«´¦Àí£¬¿´¿´receiveResponseµÄʵÏÖ£º
@Override
public void receiveResponse(final Exchange exchange, final Response response) {
exchange.setFailedTransmissionCount(0);
exchange.getCurrentRequest(). setAcknowledged(true);
exchange.setRetransmissionHandle(null);
... |
¿ÉÒÔ¿´µ½£¬½ÓÊÕµ½ÏìÓ¦Ö®ºó£¬½«Request±ê¼ÇΪack״̬£¬exchange.setRestransmissionHandler»áµ¼ÖÂÉÏÒ»´ÎµÄÖØ´«scheduÈÎÎñ±»È¡Ïû¡£
×îÖÕÖØ´«ÈÎÎñÓÉRetransmissionTaskʵÏÖ£º
int failedCount = exchange. getFailedTransmissionCount() + 1;
exchange.setFailedTransmissionCount (failedCount);
if (message.isAcknowledged()) {
return;
} else if (message.isRejected()) {
return;
} else if (message.isCanceled()) {
return;
} else if (failedCount <= max_retransmit) {
// Trigger MessageObservers
message.retransmitting();
// MessageObserver might have canceled
if (!message.isCanceled()) {
retransmit();
}
} else {
exchange.setTimedOut();
message.setTimedOut(true);
} |
Âú×ãÖØ´«µÄÌõ¼þ£º
1 ÏûϢδ±»È·ÈÏ(ÊÕµ½ACK)»ò¾Ü¾ø(ÊÕµ½RST)
2 ÏûϢδ±»È¡Ïû£»
3 ÏûϢ䳬¹ýÖØ´«´ÎÊýÏÞÖÆ£»
ÆäÖÐÖØ´«´ÎÊýmax_retransmitÓÉÅäÖÃÌṩ£¬µ±³¬¹ý¸Ã´ÎÊýÏÞÖÆÊ±ÏûÏ¢½«·¢Éú´«Ê䳬ʱ¡£
ĬÈϲÎÊýÅäÖÃ
ack_timeout=2s
ack_random_factor=1.5
ack_timeout_scale=2
max_retransmit=4 |
5.5 ·ÀÖ¹ÖØ¸´°ü£»
ÓÉÓÚ´æÔÚÖØ´«»úÖÆ£¬¼ÓÉÏUDP´«ÊäµÄ²»Îȶ¨ÐÔ£¬´«ÊäÁ½¶ËºÜ¿ÉÄÜ»áÊܵ½Öظ´µÄÏûÏ¢°ü£»
ͨ³£Öظ´ÏûÏ¢µÄ¼ì²âÒªÇóʵÏÖÏûÏ¢ÈÝÆ÷ÒԼǼºÍÆ¥ÅäÖØ¸´ÏûÏ¢ID£¬È»¶øÖ´ÐÐʱ¼äÔ½³¤£¬ÏûÏ¢»áÔ½À´Ô½¶à£¬
Òò´ËÏûÏ¢ÈÝÆ÷±ØÐë¾ß±¸Çå³ý»úÖÆ£¬»ùÓڴ˵㲻ͬ£¬californium ÌṩÁËÁ½ÖÖʵÏÖ»úÖÆ£º
5.5.1 ±ê¼ÇÇå³ý
Çå³ýÆ÷ά³ÖÒ»¸öÏûÏ¢ÈÝÆ÷£¬Ã¿¸öÏûÏ¢¶¼±£³ÖÒ»¸ö³õʼµÄʱ¼ä´Á£»
Çå³ýÆ÷¶¨Ê±½øÐÐɨÃ裬·¢ÏÖÌ«ÀϵÄÏûÏ¢Ôò½«ÆäÇå³ý¡£

SweepDeduplicator ÌṩÁËʵÏÖ£¬Çå³ý´úÂëÆ¬¶Î£º
private void sweep() {
final long oldestAllowed = System.currentTimeMillis() - exchangeLifetime;
final long start = System.currentTimeMillis();
for (Map.Entry<?, Exchange> entry : incomingMessages.entrySet()) {
Exchange exchange = entry.getValue();
if (exchange.getTimestamp() < oldestAllowed) {
incomingMessages.remove(entry.getKey());
}
}
... |
ÆäÖÐincomingMessage²ÉÓÃÁËConcurrentHashMapÊý¾Ý½á¹¹£¬ÕâÊÇÒ»¸ö²¢·¢ÐÔÁ¼ºÃµÄḬ̈߳²È«¼¯ºÏ£»
È»¶ø´ÓÉÏÃæµÄ´úÂëÒ²¿ÉÒÔ·¢ÏÖ£¬sweepÔÚÕâÀïÊÇÒ»¸ö±éÀú²Ù×÷£¬¶¨Ê±Çå³ýµÄÀÏ»¯Ê±¼äĬÈÏΪ247s£¬¼ÙÉè1sÄÚ´¦Àí1000ÌõÏûÏ¢£¬
ÄÇôÿ´ÎÇå³ýʱפÁôµÄÏûÏ¢ÊýÁ¿Îª247000£¬¼´ÐèÒª±éÀúÕâô¶àµÄ´ÎÊý£¬¶ÔÓÚCPUÀ´Ëµ´æÔÚÒ»¶¨µÄ¿ªÏú¡£
²ÉÓÃÕâÖÖ·½Ê½£¬ÏûÏ¢µÄ´æ»îʱ¼ä»ù±¾ÉÏÓÉexchangeLifetime²ÎÊýºÍɨÃè¼ä¸ô¾ö¶¨¡£
5.5.2 ·×ªÇå³ý
Çå³ýÆ÷ά³ÖÈý¸öÏûÏ¢ÈÝÆ÷£¬±£³Ö1¡¢2¡¢3Èý¸öË÷Òý·Ö±ðÖ¸ÏòÏàÓ¦ÏûÏ¢ÈÝÆ÷£¬ÆäÖÐË÷Òý1¡¢2´ú±íÁ˻µÄÏûÏ¢ÈÝÆ÷£¬
Ë÷Òý3 ´ú±íÀÏ»¯µÄÏûÏ¢ÈÝÆ÷£¬ÈçÏÂͼËùʾ

ÏûÏ¢Ë÷ÒýÊ״λáÍù I1ÈÝÆ÷дÈ룬ͬʱҲ»áÍù I2ÈÝÆ÷´æÈ뿽±´£»
²éÕÒÏûϢʱÖ÷Òª´ÓI1 ÈÝÆ÷²éÕÒ£»
ÿ¸öÖÜÆÚ»áÖ´ÐÐÒ»´Î·×ª£¬¼¸¸öÈÝÆ÷Ö¸Õë·¢ÉúÖû»(I1->I2£¬I2->I3£¬I3->I1)£¬Ö®ºóI3 Ö¸ÏòµÄÈÝÆ÷»á±»ÇåÀí£»
CropRotation ʵÏÖÁ˷תµÄÂß¼£¬´úÂëÈçÏ£º
private void rotation() {
synchronized (maps) {
int third = first;
first = second;
second = (second+1)%3;
maps[third].clear();
} |
»ùÓÚÉÏÊöµÄËã·¨·ÖÎö£¬I2ÈÝÆ÷µÄÏûÏ¢´æ»îʱ¼ä»áСÓÚÒ»¸öÖÜÆÚ£¬I1ÈÝÆ÷µÄÏûÏ¢Ôò´æ»îÒ»¸öÖÜÆÚµ½Á½¸öÖÜÆÚÖ®¼ä£¬I3 ÈÝÆ÷Ôò³¬¹ý2¸öÖÜÆÚ£¬ÊÇ×îÀϵÄÈÝÆ÷£»
»ùÓÚÕâÑùµÄÂß¼£¬·×ªÇå³ý»úÖÆµÄÏûÏ¢´æ»îʱ¼äÊÇ1-2¸öÖÜÆÚÖ®¼ä£¬¶ø¸Ã»úÖÆÏà±È±ê¼ÇÇå³ýµÄÓŵãÔÚÓÚÇå³ý»úÖÆÊÇÕû¸öÈÝÆ÷Ò»¿éÇå³ý£¬¶ø²»ÐèÒª±éÀú²Ù×÷£¬È»¶øÈ±µãÊÇÔö¼ÓÁË´æ´¢¿ªÏú¡£
JVMµÄÀ¬»ø»ØÊÕ»úÖÆÒ²´æÔÚÀàËÆµÄÉè¼Æ£¬ÏàÐÅcaliforniumµÄ¿ª·¢Õß½è¼øÁËһЩ˼·¡£
ÖÁ´Ë£¬Californium¿ò¼ÜµÄ»ù±¾È«Ã²ÒѾ·ÖÎöÍê±Ï¡£Èç¹ûÏ£Íû¶Ô¿ò¼ÜÓиüÉîÈëµÄÀí½â£¬ÄÇô½¨ÒéÄãÖ±½ÓÔÚÏîÄ¿ÖÐÖ±½ÓʹÓÃËü£¬²¢Õë¶Ô×Ô¼º¸ÐÐËȤµÄ¼¸¸öÎÊÌâ½øÐÐÔ´Âë·ÖÎö»òµ÷ÊÔ£¬ÏàÐÅÊÕ»ñ»á¸ü¶à¡£ |