Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
californium ¿ò¼ÜÉè¼Æ·ÖÎö
 
À´Ô´£º²©¿Í ·¢²¼ÓÚ£º 2017-6-7
  3166  次浏览      27
 

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¿ò¼ÜµÄ»ù±¾È«Ã²ÒѾ­·ÖÎöÍê±Ï¡£Èç¹ûÏ£Íû¶Ô¿ò¼ÜÓиüÉîÈëµÄÀí½â£¬ÄÇô½¨ÒéÄãÖ±½ÓÔÚÏîÄ¿ÖÐÖ±½ÓʹÓÃËü£¬²¢Õë¶Ô×Ô¼º¸ÐÐËȤµÄ¼¸¸öÎÊÌâ½øÐÐÔ´Âë·ÖÎö»òµ÷ÊÔ£¬ÏàÐÅÊÕ»ñ»á¸ü¶à¡£

   
3166 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö