Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: IRC-bottia tekemään

Sivun loppuun

trilog [16.04.2009 13:40:19]

#

Päässäni on pyörinyt jo muutaman kuukauden ajan ajatus tehdä IRC-botti. Nyt kun sille tuli oikea tarve niin se motivoi vielä enemmän ja päätin sitten aloittaa.

Botin täytyisi tukea useaa verkkoa, eli sen pitäisi pystyä olla yhteydessä moneen eri serveriin samanaikaisesti. Olen nyt toteuttanut tämän siten, että jokaisesta serveristä luodaan uusi thread. Se toimii hyvin, mutta onko uuden threadin luomien jokaisesta serveristä järkevää/kannattavaa? Miten asian voisi tarvittaessa toteuttaa toisin?

Threadien ohjelmoinnista minulle ei ole kokemusta juuri lainkaan, mutta olen havainnut, että tässä tilanteessa ne toimisivat oikein näppärästi (en vain viitsi käyttää niitä jos botti rupeaa syömään konetehoja kun ollaan yhteydessä useaan serveriin).

Pilkki [16.04.2009 14:22:02]

#

Lukaseppa läpi IRC-protokollan RFC niin voit toteuttaa tämän kirjoittamalla suoraan sockettiin. Oma toteutukseni on python-pohjainen. Botin rakenne on yksinkertainen. Ensin valmistellaan socketit, sitten silmukalla tutkitaan niiden sisältöä ja suoritetaan tarvittavat toimenpiteet.

trilog [16.04.2009 15:02:30]

#

Pilkki kirjoitti:

Lukaseppa läpi IRC-protokollan RFC niin voit toteuttaa tämän kirjoittamalla suoraan sockettiin. Oma toteutukseni on python-pohjainen. Botin rakenne on yksinkertainen.

Olen toki IRC:n RFC:n lukenut läpi jo, silmäilin sitä myös uudestaan nyt pikaisesti kun tuo kuulosti mielestäni oudolta. Voitko selventää mitä tarkoitat kirjoittamisella suoraan sockettiin?

Pilkki kirjoitti:

Ensin valmistellaan socketit, sitten silmukalla tutkitaan niiden sisältöä ja suoritetaan tarvittavat toimenpiteet.

Näin minunkin botti tällä hetkellä tekee, sillä poikkeuksella tosin, että silmukkaa pyöritetään threadissa verkkoa kohden.

Esimerkiksi PircBotin IRC API:ssa lukee näin:

http://www2.sys-con.com/itsg/virtualcd/java/archives/0812/mutton/index.html:

Many people ask (without thinking) whether PircBot supports multiple servers. The answer is yes, of course. This is achieved simply by creating a new instance of PircBot for each server that you wish to connect to.

Ehkä threadien luomien per verkko ei olekaan niin huono ratkaisu...

tesmu [16.04.2009 17:07:31]

#

Väittäisin että bottisi ei tule olemaan niin monessa verkossa, että säikeitten määrästä olisi jotain haittaa.

ZcMander [16.04.2009 17:16:32]

#

Toisaalta, sen voi myöskin kääntää niin, ettei siitä tule mitään merkittävää hyötyäkään, koska moniytimiset prossut on muutenki tarpeeksi tehokkaita pyörittämään vaikka millasta bottia. En tosin tiedä miten moneen verkkoon yhdistäminen ilman säikeitä onnistuu / kuinka helposti.

Mutta nyt kun miettii, niin jos botin tekee toimimaan yhdessä verkossa, ja lisää siihen vaan threadit, niin sehnä toimii monessa verkossa samaan aikaan, joten luultavasti paras ratkasu käyttää threadeja, vaikkei niissä _teholtaan_ juuri mitään etua saakkaan.

tesmu [16.04.2009 18:27:31]

#

Periaatteessa se, että luot uuden säikeen per yhteys on melkein sama kuin se että käynnistät jokaista serveriä varten oman botin.

Metabolix [16.04.2009 19:13:53]

#

