国产日韩欧美一区二区三区综合,日本黄色免费在线,国产精品麻豆欧美日韩ww,色综合狠狠操

極客小將

您現(xiàn)在的位置是:首頁 » scratch編程資訊

資訊內(nèi)容

用Scratch+Python做一個(gè)聯(lián)網(wǎng)游戲

極客小將2021-03-22-
Scratch2有一個(gè)擴(kuò)展功能,可以讓Scratch和第三方應(yīng)用通過http連接起來,實(shí)現(xiàn)訪問網(wǎng)站數(shù)據(jù)、控制硬件等應(yīng)用。我們今天就使用這個(gè)擴(kuò)展,連接到一個(gè)用Python實(shí)現(xiàn)的網(wǎng)絡(luò)服務(wù),來做一個(gè)聯(lián)網(wǎng)游戲。希望大家能通過今天的學(xué)習(xí)了解一些網(wǎng)絡(luò)編程的基本知識(shí),以及知道要做出一個(gè)比較復(fù)雜的系統(tǒng)要

Scratch2有一個(gè)擴(kuò)展功能,可以讓Scratch和第三方應(yīng)用通過http連接起來,實(shí)現(xiàn)訪問網(wǎng)站數(shù)據(jù)、控制硬件等應(yīng)用。我們今天就使用這個(gè)擴(kuò)展,連接到一個(gè)用Python實(shí)現(xiàn)的網(wǎng)絡(luò)服務(wù),來做一個(gè)聯(lián)網(wǎng)游戲。希望大家能通過今天的學(xué)習(xí)了解一些網(wǎng)絡(luò)編程的基本知識(shí),以及知道要做出一個(gè)比較復(fù)雜的系統(tǒng)要關(guān)心的方面。

我們先用Scratch做一個(gè)大富翁游戲:有兩個(gè)以上的游戲角色(這個(gè)例子里是一只貓和一只狗)分別由兩臺(tái)電腦控制。角色輪流滾動(dòng)色子走動(dòng),走動(dòng)的步數(shù)由骰子的點(diǎn)數(shù)隨機(jī)決定。走動(dòng)途中會(huì)碰到不同的魔術(shù)指令可以改變走動(dòng)的路徑、加分等等。誰先走到終點(diǎn)就算贏。游戲畫面如下所示:

upload/article/images/2021-03-22/bfbe9e0ce3d5bd9aacee59e144a2f010.jpg

系統(tǒng)結(jié)構(gòu)圖

有兩個(gè)玩家情況下的系統(tǒng)架構(gòu)圖如下所示:

upload/article/images/2021-03-22/5022df9dcf610df1a2d4ce77971ecc95.jpg

我們這里說的系統(tǒng)架構(gòu)圖是一個(gè)計(jì)算機(jī)系統(tǒng)的設(shè)計(jì)圖。描述的對(duì)象包括直接構(gòu)成系統(tǒng)的各個(gè)硬件和軟件組件,以及各個(gè)組件之間的連接和通訊方法。

系統(tǒng)架構(gòu)圖是構(gòu)建計(jì)算機(jī)系統(tǒng)實(shí)踐的基礎(chǔ),與建筑師在開始建設(shè)前必須完成的設(shè)計(jì)圖紙一樣重要。現(xiàn)代的大型計(jì)算機(jī)系統(tǒng)就如同一個(gè)復(fù)雜龐大的建筑,完成它需要多方面的計(jì)算機(jī)網(wǎng)絡(luò)、硬件和軟件配合以及涉及大量的知識(shí)。如果正式搭建之前沒有想好系統(tǒng)架構(gòu)和設(shè)計(jì)細(xì)節(jié),往往會(huì)導(dǎo)致事倍功半,甚至在項(xiàng)目后期才發(fā)現(xiàn)無法解決的問題而不得不推倒重來。

大家編程的過程中如果涉及多個(gè)組件(或?qū)ο螅貏e是如果涉及網(wǎng)絡(luò)的編程,在開始寫程序之前請(qǐng)務(wù)必通過畫出系統(tǒng)架構(gòu)圖來理清各組件之間的關(guān)系。

架構(gòu)圖等計(jì)算機(jī)設(shè)計(jì)圖表是用來輔助我們理解、維護(hù)計(jì)算機(jī)系統(tǒng)以及方便我們和其他部門溝通交流的,對(duì)于圖表的格式,不同的單位可能會(huì)有不同的要求,總的來說只要方便相關(guān)的人員理解就行。比較著名的一種格式叫做統(tǒng)一建模語言(Unified Modeling Language, UML),可以進(jìn)一步學(xué)習(xí)了解。

上面的架構(gòu)圖說明了在有兩個(gè)玩家的情況下,網(wǎng)絡(luò)里會(huì)有:

3個(gè)硬件:

  • 一臺(tái)服務(wù)器

  • 兩臺(tái)個(gè)人電腦

兩臺(tái)個(gè)人電腦實(shí)際上是可以直接連接起來實(shí)現(xiàn)聯(lián)網(wǎng)對(duì)戰(zhàn)的。為什么需要一臺(tái)服務(wù)器那么復(fù)雜呢?原因是:如果其中一個(gè)玩家沒開電腦,沒有服務(wù)器的話,另一個(gè)玩家需要找一個(gè)新玩家的話就不是那么容易了。就算找到了新玩家,兩臺(tái)電腦之間還需要重新設(shè)置網(wǎng)絡(luò)參數(shù)以實(shí)現(xiàn)聯(lián)網(wǎng)。這對(duì)于沒有多少電腦知識(shí)只想簡(jiǎn)簡(jiǎn)單單玩?zhèn)€游戲的人來說非常困難。而服務(wù)器一般都是7*24小時(shí)穩(wěn)定提供服務(wù)的,在游戲開發(fā)時(shí)設(shè)置好服務(wù)器地址后,任意一個(gè)玩家打開游戲就可以連上同一個(gè)服務(wù)器,再通過服務(wù)器尋找其他在線的玩家一起玩了。

5個(gè)軟件組件:

  • 服務(wù)器里的Python服務(wù)端(實(shí)現(xiàn)聯(lián)網(wǎng)游戲的協(xié)作和數(shù)據(jù)共享)

  • 每臺(tái)電腦上的Python客戶端(負(fù)責(zé)和服務(wù)器連接,是服務(wù)器和Scratch游戲之間溝通的橋梁)

  • 每臺(tái)電腦上的Scratch游戲端(負(fù)責(zé)展示游戲畫面)

上面的架構(gòu)圖還說明了不同部件之間的連接協(xié)議。這里的協(xié)議可以理解為部件之間溝通的一種語言。Scratch游戲不能直接和Python語言寫的客戶端溝通;Python語言寫的客戶端和服務(wù)端分布在網(wǎng)絡(luò)的兩端,它們之間的溝通也不像在同一臺(tái)電腦上溝通那么簡(jiǎn)單(比如不能直接訪問文件),這就需要根據(jù)需求選擇溝通協(xié)議。

Scratch的擴(kuò)展規(guī)定了只能使用http協(xié)議,所以第三方應(yīng)用必須要使用http協(xié)議才能和Scratch游戲溝通。用Python可以很容易地寫一個(gè)支持http協(xié)議的應(yīng)用。

Python客戶端和服務(wù)端可以選擇的連接協(xié)議就非常之多了。我們沒有選擇最方便的http協(xié)議是因?yàn)閔ttp協(xié)議只能單向請(qǐng)求,即只能等客戶端向服務(wù)端發(fā)起請(qǐng)求之后服務(wù)端才能給客戶端發(fā)送信息,服務(wù)端不能主動(dòng)隨時(shí)向客戶端發(fā)送信息。我們的聯(lián)網(wǎng)游戲需要頻繁地雙向溝通,這種協(xié)議并不是太適合。

我們選擇了websocket作為python客戶端和服務(wù)端的溝通協(xié)議。Websocket的連接方式和http一樣,只需要服務(wù)端定義好連接接口,不需要在客戶端進(jìn)行額外的網(wǎng)絡(luò)設(shè)置。連接后客戶端和服務(wù)端之間可以隨時(shí)互相發(fā)送消息了。

網(wǎng)絡(luò)基本知識(shí)

1.??Http

Http(超文本傳輸協(xié)議)應(yīng)該是大家日常接觸到的最多的互聯(lián)網(wǎng)技術(shù)。你用瀏覽器打開任意一個(gè)網(wǎng)頁都會(huì)在地址欄里看到http這四個(gè)字母。

upload/article/images/2021-03-22/480e382b261d98864573211f0fb5a9cb.jpg

http是用來在網(wǎng)絡(luò)間傳輸諸如網(wǎng)頁、數(shù)據(jù)等信息的應(yīng)用層協(xié)議。它最初用于瀏覽器和服務(wù)器之間的通信,現(xiàn)在也廣泛用于各種網(wǎng)絡(luò)組件之間通信。不懂http就幾乎等于不懂網(wǎng)絡(luò)編程。http遵循經(jīng)典的客戶端-服務(wù)端模型,客戶端打開一個(gè)連接發(fā)出http請(qǐng)求,然后等待服務(wù)器端的響應(yīng)。

2.??地址

每個(gè)http服務(wù)都要綁定到一個(gè)地址以接收請(qǐng)求,比如百度網(wǎng)站的地址是http://www.baidu.com。也就是說百度網(wǎng)站的服務(wù)器地址是www.baidu.com。這種地址叫做域名。可以理解為一個(gè)人在網(wǎng)絡(luò)上注冊(cè)的名字。注意這個(gè)名字和我們?nèi)说拿钟悬c(diǎn)不同的是,它在互聯(lián)網(wǎng)上是獨(dú)一無二的。

還有一種地址叫做IP地址,比如183.232.231.173。IP地址就像人的身份證號(hào)。它是互聯(lián)網(wǎng)上每臺(tái)設(shè)備的獨(dú)一無二的身份識(shí)別碼。每個(gè)域名都要映射到一個(gè)IP地址上才能使用?;ヂ?lián)網(wǎng)是先有IP地址再有域名的。由于IP地址太難記了,人們發(fā)明了域名來方便人們記住不同的網(wǎng)站。

要知道一個(gè)網(wǎng)站的IP地址很簡(jiǎn)單,在Windows菜單欄里輸入‘CMD’打開命令提示符,然后輸入ping和空格再加上網(wǎng)站的域名就可以了。比如下面的命令找到了百度網(wǎng)站的IP地址就是183.232.231.173:

upload/article/images/2021-03-22/55e06d9919a90d4c3c29af1383764c02.jpg

3.??端口

一臺(tái)擁有IP地址的服務(wù)器可以提供許多服務(wù),比如網(wǎng)站服務(wù)、文件傳輸服務(wù)FTP、郵件服務(wù)SMTP等,這些服務(wù)完全可以通過1個(gè)IP地址來實(shí)現(xiàn)。那么,服務(wù)器是怎樣區(qū)分不同的網(wǎng)絡(luò)服務(wù)呢?顯然不能只靠IP地址,因?yàn)镮P?地址與網(wǎng)絡(luò)服務(wù)的關(guān)系是一對(duì)多的關(guān)系。實(shí)際上是通過“IP地址+端口號(hào)”來區(qū)分不同的服務(wù)的。為了在一臺(tái)設(shè)備上可以運(yùn)行多個(gè)程序,人為的設(shè)計(jì)了端口(Port)的概念,類似的例子是公司內(nèi)部的分機(jī)號(hào)碼。

一個(gè)網(wǎng)絡(luò)設(shè)備可以有65536個(gè)端口,0-1024之間多被操作系統(tǒng)占用,所以實(shí)際編程時(shí)一般采用1024以后的端口號(hào)。

要訪問同一個(gè)網(wǎng)站的不同端口可以簡(jiǎn)單地在地址后面加冒號(hào)(:)和端口號(hào),如訪問百度的80端口:http://www.baidu.com:80

HTTP服務(wù)的默認(rèn)端口是80和443,也就是說打開http://www.baidu.com實(shí)際上是打開http://www.baidu.com:80或http://www.baidu.com:443,只不過瀏覽器很聰明地幫我們把補(bǔ)充了80或443端口。

????4.? Websocket

HTTP的一個(gè)局限性是只能從客戶端向服務(wù)端發(fā)起請(qǐng)求,服務(wù)端不能主動(dòng)向客戶端發(fā)去消息。在有些時(shí)候,如一個(gè)玩家完成了一個(gè)動(dòng)作之后,我們希望另一個(gè)玩家可以馬上收到消息繼續(xù)進(jìn)行下一個(gè)動(dòng)作,這種時(shí)候就需要游戲服務(wù)器主動(dòng)向客戶端發(fā)送消息了。Websocket協(xié)議是一個(gè)簡(jiǎn)單的解決方法,它用起來和HTTP類似,也是需要客戶端和服務(wù)端。

Scratch擴(kuò)展的溝通協(xié)議

Scratch擴(kuò)展的溝通協(xié)議有專門的規(guī)范。

首先,需要建立一個(gè)“.s2e”描述文件來定義擴(kuò)展積木。該文件是json格式的。然后把該文件導(dǎo)入到Scratch里面生成擴(kuò)展積木。導(dǎo)入方法是在scratch里按住鍵盤“Shift”鍵然后點(diǎn)擊“文件”,然后選擇“導(dǎo)入實(shí)驗(yàn)性HTTP擴(kuò)展功能”,接著選擇你的“.s2e”文件就可以了。導(dǎo)入成功后在“更多積木”那里就能看到自定義的積木了。

upload/article/images/2021-03-22/d7e2bad3adfa7e0fb8bd8dfc6d7aaf9c.jpg

下面是一個(gè)“.s2e”文件例子:

upload/article/images/2021-03-22/29037697ce7d1fe74612230c2170d1d9.jpg

導(dǎo)入后會(huì)在“更多積木”類別那里看到:?

upload/article/images/2021-03-22/3ccf590efc38a1c44323677f476f289b.jpg

第一行:"Extension Example"就是顯示的擴(kuò)展積木模塊名稱。

第二行:12345是http客戶端的端號(hào)。這個(gè)擴(kuò)展積木會(huì)訪問本地電腦的12345 http端口來通信,即http://localhost:12345/

第三行開始定義不同的積木。

第四行定義了一個(gè)執(zhí)行命令積木,它在scratch里面的顯示名稱是“partner moved”,當(dāng)該積木被執(zhí)行的時(shí)候會(huì)發(fā)送一個(gè)http請(qǐng)求到http://localhost:12345/partnerMoved地址里。最后一個(gè)參數(shù)就是該請(qǐng)求的地址。

第五行定義了一個(gè)設(shè)置命令參數(shù),它會(huì)把“set character to_”里的“_”傳輸出去。如執(zhí)行“set character to 3”積木就會(huì)發(fā)一個(gè)http請(qǐng)求到http://localhost:12345/setChar/3 地址去。

第六行是一個(gè)從http服務(wù)端取得當(dāng)前參數(shù)返回值的命令。第一個(gè)參數(shù)“r”代表他是一個(gè)“報(bào)告”指令,它可以取得“getCharacter”的值。注意這里取值并不是直接發(fā)一條getCharacter請(qǐng)求到http服務(wù)端,而是從最近的一次http://localhost:12345/poll請(qǐng)求里取出getCharacter指令的值。關(guān)于“/poll”請(qǐng)求請(qǐng)看下面詳細(xì)說明:

/poll 請(qǐng)求

Scratch每秒鐘大概發(fā)30條“/poll”請(qǐng)求到http服務(wù)端,并從“/poll”請(qǐng)求的回應(yīng)報(bào)文那里獲取最新的參數(shù)值。http服務(wù)端要通知Scratch的任何信息或結(jié)果都需要通過“/poll”回應(yīng)報(bào)文來傳送。每一對(duì)返回參數(shù)和返回值占一行,兩對(duì)之間通過“/n”行結(jié)束符分隔。返回參數(shù)和返回值之間要有一個(gè)空格。如下面的回應(yīng)報(bào)文:

getCharacter abc

age 12

它返回兩個(gè)參數(shù):getCharacter的值是abc,age的值是12。getCharacter的值可以通過上面的第六行定義的“

upload/article/images/2021-03-22/f4b27aa63d9b73fe2ce24b646605428d.jpg

”積木獲取。

/reset_all 請(qǐng)求

