Maskers en controleframes
Berichten in stukken
Elk encode_frame(OP_TEXT, "Hel", fin=False), een frame dat niet de laatste is. Dat frame is de helft van een echt voorbeeld. RFC 6455 sectie 5.7 stuurt “Hello” als twee frames:
01 03 48 65 6c
80 02 6c 6f
Het eerste frame is 01: FIN uit, 80: FIN gezet, opcode 0, daarna de lengte 2 en “lo”. Samen dragen ze één tekstbericht, “Hello”. Dit is fragmentatie, en deze les leest het zonder er code voor te schrijven.
De regels van sectie 5.4
Een bericht dat over meerdere frames is verdeeld, zijn fragmenten, volgt drie regels:
Het eerste frame draagt de opcode van het bericht, 1 voor tekst of 2 voor binair, met FIN uit.
Eventuele middelste frames dragen opcode 0, vervolg, met FIN uit.
Het laatste frame draagt opcode 0 met FIN gezet.
Opcode 0 zegt “dit frame zet het bericht voort dat al bezig is”; alleen het eerste frame zegt wat voor bericht het is. FIN markeert het einde, dus de ontvanger blijft payloads verzamelen totdat er een vervolgframe aankomt met FIN gezet, en voegt ze dan samen. Een bericht in één frame is gewoon het geval waarin het eerste frame ook het laatste is: opcode 1 of 2 met FIN gezet, de enige soort die je codec tot nu toe heeft gezien.
Dit blok leest beide frames met de bitoperaties uit hoofdstuk 3 en voegt hun payloads samen:
Welk frame beëindigt een gefragmenteerd bericht?
Waarom een bericht splitsen
Twee situaties laten een afzender een bericht splitsen. De eerste is een afzender die bij het begin niet weet hoe lang het bericht wordt, bijvoorbeeld een die data stuurt terwijl hij die maakt. De header van een frame noemt de payloadlengte vóór de payload, dus zo’n afzender stuurt wat hij heeft als fragment en markeert het laatste stuk met FIN als hij klaar is.
De tweede is een lang bericht dat niet al het andere mag blokkeren. Les 3 gaf controleframes een derde regel: ze mogen tussen de fragmenten van een bericht aankomen. Een afzender die midden in een groot bericht zit, kan tussen twee fragmenten stoppen, een
01 03 48 65 6c
89 05 48 65 6c 6c 6f
80 02 6c 6f
De ontvanger handelt de ping apart af en gaat daarna verder met het verzamelen van “Hello”. Dataframes mogen zich niet zo door elkaar mengen: een nieuw tekst- of binair bericht kan pas beginnen als het laatste fragment van het huidige is aangekomen. Alleen controleframes mogen ertussen komen, en dat is een reden waarom een controleframe zelf nooit gefragmenteerd is en op 125 bytes of minder blijft.
Er komt een ping aan tussen 01 03 48 65 6c en 80 02 6c 6f. Is dat toegestaan?
Wat de leercodec doet
Fragmenten weer samenvoegen vraagt toestand die over frames heen blijft bestaan: de opcode van het bericht dat bezig is, de payloads die tot nu toe verzameld zijn, een groottelimiet op hun totaal, en de regel dat er een controleframe in het midden mag aankomen. De leercodec doet dit niet. De read_message die je in les 6 schrijft, weigert elk frame met FIN uit of met opcode 0, en noemt een
Geen enkele sluitcode betekent “dit eindpunt voegt gefragmenteerde berichten niet samen”. 1003, niet-ondersteunde data, is de minst verkeerde keuze: die zegt dat het eindpunt niet kan accepteren wat er aankwam. 1002, protocolfout, zou fout zijn, omdat die de peer de schuld geeft, en een peer die een bericht fragmenteert, breekt geen enkele regel. Dit is een grens van de leercodec, gekozen om de codec klein genoeg te houden om in één hoofdstuk te schrijven, geen fout van de peer. Een
De bibliotheek websockets die je vanaf hoofdstuk 6 gebruikt, accepteert ze wel. In een run die werd gemaakt toen deze cursus werd geschreven, droegen frames die met de leercodec waren gebouwd “Hel”, een ping en “lo” over
Waarom sluit de leercodec met 1003 als hij een fragment ziet?
De leercodec is dus geen volledige WebSocket-implementatie, en hij zegt dat met een code in plaats van op een verwarrende manier te falen. De volgende les, het project van het hoofdstuk, zet elke regel uit dit hoofdstuk achter één read_message, die een stroom bytes omzet in berichten en controle-events, en elke weigering haar sluitcode geeft.