Palvelimen rakentaminen
Hyväksykää saapuvat yhteydet.
Palvelimen rakentaminen on ilmainen Lua Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Lua Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Lua Academy-kurssilla on yhteensä 4 oppituntia.
Palvelimen elinkaari
TCP-palvelin sitoo socketin osoitteeseen, kuuntelee yhteyksiä ja käsittelee sitten asiakkaita hyväksyvässä silmukassa.
LuaSocketissa luotte masterin kutsulla socket.tcp(), muutatte sen kuuntelevaksi palvelimeksi kutsuilla bind/listen ja poimitte asiakkaat jonosta kutsulla accept.
local socket = require("socket")
local server = assert(socket.tcp())Porttiin sitominen
server:bind(host, port) varaa paikallisen osoitteen. Käyttäkää arvoa "*" tai "0.0.0.0", jos haluatte hyväksyä yhteyksiä kaikista liitännöistä, tai arvoa "127.0.0.1", jos yhteydet sallitaan vain paikallisesti.
Bind epäonnistuu virheellä "address already in use", jos toinen prosessi käyttää porttia.
server:setoption("reuseaddr", true)
local ok, err = server:bind("*", 8080)
if not ok then error("bind failed: " .. err) endAsiakkaiden kuunteleminen
server:listen(backlog) merkitsee socketin passiiviseksi ja alkaa jonottaa saapuvia kättelyjä. Backlog ilmaisee odottavien yhteyksien enimmäismäärän.
Lyhyt muoto socket.bind(host, port, backlog) suorittaa bind- ja listen-vaiheet yhdellä kutsulla ja palauttaa valmiin palvelinobjektin.
local socket = require("socket")
local server = assert(socket.bind("*", 8080, 32))
print("listening on", server:getsockname())Yhteyden hyväksyminen
server:accept() odottaa, kunnes asiakas yhdistää, ja palauttaa sitten kyseistä vertaista varten uuden TCP-asiakasobjektin. Palvelinsocket jatkaa itse kuuntelemista.
Aikakatkaisulla varustetussa palvelinsocketissa accept palauttaa arvot nil, "timeout", joten voitte tehdä välillä myös muuta työtä.
local client, err = server:accept()
if client then
print("client from", client:getpeername())
endYhden asiakkaan palveleminen
Hyväksymisen jälkeen käsitelkää palautettua objektia aivan kuten asiakassocketia: vastaanottakaa pyyntöjä receive-kutsulla ja lähettäkää vastauksia send-kutsulla.
Asettakaa jokaiselle asiakassocketille oma aikakatkaisu, jotta yksi hidas asiakas ei voi pysäyttää koko palvelinta.
client:settimeout(10)
local line = client:receive("*l")
if line then client:send(line .. "\n") end
client:close()Hyväksymissilmukka
Perinteinen iteratiivinen palvelin toimii ikuisessa silmukassa: se hyväksyy asiakkaan, palvelee sitä, sulkee yhteyden ja toistaa tämän. Näin yksi asiakas käsitellään kerrallaan.
Ratkaisu on yksinkertainen ja toimiva, mutta se ei pysty palvelemaan samanaikaisia asiakkaita, koska hidas pyyntö estää kaikki sen jälkeen tulevat.
while true do
local c = server:accept()
if c then
local msg = c:receive("*l")
if msg then c:send(msg .. "\r\n") end
c:close()
end
endPienin kaikupalvelin
Kun osat yhdistetään, kaikupalvelin sitoo osoitteen, alkaa kuunnella ja palauttaa jokaisen asiakkaan ensimmäisen rivin kaikuna.
Tämä on pienin täydellinen LuaSocket-palvelin ja hyödyllinen tavoite aiemmin rakentamallenne asiakkaalle.
local socket = require("socket")
local s = assert(socket.bind("*", 8080))
while true do
local c = s:accept()
c:send((c:receive("*l") or "") .. "\r\n")
c:close()
endSamanaikaisuus select-kutsulla
Jos haluatte palvella useita asiakkaita samanaikaisesti ilman säikeitä, käyttäkää socket.select-kutsua. Se palauttaa lukemista varten valmiit socketit, myös kuuntelevan palvelinsocketin silloin, kun uusi asiakas odottaa.
Hallinnoitte aktiivisten asiakkaiden taulukkoa ja käsittelette vain niitä, joilla on tietoja, jolloin yksisäikeinen tapahtumasilmukka pysyy responsiivisena.
local readable = socket.select(watch, nil, 1)
for _, sock in ipairs(readable) do
if sock == server then
table.insert(watch, server:accept())
end
endEi-estävä accept
Asettakaa server:settimeout(0), jotta accept ei koskaan estä muuta toimintaa. Yhdistäkää se select-kutsuun, jotta kutsutte acceptia vain, kun kuuntelija on todella luettavissa.
Tämä muodostaa perustan skaalautuvalle yhden prosessin palvelimelle, joka multipleksoi satoja yhteyksiä.
server:settimeout(0)
local ready = socket.select({server}, nil, 5)
if #ready > 0 then
local c = server:accept()
endAsiakasvirheiden käsittely
Asiakkaat voivat katkaista yhteyden odottamatta. Kun receive palauttaa arvot nil, "closed" tai osittaisen puskurin, poistakaa asiakas tarkkailutaulukosta ja sulkekaa sen socket.
Älkää koskaan antako yhden rikkoutuneen yhteyden kaataa hyväksymissilmukkaa, vaan eristäkää kunkin asiakkaan virheet.
local data, err = client:receive("*l")
if err == "closed" then
client:close()
remove_from_watch(client)
endHallittu sammutus
Sammutuksen yhteydessä lopettakaa uusien yhteyksien hyväksyminen, sulkekaa kaikki aktiiviset asiakassocketit ja sulkekaa lopuksi kuunteleva palvelin vapauttaaksenne portin.
Asetuksen reuseaddr määrittäminen bind-vaiheessa mahdollistaa välittömän uudelleenkäynnistyksen ilman, että TCP:n TIME_WAIT-jaksoa tarvitsee odottaa loppuun.
for _, c in ipairs(clients) do c:close() end
server:close()
print("server stopped")Pikatesti
Valitkaa kutsujärjestys, joka muuttaa uuden master-socketin toimivaksi kuuntelijaksi.
Kertaus
Rakensitte TCP-palvelimen: sidotte sen osoitteeseen reuseaddr-asetuksella, aloititte kuuntelun backlogilla ja käsittelitte asiakkaita accept-silmukassa.
Näitte yksinkertaisen iteratiivisen silmukan ja laajensitte sen sitten ei-estäväksi samanaikaisuudeksi socket.select-kutsulla sekä opitte virheiden eristämisen ja hallitun sammutuksen. Seuraavaksi siirrytte HTTP:n pariin.
Opi Lua tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 40
- Oppitunnit
- 159
Usein kysytyt kysymykset
Onko oppitunti ”Palvelimen rakentaminen” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Lua Academy-oppimispolun 3 oppituntia, myös oppitunnin “Palvelimen rakentaminen”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Lua Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Palvelimen rakentaminen”?
Hyväksykää saapuvat yhteydet. Harjoittelet Lua Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Lua Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Lua Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Palvelimen rakentaminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Lua Academy-oppitunnilla?
Kyllä. Jokainen Lua Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- TCP:n perusteet
- Asiakkaan rakentaminen
- Palvelimen rakentaminen
- HTTP-pyynnöt