Voit aivan hyvin hoitaa kaikkia yhteyksiä samassa säikeessä. Sinun täytyy vain dataa vastaanottaessasi ensin tarkistaa, onko dataa, ja vastaanottaa vain, jos on.

Ohjelman perusrakenne olisi siis tällainen:

kun ohjelma on käynnissä:
    jokaiselle yhteydelle:
        jos on dataa:
            lue data ja reagoi
        tee muut toiminnot (mm. ajastetut tapahtumat)
    nuku hetki ennen seuraavaa kierrosta

_Pete_ [17.04.2009 13:49:31]

#

Tähän väliin pakollinen mainos:
http://quadcore.homeunix.net/trac_h2/

Tekee juurikin sen mitä Trilog pohtii ja hieman muutakin.

trilog [17.04.2009 22:09:24]

#

Metabolix kirjoitti:

Voit aivan hyvin hoitaa kaikkia yhteyksiä samassa säikeessä. Sinun täytyy vain dataa vastaanottaessasi ensin tarkistaa, onko dataa, ja vastaanottaa vain, jos on.

Erittäin mahtava vinkki, kiitos siitä. Sain toimimaan tuon esittämälläsi tavalla yhdessä säikeessä ja myös pari ongelmaa, jotka oli säikeiden kanssa jouduttu tekemään monimutkaisesti, poistui.

Ainut vain, että uusi ongelma tuli mieleeni. Jos emme odota dataa saapuvaksi eksplisiittisesti (emme voi tietää, milloin serveri lähettää dataa) ja nukumme silmukan lopussa niin osa datasta voi jäädä pois (kuten jo testailussani kävikin). Onko tähän ongelmaan vielä jotakin kätevää kikkaa?

Kray [17.04.2009 23:06:04]

#

Jos pythonilla teet, niin heitäpä googleen sellainen taikasana kuin irclib, sen kanssa ei tarvitse yhteyksistä ja niiden ylläpidosta välittää tuon taivaallista.

Metabolix [18.04.2009 00:21:24]

#

trilog kirjoitti:

Jos – – nukumme silmukan lopussa niin osa datasta voi jäädä pois – –

Tämäpä kuulostaa omituiselta. Minun tuntemissani socket-järjestelmissä data pysyy odottamassa, kunnes se luetaan. Näin näyttäisi myös Pythonin kanssa olevan.

Tässä ovat olennaiset osat Python-koodista, jolla testasin menetelmän toimivaksi. Joudut tästä korjaamaan rivinvaihdon \r\n:ksi IRC-protokollan mukaan ja tietenkin kääntämään koodin käyttämällesi kielelle; itse koodasin Pythonin kolmosversiolla, kun siinä ovat niin mukavasti string ja bytes eri tyyppejä. :)

# Säädetään blokkaus pois päältä.
s.setblocking(0)

# Alustetaan vastaanotettu data tyhjäksi ja silmukka käyntiin.
buf = b""
loop = True
while loop:
    time.sleep(1)
    # Haetaan kaikki mahdollinen data puskurin jatkoksi.
    while True:
        try:
            buf = buf + s.recv(4096)
        except socket.error as msg:
            # Data loppui.
            break
    # Jaetaan puskuri rivinvaihtojen kohdalta; IRCissä tietenkin b"\r\n".
    lines = buf.split(b"\n")
    # Laitetaan viimeinen (keskeneräinen tai tyhjä) rivi takaisin puskuriin.
    buf = lines.pop()
    # Käsitellään saadut rivit järjestyksessä.
    for str in lines:
        str = str.decode()
        print(str)
        if str == "exit":
            loop = False
    lines = None

Edit. Antti toivottavasti joskus lisää Python-väritykseen tuen tabulaattoreille.

trilog [18.04.2009 00:56:58]

#

Metabolix kirjoitti:

Minun tuntemissani socket-järjestelmissä data pysyy odottamassa, kunnes se luetaan.

Jep, bugihan siellä oli. Kiitos vielä rautalangasta. :)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta