当前位置: 首页 > 后端技术 > Python

【连载1】如何把协议规范变成开源库系列文章WebSocket

时间:2023-03-26 13:06:30 Python

杩欐槸璇ョ郴鍒楃殑绗竴绡囨枃绔狅紝涔熸槸闈炲父閲嶈鐨勪竴绡囥€傚笇鏈涘ぇ瀹惰兘鐪嬫噦鎴戞兂琛ㄨ揪鐨勬剰鎬濄€傜郴鍒楁枃绔犲紑绡囨杩颁笌鍏朵粬缂栫▼璇█鐩告瘮锛孭ython鐢熸€佷腑鏈€绐佸嚭鐨勫氨鏄涓夋柟搴撱€備换浣曞悎鏍肩殑Python寮€鍙戣€呴兘鑷冲皯浣跨敤杩?涓涓夋柟搴撱€傚氨鐖櫕棰嗗煙鑰岃█锛屾瘮濡傜綉缁滆姹傚簱Requests銆佺綉椤佃В鏋愬簱Parsel鎴朆eautifulSoup銆佹暟鎹簱瀵硅薄鍏崇郴鏄犲皠Motor鎴朣QLAlchemy銆佸畾鏃朵换鍔pscheduler銆佺埇铏鏋禨crapy绛夐兘浼氱敤鍒般€傛瘡涓汉閮藉繀椤婚潪甯哥啛缁冨湴浣跨敤杩欎簺寮€婧愬簱锛岀敋鑷冲煿鍏诲嚭鑷繁鐨勪竴濂楁妧鑳姐€傛棩甯稿伐浣滄暡閿洏鑲畾鏄槑鍢庝綔鍝嶃€備絾鏄綘鏈夋病鏈夋兂杩囷細閭d釜绁炲鐨勫姛鑳芥槸濡備綍瀹炵幇鐨勫憿锛熻繖涓姛鑳借儗鍚庣殑閫昏緫鏄粈涔堬紵涓轰粈涔堣繖鏍峰仛鑰屼笉鏄€夋嫨鍙︿竴绉嶅啓娉曞憿锛熺紪鍐欒繖鏍风殑搴撻渶瑕佸摢浜涚煡璇嗭紵杩欎釜璁虹偣鏈夋槑纭殑渚濇嵁鍚楋紵濡傛灉浣犱粠鏉ユ病鏈夋兂杩囷紝璇存槑浣犺繕娌℃湁鍒扳€滄浮鍔€濈殑鏃跺€欙紱濡傛灉浣犳彁鍑轰簡3涓互涓婄殑闂锛屽氨鎰忓懗鐫€浣犲嵆灏嗗埌杈鹃偅涓噸瑕佺殑鍏冲彛锛涘鏋滀綘缁忓父鏈夎繖鏍风殑鎯虫硶锛屽苟涓斾篃璇曞浘鎵惧埌鐩稿簲鐨勭瓟妗堬紝閭d箞鎭枩浣狅紝浣犵幇鍦ㄥ凡缁忓埌浜嗏€滄浮鍔€濈殑闂ㄦ涓婁簡銆傚伓灏旀湁涓€缇ゆ湅鍙嬩細闂繖鏍蜂竴涓棶棰橈細濡備綍瀹氫箟鍒濈骇宸ョ▼甯堛€佷腑绾у伐绋嬪笀銆侀珮绾у伐绋嬪笀锛熻繖涓棶棰樻湁涓ょ涓嶅悓鐨勭湅娉曪紝绗竴绉嶆槸鐪嬭亴绾э紝绗簩绉嶆槸鐪嬩釜浜鸿兘鍔涖€傝亴浣嶇瓑绾ф槸涓€涓潪甯稿彲鍙樼殑鍙傝€冦€傛瘮濡傞樋閲屽反宸寸殑瓒呭墠鐮斿彂鍜屾垜浠叕鍙哥殑瓒呭墠鐮斿彂閮藉啝浠モ€滆秴鍓嶇爺鍙戔€濓紝浣嗚兘鍔涗笂鍙兘宸窛寰堝ぇ銆傚浣曡瘎浼颁釜浜鸿兘鍔涳紵鏄惁鍙互鐪嬪嚭浠g爜鍐欏緱蹇繕鏄參锛熷綋鐒朵笉鏄紒涓汉鑳藉姏瑕佷粠骞垮害鍜屾繁搴︽潵鑰冭檻锛岃繖涓病鏈夋槑纭殑鏍囧噯銆傚綋涓や釜浜虹殑鑳藉姏宸窛寰堝ぇ鏃讹紝澶栦汉寰堝鏄撳垎杈ㄥ嚭璋佸己璋佸急銆傚浣曞尯鍒嗕釜浜鸿兘鍔涚殑杩涢€€锛熻繖鍙堝洖鍒颁簡涓婇潰鎻愬埌鐨勯棶棰橈細WHOWHATWHEREWHYWHENHOW锛熸垜鎯抽€氳繃杩欑瘒鏂囩珷鍛婅瘔浣狅紝涓嶈鎴愪负浣跨敤搴撶殑浜猴紝鑰屾槸鍒涘缓搴撶殑浜恒€傝绠楁満涓栫晫涔嬫墍浠ュ姝ゅ惛寮曚汉锛屾槸鍥犱负鎴戜滑鍙互鍦ㄨ繖涓笘鐣屼笂闅忓績鎵€娆插湴鍒涢€犮€備綘鎯虫垚涓哄垱閫犺€呭悧锛熷鏋滄病鏈夛紝鎮ㄧ幇鍦ㄥ彲浠ュ叧闂祻瑙堝櫒绐楀彛骞惰繑鍥濰ub涓栫晫銆傚唴瀹逛粙缁嶈繖鏄竴涓郴鍒楁枃绔犮€傛湰绯诲垪灏嗚瑙e父鐢ㄥ簱锛堝WebSocket銆丠TTP銆丄SCII銆丅ase64銆丮D5銆丄ES銆丷SA锛夌殑鍗忚瑙勮寖鍙婄浉搴斾唬鐮佸疄鐜帮紝甯姪鎮ㄢ€滅煡琛屽悎涓€锛岀煡琛屽悎涓€鈥濄€傝繖灏辨槸涓轰粈涔堛€傗€濈洰鏍囪繖娆℃垜浠瀛︿範鐨勬槸WebSocket鍗忚瑙勮寖鍜屼唬鐮佸疄鐜帮紝涔熷彲浠ョ悊瑙d负浠庡ご寮€濮嬬紪鍐檃iowebsocket搴撱€傝嚦浜庝负浠€涔堥€夋嫨瀹冿紝澶ф鏄洜涓洪噷闈㈡病鏈変汉銆備笘鐣屼笂璋佹瘮鎴戞洿鐔熸倝瀹冦€傛垜鏄痑iowebsocket搴撶殑浣滆€咃紝鎴戣姳浜?澶╂椂闂村啓杩欎釜搴撱€傚啓杩欎釜搴撶殑杩囩▼璁╂垜娣卞埢鍦扮悊瑙d簡閫犺疆瀛愬拰寮€杞︿箣闂寸殑鍖哄埆锛屽苟涓斿畠涔熻鎴戣繘姝ュ緢蹇紝甯屾湜閫氳繃绯诲垪鏂囩珷鐨勫舰寮忥紝甯姪澶у浠庨┍鍔ㄨ€呰浆鍙樹负鍒涢€犺€咃紝鎷ユ湁鈥滅紪绋嬫€濈淮鈥濓紝瀹冪殑鍑虹幇浣垮緱瀹㈡埛绔拰鏈嶅姟绔箣闂寸殑鏁版嵁浜ゆ崲鍙樺緱鏇村姞瀹规槗锛屼笅鍥炬弿杩颁簡涓ょ浜や簰鐨勮繃绋嬶細WebSocket閫氬父鐢ㄥ湪瀵瑰疄鏃舵€ц姹傛瘮杈冮珮鐨勫満鏅紝姣斿濡備簨浠舵暟鎹€佽偂绁ㄨ瘉鍒搞€佺綉缁滆亰澶╁拰鍦ㄧ嚎缁樺浘绛夈€俉ebSocket涓嶩TTP鍗忚瀹屽叏涓嶅悓锛屼絾涔熻骞挎硾浣跨敤銆傛棤璁轰綘鏄悗绔紑鍙戜汉鍛樸€佸墠绔紑鍙戜汉鍛樸€佺埇铏伐绋嬪笀杩樻槸淇℃伅瀹夊叏宸ヤ綔鑰咃紝閮藉簲璇ユ帉鎻ebSocket鍗忚鐨勭煡璇嗐€傚彂琛ㄨ繃鍑犵瘒鍏充簬WebSocket鐨勬枃绔狅細銆愪弗閫?浼樿川鏂囩珷銆戝紑鍙戣€呭繀鐭ュ繀鐭ョ殑WebSocket鍗忚Python濡備綍鐖彇瀹炴椂鍙樺寲鐨刉ebSocket鏁版嵁WebSocket浠庡叆闂ㄥ埌鍐欏紑婧愬簱锛屻€娿€愪弗閫?楂樿川閲忔枃绔犮€戝紑鍙戣€呭繀鐭ュ繀浼氱殑 WebSocket 鍗忚銆嬩粙缁嶄簡鐩稿叧鐨勫崗璁鑼冪殑鐭ヨ瘑銆傛湰鏂囧唴瀹瑰ぇ鑷村涓嬶細WebSocket鍗忚鐨勬潵婧怶ebSocket鍗忚鐨勪紭鐐筗ebSocket鍗忚瑙勮寖涓€浜涘疄鎴樹唬鐮佹紨绀哄鏋滄病鏈夋帉鎻ebSocket鍗忚鐨勬湅鍙嬶紝寤鸿鍏堥槄璇绘湰鏂囷紝鐗瑰埆鏄WebSocket鍗忚瑙勮寖鐨勪粙缁嶃€傛兂瑕佸皢鍗忚瑙勮寖RFC6455鍙樻垚寮€婧愬簱锛岀涓€姝ュ氨鏄鐔熸倝鏁翠釜鍗忚瑙勮寖锛屾墍浠ラ渶瑕侀槄璇汇€愪弗閫?浼樿川鏂囩珷銆戝紑鍙戣€呭繀鐭ョ殑WebSocket鍗忚銆傚綋鐒讹紝鏈夎兘鍔涚殑鍚屽鐩存帴闃呰RFC6455涔熸湭灏濅笉鍙€傜劧鍚庝綘闇€瑕佷簡瑙g紪绋嬭瑷€涓唴缃簱Socket鐨勫熀鏈敤娉曪紝姣斿Python涓殑socket鎴栬€呮洿楂樼骇鏇存祦琛岀殑Streams銆乀ransports鍜孭rotocols銆傚鏋滀綘鏄疓o寮€鍙戣€咃紝Rust寮€鍙戣€咃紝璇锋壘瀵瑰簲璇█鐨勫唴缃簱銆傚亣璁句綘宸茬粡鐔熸倝RFC6455锛屼綘搴旇鐭ラ亾Frame鍦ㄦ墦鍖呭拰瑙e寘鏃堕渶瑕佷娇鐢ㄤ綅鎿嶄綔銆傛濂?鍒嗛挓鍓嶅啓浜嗕竴绡囦綅杩愮畻鐩稿叧鐨勬枃绔狅紝褰诲簳鐞嗚В浣嶈繍绠椼€傝嚦浜庡叾浠栫殑锛岃刀绱у涔犲惂锛佺敤浜嶱ython缃戠粶閫氫俊鐨凷treamsWebSocket涔熷彲浠ョ悊瑙d负WEB搴旂敤涓娇鐢ㄧ殑Socket锛屼篃灏辨槸璇存湰鏂囧皢娑夊強鍒癝ocket缂栫▼銆備笂闈㈣浜哖ython涓笌Socket鐩稿叧鐨勬湁socket銆丼treams銆乀ransports鍜孭rotocols銆傚叾涓璼ocket鏄悓姝ョ殑锛屽彟澶栦袱涓槸寮傛鐨勩€傝繖涓や釜灞炰簬澶у缁忓父鍚埌鐨刟syncio銆係ocket閫氫俊杩囩▼Socket鏄鍒扮鐨勯€氫俊锛屾墍浠ユ垜浠寮勬竻妤氭秷鎭槸濡備綍浠庝竴鍙版満鍣ㄥ彂閫佸埌鍙︿竴鍙版満鍣ㄧ殑锛岃繖涓€鐐瑰緢閲嶈銆傚亣璁鹃€氫俊鐨勪袱鍙版満鍣ㄥ垎鍒槸Client鍜孲erver锛孋lient鍚慡erver鍙戦€佹秷鎭殑杩囩▼濡備笅鍥炬墍绀猴細Client閫氳繃鏂囦欢鎻忚堪绗︾殑璇诲啓APIread&write璁块棶鎿嶄綔绯荤粺鍐呮牳涓殑缃戠粶妯″潡骞跺垎閰嶅綋鍓嶅鎺ュ瓧鍙戦€佸彂閫佺紦鍐插尯鍜屾帴鏀舵帴鏀剁紦鍐插尯缂撳瓨銆侰lient杩涚▼鍚戝唴鏍哥殑鍙戦€佺紦鍐插尯鍐欏叆娑堟伅锛屽唴鏍稿皢鍙戦€佺紦鍐插尯涓殑鏁版嵁浼犺緭鍒扮墿鐞嗙‖浠禢IC锛屽嵆NetworkInterfaceCircuit銆侼IC璐熻矗灏嗚浆鎹㈠悗鐨勬ā鎷熶俊鍙烽€氳繃缃戠粶纭欢浼犻€掑埌鏈嶅姟鍣ㄧ‖浠剁殑NIC銆傛湇鍔″櫒鐨勭綉鍗″啀灏嗘ā鎷熶俊鍙疯浆鎹㈡垚瀛楄妭鏁版嵁锛屽瓨鍏ュ唴鏍镐负濂楁帴瀛楀垎閰嶇殑鎺ユ敹缂撳啿鍖轰腑銆傛渶鍚庯紝鏈嶅姟鍣ㄨ繘绋嬩粠鎺ユ敹缂撳啿鍖轰腑璇诲彇鏁版嵁浣滀负婧愬鎴风杩涚▼浼犻€掔殑娑堟伅銆備互涓婇€氫俊杩囩▼鐨勬弿杩板拰鍥剧墖鍧囨潵鑷挶鏂囧搧瀵筊PC浜や簰杩囩▼鐨勬繁鍏ョ悊瑙c€傛垜璇曞浘鎵惧埌閫氫俊杩囩▼涓瘡涓€姝ョ殑渚濇嵁锛堝挨鍏舵槸sendbuffertoNICtorecvbuffer锛夛紝锛堟垜鐪嬩簡TCP鍜孠ernel.org鐨凴FC锛夛紝鍙儨娌℃壘鍒板己鏈夊姏鐨勮瘉鏄庯紙涓€瀹氭槸metoodish锛夛紝鏈夌煡閬撶殑璇疯瘎璁烘垨鑰呭彂閭欢鍒皕enrusts@sina.com鍛婅瘔鎴戯紝鎴戝彲浠ュ啀灞曞紑涓€绡囥€傚垱寤篠treams閭d箞闂鏉ヤ簡锛氭垜浠浣曞湪Python涓疄鐜扮鍒扮鐨勬秷鎭彂閫侊紵绛旓細Python鎻愪緵浜嗕竴浜涘璞℃潵甯姪鎴戜滑瀹炵幇杩欎釜闇€姹傦紝鍏朵腑Streams鏄瘮杈冨ソ鐢ㄧ殑銆傛祦鏄疨ython寮傛I/O涓彁渚涚殑楂樼骇API銆侾ython瀹樻柟鏂囨。瀵筍treams鐨勪粙缁嶅涓嬶細Streams鏄敤浜庡鐞嗙綉缁滆繛鎺ョ殑楂樼骇寮傛/绛夊緟灏辩华鍘熻銆傛祦鍏佽鍦ㄤ笉浣跨敤鍥炶皟鎴栦綆绾у崗璁拰浼犺緭鐨勬儏鍐典笅鍙戦€佸拰鎺ユ敹鏁版嵁銆傝鎴戠炕璇戜竴涓嬶細娴佹槸鐢ㄤ簬缃戠粶鐨勯珮绾у紓姝?绛夊緟灏辩华鍘熻銆傛祦鍏佽鍦ㄤ笉浣跨敤鍥炶皟鎴栦綆绾у崗璁拰浼犺緭鐨勬儏鍐典笅鍙戦€佸拰鎺ユ敹鏁版嵁銆侾ython鎻愪緵浜哸syncio.open_connection()鏉ヨ寮€鍙戣€呭垱寤篠treams銆俛syncio.open_connection()灏嗗缓绔嬬綉缁滆繛鎺ュ苟杩斿洖reader鍜寃riter瀵硅薄锛屽畠浠疄闄呬笂鏄疭treamReader鍜孲treamWriter绫荤殑瀹炰緥銆傚紑鍙戣€呭彲浠ヤ娇鐢⊿treamReader浠嶪O娴佷腑璇诲彇鏁版嵁锛屼娇鐢⊿treamWriter鍚慖O娴佷腑鍐欏叆鏁版嵁銆傝櫧鐒舵枃妗f病鏈夌粰鍑篒O娴佺殑鏄庣‘瀹氫箟锛屼絾鎴戠寽鎯冲拰buffer鏈夊叧锛堝氨鏄痵endbuffertoNICtorecvbuffer涓殑buffer锛夛紝涔熷彲浠ユ娊璞$殑璁や负鏄痓uffer銆備娇鐢⊿treams锛屽彲浠ュ畬鏁村湴瀹炵幇绔埌绔秷鎭紶閫掋€傝鎴戜滑閫氳繃涓€涓緥瀛愭潵鐔熸倝Streams鐨勭敤娉曞拰鐢ㄩ€斻€傝繖鏄疨ython瀹樻柟鏂囨。涓粰鍑虹殑鍙岀绀轰緥銆傜涓€涓槸鏈嶅姟鍣ㄧ锛?TCPechoserverusingstreams#reader.read(100)message=data.decode()addr=writer.get_extra_info('peername')print(f"Received{message!r}from{addr!r}")print(f"Send:{message!r}")writer.write(data)awaitwriter.drain()print("Closetheconnection")writer.close()asyncdefmain():鏈嶅姟鍣?awaitasyncio.start_server(handle_echo,'127.0.0.1',8888)addr=server.sockets[0].getsockname()print(f'Servingon{addr}')涓庢湇鍔″櫒寮傛锛歛waitserver.serve_forever()asyncio.run(main())followedbyClient:#TCPechoclientusingstreams#鏈枃鏉ヨ嚜銆奛ightTeam銆嬭浆杞借鑱旂郴鑾峰彇鎺堟潈importasyncioasyncdeftcp_echo_client(message):reader,writer=awaitasyncio.open_connection('127.0.0.1',8888)print(f'Send:{message!r}')writer.write(message.encode())data=awaittreader.read(100)print(f'Received:{data.decode()!r}')print('鍏抽棴杩炴帴')writer.close()asyncio.run(tcp_echo_client('HelloWorld!'))灏嗙ず渚嬪垎鍒啓鍏erver.py鍜宑lient.py锛岀劧鍚庝緷娆¤繍琛屻€傛鏃秙erver.py鐨勭獥鍙d細杈撳嚭濡備笅鍐呭锛歋ervingon('127.0.0.1',8888)Received'HelloWorld!'from('127.0.0.1',59534)Send:'HelloWorld!'鍏抽棴杩炴帴浠庤緭鍑烘垜浠煡閬撴湇鍔″惎鍔ㄧ殑鍦板潃鍜岀鍙f槸('127.0.0.1',8888),from('127.0.0.1',59534)璇诲彇鍐呭涓篐elloWorld!鐨勬秷鎭紝杩斿洖HelloWorld!to('127.0.0.1',59534)锛屾渶鍚庡叧闂繛鎺ャ€俢lient.py鐨勭獥鍙h緭鍑哄涓嬶細Send:'HelloWorld!'Received:'HelloWorld!'鍏抽棴杩炴帴杩炴帴寤虹珛鍚庯紝Client鍙戦€佹秷鎭紝鍐呭涓篐elloWorld!鍒版寚瀹氱殑涓€绔紝鐒跺悗浠庢寚瀹氱殑涓€绔敹鍒板唴瀹逛负HelloWorld!鐨勬秷鎭紝鏈€鍚庡叧闂繛鎺ャ€傛湁鐨勮鑰呭彲鑳戒笉鏄庣櫧锛屼负浠€涔圕lient瑕佸彂閫丠elloWorld锛?鏈嶅姟鍣ㄤ篃鍙戦€丠elloWorld!鏀跺埌鍚庡彂缁欏鎴枫€傚弻绔殑Send鍜孯eceived閮芥槸HelloWorld锛侊紝杩欏緢瀹规槗璁╂柊鎵嬫劅鍒板洶鎯戙€傚叾瀹炶繖鏄竴涓櫘閫氱殑echoserver鐨勪緥瀛愶紝涔熷氨鏄褰揝erver鏀跺埌娑堟伅鍚庯紝灏嗘秷鎭唴瀹瑰師灏佷笉鍔ㄧ殑杩斿洖缁機lient銆傝繖鍙槸涓轰簡婕旂ず锛屽苟娌℃湁鍏朵粬鐩殑锛屼絾鏄繖鏍风殑渚嬪瓙浼氱粰鏂版墜閫犳垚鍥版儜銆備互涓婂氨鏄竴涓畝鍗曠殑Socket缂栫▼渚嬪瓙锛屾暣浣撴€濊矾杩樻槸寰堝鏄撶悊瑙g殑銆傛帴涓嬫潵锛屾垜浠皢閫愭瑙h绀轰緥涓殑浠g爜锛?鍦╟lient.py涓娇鐢╜asyncio.open_connection()`杩炴帴鎸囧畾绔紝鑾峰彇reader鍜寃riter杩欎袱涓璞°€?鐒跺悗浣跨敤writer瀵硅薄涓殑`write()`鏂规硶灏哷HelloWorld!`鍐欏叆IO娴侊紝娑堟伅灏嗗彂閫佸埌Server銆?鐒跺悗浣跨敤reader瀵硅薄涓殑`read()`鏂规硶浠嶪O娴佷腑璇诲彇娑堟伅骞跺皢娑堟伅鎵撳嵃鍒扮粓绔€傜湅鍒拌繖閲岋紝浣犲彲鑳戒細鏈夊彟澶栦竴涓枒闂細write()鍙槸灏嗘秷鎭啓鍏O娴侊紝骞舵病鏈夊彂閫侊紝閭d箞娑堟伅鏄浣曚紶杈撳埌鏈嶅姟鍣ㄧ殑鍛紵鐢变簬鎴戜滑鏃犳硶鐩存帴閬靛惊CPython婧愪唬鐮侊紝鍥犳鏃犳硶鑾峰緱鍑嗙‘鐨勭粨鏋溿€備絾鏄垜浠彲浠ヨ窡杩汸ython浠g爜锛岀煡閬撴秷鎭渶缁堟槸浼犻€掔粰transport.write()鐨勶紝濡傛灉鎯充簡瑙f洿澶氬彲浠ョ湅Transports鍜孭rotocols鐨勪粙缁嶃€傚彲浠ユ妸杩欎釜杩囩▼鎶借薄涓轰笂鍥句腑鐨凜lient鍙戦€乥uffer缁橬IC锛宺ecvbuffer缁橲erver銆傚姛鑳芥ā鍧楄璁¢€氳繃涓婇潰鐨勫涔狅紝鐜板湪浣犲凡缁忔帉鎻′簡WebSocket鍗忚瑙勮寖鍜孭ythonStreams鐨勫熀鏈敤娉曪紝鎺ヤ笅鏉ュ氨鍙互璁捐WebSocket瀹㈡埛绔簱浜嗐€傛牴鎹甊FC6455鐨勫崗璁紝WebSocket涔嬪墠鏄疕TTP锛岄€氳繃鈥滄彙鎵嬧€濆崌绾у崗璁€傚崗璁崌绾у悗锛岃繘鍏ョ湡姝g殑WebSocket閫氫俊锛岄€氫俊鍖呮嫭鍙戦€侊紙Send锛夊拰鎺ユ敹锛圧ecv锛夈€傛枃鏈秷鎭湪浼犺緭鍓嶉渶瑕佽浆鎹负Frames锛屾帴鏀舵柟闃呰娑堟伅鍚庨渶瑕佸皢Frames杞崲涓烘枃鏈€傚綋鐒讹紝鏈熼棿浼氬嚭鐜颁竴浜涘紓甯革紝鎴戜滑鍙兘闇€瑕佽嚜瀹氫箟寮傚父鏉ュ揩閫熷畾浣嶉棶棰樸€傜幇鍦ㄦ垜浠湁鍑犱釜妯″潡锛?Handshake-ShakeHands*Transmission-Transports*Frameprocessing-Frames*Exception-Exceptions涓€鍒囧氨缁悗锛屽氨鍙互杩涘叆鐪熸鐨勭紪鐮佺幆鑺備簡銆傜敱浜庡疄闄呯紪鐮佸お闀匡紝鎴戝喅瀹氭斁鍦ㄤ笅涓€鏈熴€傝鑰呭彲鑳介渶瑕佽姳涓€浜涙椂闂存潵鍚告敹鏈湡鐨勫唴瀹广€傛€荤粨寮€澶存垜寮鸿皟浜嗏€滃垱鎰忚兘鍔涒€濈殑閲嶈鎬э紝杩樻姏鍑轰簡涓€浜涗笉鎭板綋鐨勪緥瀛愶紝浣嗘垜鍙兂鍛婅瘔浣狅紝涓嶈鍋氳皟鏁答煇躲€傞偅鎴戝憡璇変綘锛岃繖绡囨枃绔犳槸鍏充簬WebSocket鐨勩€傜劧鍚庢垜鍛婅瘔浣狅紝瑕佹帉鎻ebSocket鍗忚锛屽鏋滀綘涓嶈兘鐙珛瀹屾垚RFC6455锛屼綘涔熷彲浠ョ湅鐪嬫垜鍐欑殑鍑犵瘒鍏充簬WebSocket鍜屼綅鎿嶄綔鐨勬枃绔犮€傚嚑鍒嗛挓鍚庯紝Socket閫氫俊杩囩▼灏卞睍绀虹粰浣犱簡銆傝櫧鐒舵病鏈夊己鏈夊姏鐨勪緷鎹紝浣嗘偍鍙互鍋囪杩欐槸姝g‘鐨勩€傚枬瀹屼竴鏉櫧寮€姘达紝缁欏ぇ瀹跺睍绀篠treams鐨勫叿浣撶敤娉曪紝涓哄ぇ瀹惰瑙d唬鐮佺殑浣滅敤銆傞噸瑕佺殑鏄妸Streams鍜孲ocket鐨勯€氫俊杩囩▼鎶借薄鍑烘潵銆傝繖浜涘墠鎻愭潯浠剁‘瀹氫箣鍚庯紝鎴戝氨甯﹀ぇ瀹惰刀绱ц璁ebSocket瀹㈡埛绔殑鍔熻兘妯″潡銆備笅绡囨枃绔犲皢杩涘叆瀹為檯浠g爜锛岃鍑嗗濂界幆澧冿紙Python3.6+锛夈€傛€讳箣锛屾兂瑕佺炕杩囧墠闈㈢殑灞憋紝灏辫窡鎴戞潵鍚э紒鏂囩珷浣滆€咃細銆婂闃烴ightTeam銆嬧€斺€旈瓘涓栦笢澶滈槦鎴愮珛浜?019骞达紝鍥㈤槦鎴愬憳鍖呮嫭宕斿簡鎵嶃€佸懆瀛愬銆侀檲绁ュ畨銆佸攼涓€椋炪€佸啹鐜€佽敗杩涖€佹埓榛勯敠銆佸紶鍙堕潚銆侀瓘涓栦笢.娑夊強鐨勪富瑕佺紪绋嬭瑷€鏈塒ython銆丷ust銆丆++銆丟o锛岄鍩熸兜鐩栫埇铏€佹繁搴﹀涔犮€佹湇鍔″紑鍙戙€佸璞″瓨鍌ㄧ瓑銆傚洟闃熸棤鍠勬棤鎭讹紝鍙仛瀵圭殑浜嬶紝璇锋厧閲嶃€?/p>