在Scratch里點(diǎn)擊結(jié)束的紅球時(shí)會(huì)觸發(fā)發(fā)一個(gè)“/reset_all”請(qǐng)求到http服務(wù)端??梢园岩恍┯螒蛑刂没蛲V箷r(shí)需要做的東西放到這個(gè)請(qǐng)求的處理模塊里。但是我的試驗(yàn)里有時(shí)候點(diǎn)綠旗也會(huì)觸發(fā)“/reset_all”請(qǐng)求,但并不是每次都會(huì)。所以如果需要在游戲沒有結(jié)束(不點(diǎn)擊紅球)時(shí)做一些重置動(dòng)作的話,保險(xiǎn)起見最好自己定義一個(gè)“reset”積木。

Scratch擴(kuò)展的一個(gè)關(guān)鍵點(diǎn)或者說限制條件是:Scratch只能通過poll請(qǐng)求從http服務(wù)端獲取信息,而不能通過其他請(qǐng)求或者指令。換一種說法,http服務(wù)端如果想要發(fā)消息給Scratch端,只能把消息內(nèi)容放在poll請(qǐng)求的回復(fù)里面。

我們要做的聯(lián)網(wǎng)游戲需要用到的Scratch擴(kuò)展溝通協(xié)議知識(shí)就是上面這些。接下來介紹一些聯(lián)網(wǎng)游戲的關(guān)鍵部分。不同模塊之間的溝通次序。我們用一種叫“順序圖”的圖表來描述這種關(guān)系。

順序圖

順序圖一般用于說明一個(gè)系統(tǒng)之間如何交互來實(shí)現(xiàn)一個(gè)使用場(chǎng)景,它體現(xiàn)的是系統(tǒng)不同組件之間如何按照時(shí)間順序互相配合來完成一個(gè)任務(wù)。它是一個(gè)二維圖,縱向是時(shí)間軸,時(shí)間沿豎線向下延伸。橫向代表了協(xié)作中各個(gè)組件。

我們來看一個(gè)查看可用角色功能的順序圖:

upload/article/images/2021-03-22/3232ad82314e5af2499912d596896395.jpg

“可用角色”這一信息保存在服務(wù)器端,所以每個(gè)游戲的界面(Scratch端)都要通過連接Python客戶端再連到服務(wù)器端去取得這個(gè)信息。順序圖的頂端是3個(gè)組件的名稱。每個(gè)組件都有一條縱向的生命線。生命線間用有方向的連線表示不同組件的協(xié)作。實(shí)線表示一個(gè)組件向另一個(gè)組件發(fā)起一個(gè)請(qǐng)求,箭頭方向表示請(qǐng)求的方向;虛線表示請(qǐng)求的結(jié)果返回。從上到下表示時(shí)間順序。上圖的意思是以下步驟按時(shí)間先后順序進(jìn)行:

1.?? Scratch游戲程序向Python客戶端(在同一臺(tái)電腦上通過http協(xié)議)發(fā)起一個(gè)checkAvailChar(檢查可用角色)的請(qǐng)求。

2.?? Scratch游戲程序執(zhí)行等待1秒鐘的指令。我們這里預(yù)期1秒內(nèi)從網(wǎng)絡(luò)中得到可用角色的返回值。

3.?? Python客戶端(在網(wǎng)絡(luò)上通過websocket協(xié)議)向服務(wù)器端發(fā)起一個(gè)checkAvailChar(檢查可用角色)的請(qǐng)求。這一步驟是和步驟2同步進(jìn)行的,我們沒辦法控制2和3的先后次序。

4.?? Python服務(wù)器端向客戶端返回步驟3的請(qǐng)求結(jié)果 - 可用角色。

5.?? Scratch游戲程序向Python客戶端發(fā)出poll請(qǐng)求。上面介紹過, 事實(shí)上Scratch游戲程序大概每秒鐘發(fā)出30條poll請(qǐng)求。只不過 Python客戶端只有在服務(wù)器端返回可用角色信息后才會(huì)把正確的值通過poll返回給Scratch游戲,在這之前Scratch游戲都只能取得一個(gè)不正確的值。

6.?? Python客戶端向Scratch端返回步驟5的請(qǐng)求結(jié)果 - 可用角色。只有客戶端已經(jīng)從服務(wù)器端取得正確的可用角色值后,它才能向Scratch端返回正確的結(jié)果。否則就返回默認(rèn)值。

7.?? Scratch游戲程序向Python客戶端發(fā)起一個(gè)setChar(設(shè)置角色)的請(qǐng)求。這個(gè)步驟是在‘步驟2 – 等待1秒’之后才會(huì)進(jìn)行的。并且圖里省略了Scratch游戲讓玩家選擇角色的步驟,因?yàn)檫@個(gè)流程圖重點(diǎn)在于描述不同系統(tǒng)組件間的協(xié)作。

上面是一個(gè)簡(jiǎn)單的順序圖介紹。順序圖對(duì)于編程人員非常重要,一個(gè)復(fù)雜的涉及多個(gè)組件的系統(tǒng)直接看程序的話通常很難理解。我寫這個(gè)小聯(lián)網(wǎng)游戲的過程中就有感覺,如果不看順序圖的話,經(jīng)常是昨天寫的程序今天已經(jīng)看得非常吃力了。同一個(gè)作者尚且如此,如果是不同部門、不同領(lǐng)域用不同語言寫的程序看起來就更加是天書一樣了。順序圖就提供了一種通用、簡(jiǎn)單、直白的語言來描述不同組件之間的聯(lián)系。這也是UML的核心作用或者說目標(biāo) – 提供一種統(tǒng)一的設(shè)計(jì)溝通語言。

畫順序圖還有一個(gè)好處就是它讓人可以更早地在寫程序之前真正深入地理清核心系統(tǒng)的邏輯關(guān)系,可以盡早地發(fā)現(xiàn)一些比較嚴(yán)重的邏輯錯(cuò)誤。計(jì)算機(jī)系統(tǒng)開發(fā)有一個(gè)重要規(guī)律是問題越早發(fā)現(xiàn)修改起來的需要的資源(費(fèi)用)就越低。一個(gè)簡(jiǎn)單的例子:一個(gè)設(shè)計(jì)錯(cuò)誤如果在測(cè)試階段才發(fā)現(xiàn)的話往往要花費(fèi)很多部門(設(shè)計(jì)、開發(fā)、測(cè)試)的精力才能修復(fù);如果設(shè)計(jì)階段已經(jīng)發(fā)現(xiàn)了就沒有開發(fā)、測(cè)試部門的重復(fù)勞動(dòng)了。

順序圖可以按不同的功能分開來畫,比如上面的圖只包括了檢查可用角色的功能。并且它不需要包括系統(tǒng)的所有邏輯順序,一些顯而易見的只是系統(tǒng)一個(gè)小組件內(nèi)部的步驟就不需要畫出來了。當(dāng)然這個(gè)要靠團(tuán)隊(duì)特別是設(shè)計(jì)師的經(jīng)驗(yàn)和能力來判斷了。對(duì)于初學(xué)者,所有涉及不同組件(比如分布在不同電腦的程序、或者使用不同語言寫的程序)的交互部分應(yīng)該都畫出順序圖來。

畫順序圖包括其他設(shè)計(jì)圖的大原則是方便交流和理解系統(tǒng)就行,并不需要花大量時(shí)間畫得很精美。它并不是最終用戶看到的東西。

Python http 服務(wù)器

我們用python自帶的HTTPServer類來做一個(gè)簡(jiǎn)單的可以接收http請(qǐng)求的服務(wù)器。這里的http服務(wù)器是位于Scratch和真正物理服務(wù)器中間的Python客戶端,即下面架構(gòu)圖中的紅色框部分:

upload/article/images/2021-03-22/528f2ac3bb2b999772ba79fc11002499.jpg

  1. 寫一個(gè)SimpleHTTPRequestHandler類來繼承python的BaseHTTPRequestHandler類:
    from http.server import BaseHTTPRequestHandler
    class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):

  2. SimpleHTTPRequestHandler重寫父類BaseHTTPRequestHandler的do_GET方法來處理http請(qǐng)求:
    def do_GET(self):

  3. do_GET方法根據(jù)請(qǐng)求地址的不同來返回不同的結(jié)果,比如收到‘/poll’請(qǐng)求就返回“hello“:

    def do_GET(self):

    ??????? ifself.path == '/poll':

    ??????? ????self.send_response(200)

    ??????? ????self.end_headers()
    ? ? ? ? ? ? self.wfile.write('hello'.encode('UTF-8'))

  4. 導(dǎo)入HTTPServer:
    from http.server import HTTPServer

  5. 實(shí)列化HTTPServer,它的地址是'localhost',端口是12345。'localhost'是一個(gè)特殊的地址,指向本地即自己,因?yàn)槲覀兊膕cratch游戲和這個(gè)http服務(wù)器是放在同一臺(tái)電腦上的。
    HTTPServer使用我們自己寫的SimpleHTTPRequestHandler來處理請(qǐng)求:
    httpd = HTTPServer(('localhost', 12345), SimpleHTTPRequestHandler)

  6. 讓這個(gè)服務(wù)器一直運(yùn)行:
    httpd.serve_forever()

  7. 現(xiàn)在簡(jiǎn)單的http服務(wù)器已經(jīng)起來了。可以用瀏覽器測(cè)試打開http://localhost:12345/poll?,瀏覽器會(huì)顯示“hello”就表示成功了。

接下來我們就可以根據(jù)“Scratch擴(kuò)展的溝通協(xié)議”來具體實(shí)現(xiàn)scratch游戲的python http 客戶端。記得把Scratch擴(kuò)展配置文件 - “.s2e”文件里的“extensionPort”端口配成http服務(wù)器的端口,就可以實(shí)現(xiàn)Scratch和http服務(wù)器的通信了。?

upload/article/images/2021-03-22/dac1d3821e989beb0139ec7dffc8fe52.jpg

更多關(guān)于python http服務(wù)的內(nèi)容請(qǐng)參考:

https://docs.python.org/3/library/http.server.html

Websocket 客戶端和服務(wù)端

我們使用了Aymeric Augustin的基于python asyncio的websocket實(shí)現(xiàn)。它使得使用websocket異常簡(jiǎn)單。下面是一個(gè)簡(jiǎn)單的websocket客戶端,它連接到位于本機(jī)即“l(fā)ocalhost”8765端口的websocket服務(wù)端,向它發(fā)送一句“Hello server”字符串:

import?asyncio

import?websockets

async?def?hello(uri):

??? async?with websockets.connect(uri) as websocket:

??????? await websocket.send("Hello server")

asyncio.get_event_loop().run_until_complete(

??? hello('ws://localhost:8765'))

下面是websocket服務(wù)端,它使用8765端口,當(dāng)接到客戶端的消息后就發(fā)送一句“Hello client”字符串:

import asyncioimport websockets?async def echo(websocket, path):??? async for message in websocket:??????? await websocket.send("Hello client")?asyncio.get_event_loop().run_until_complete(??? websockets.serve(echo,'localhost',8765))asyncio.get_event_loop().run_forever()

在我們的聯(lián)網(wǎng)游戲例子里,websocket客戶端就是Python客戶端,即下圖中紅框部分;而websocket服務(wù)端就是Python服務(wù)端,即下圖中藍(lán)框部分:

upload/article/images/2021-03-22/3ba1ae2dc7fcc61326d90dd4cfb546e4.jpg

? ? ??

聲明:本文章由網(wǎng)友投稿作為教育分享用途,如有侵權(quán)原作者可通過郵件及時(shí)和我們聯(lián)系刪除

預(yù)約試聽課

已有385人預(yù)約都是免費(fèi)的,你也試試吧...

主站蜘蛛池模板: 南华县| 武冈市| 安丘市| 三亚市| 定安县| 永新县| 牟定县| 湖南省| 新泰市| 任丘市| 台中县| 易门县| 大渡口区| 筠连县| 牡丹江市| 绵竹市| 郸城县| 镇宁| 炉霍县| 府谷县| 桦南县| 宜都市| 新安县| 当阳市| 长宁县| 湘乡市| 东阳市| 星子县| 突泉县| 阿拉善盟| 塘沽区| 浪卡子县| 六盘水市| 江川县| 澎湖县| 青阳县| 县级市| 商都县| 连平县| 涟源市| 合川市|