Mikhail Salosin (mĂ« tej â MS): â TĂ« gjithĂ« pĂ«rshĂ«ndetje! Jam Mikhail. Punoj si zhvillues backend nĂ« kompaninĂ« MC2 Software dhe do tĂ« flas pĂ«r pĂ«rdorimin e Go nĂ« backend-in e aplikacionit mobil âShiko+.â

Ka ndonjë nga të pranishmit që e do hokeun?

Atëherë ky aplikacion është për ju. Ai është për Android dhe iOS, shërben për të parë transmetimet e ngjarjeve të ndryshme sportive në kohë reale dhe në regjistrim. Gjithashtu, aplikacioni përmban statistikë të ndryshme, transmetime tekstuale, tabela për konferenca, turne dhe informacione të tjera të dobishme për tifozët.

Po ashtu, në aplikacion ka një funksion si momente video, domethënë mund të shihni momentet më interesante të ndeshjeve (gola, përleshje, gjuajtje penalltie etj.). Nëse nuk dëshironi të shihni tërë transmetimin, mund të shihni vetëm më të rëndësishmet.
ĂfarĂ« kemi pĂ«rdorur nĂ« zhvillim?
Pjesa kryesore ishte shkruar nĂ« Go. API-i me tĂ« cilin komunikuan klientĂ«t mobilĂ« ishte shkruar nĂ« Go. Po ashtu, njĂ« shĂ«rbim pĂ«r dĂ«rgimin e njoftimeve push pĂ«r mobilĂ« Ă«shtĂ« shkruar nĂ« Go. Na duhej tĂ« shkruanim njĂ« ORM tonin, pĂ«r tĂ« cilin ndoshta do tĂ« flasim ndonjĂ«herĂ«. Dhe gjithashtu, disa shĂ«rbime tĂ« vogla janĂ« shkruar nĂ« Go: ndryshimi i madhĂ«sisĂ« dhe ngarkimi i imazheve pĂ«r anĂ«n e redaktorĂ«veâŠ
Si bazë të dhënash kemi përdorur PostgreSQL. Ndërfaqja për redaktorët ishte shkruar në Ruby on Rails me ndihmën e gem-it ActiveAdmin. Edhe importimi i statistikës nga ofruesi i statistikave ishte shkruar në Ruby.
Për testet sistemore të API-t, ne përdorëm unittest-in e Python-it. Memcached përdoret për kufizimin e thirrjeve në API-në e pagesës, Chef për kontrollin e konfigurimeve, Zabbix për mbledhjen dhe monitorimin e të dhënave statistikore të brendshme të sistemit. Graylog2 përdoret për mbledhjen e log-eve, Slate është dokumentacioni i API-t për klientët.

Zgjedhja e protokollit
Problemi i parĂ« me tĂ« cilin u pĂ«rballĂ«m: duhej tĂ« zgjidhnim njĂ« protokoll tĂ« ndĂ«rveprimit midis backend-it dhe klientĂ«ve mobilĂ«, duke u bazuar nĂ« pikat e mĂ«poshtmeâŠ
- Kushti më i rëndësishëm: të dhënat në klientë duhet të përditësohen në kohë reale. Pra, të gjithë ata që janë duke parë transmetimin në atë moment duhet të marrin përditësimet pothuajse në çast.
- Për t'u thjeshtuar, ne pranuam se të dhënat që sinkronizohen me klientët nuk fshihen, por fshehen përmes flamujve të veçantë.
- Kërkesat e rralla (si statistikat, përbërja e skuadrave, statistikat e skuadrave) kryhen me kërkesa të zakonshme GET.
- Për më tepër, sistemi duhej të përballonte qetë 100,000 përdorues njëkohësisht.
Duke u bazuar në këtë, ne kishim dy opsione protokolli:
- Websocket. Por ne nuk kishim nevojë për kanale nga klienti në server. Na duhet vetëm të dërgojmë azhurnime nga serveri në klient, prandaj websockets janë një opsion i tepruar.
- Ngjarjet e Dërguara nga Serveri (SSE) ishin perfekte për ne! Ato janë mjaft të thjeshta dhe përmbushin gjithçka që na nevojitet.
Ngjarjet e Dërguara nga Serveri
Disa fjalë rreth mënyrës se si funksionon kjo gjë...
Ajo funksionon mbi një lidhje http. Klienti dërgon një kërkesë, serveri përgjigjet me Content-Type: text/event-stream dhe nuk e mbyll lidhjen me klientin, por vazhdon të shkruajë të dhëna në lidhje:

TĂ« dhĂ«nat mund tĂ« dĂ«rgohen nĂ« njĂ« format tĂ« pĂ«rshtatur me klientĂ«t. NĂ« rastin tonĂ«, dĂ«rgonim nĂ« kĂ«tĂ« mĂ«nyrĂ«: nĂ« fushĂ«n event shkonte emri i strukturĂ«s sĂ« ndryshuar (njeri, lojtar), ndĂ«rsa nĂ« fushĂ«n data â JSON me fushat e reja, tĂ« ndryshuara pĂ«r lojtarin.
Tani për mënyrën e funksionimit të bashkëpunimit.
- Së pari, klienti përcakton kur është kryer hera e fundit përditësimi me shërbimin: ai shikon në DB-në e tij lokale dhe përcakton datën e ndryshimit të fundit të regjistruar.
- Ai dërgon një kërkesë me këtë datë.
- Në përgjigje, i dërgojmë të gjitha përditësimet që ndodhën nga ajo datë.
- Pas kësaj, ai tregton lidhjen me kanalin live dhe nuk e mbyll derisa të ketë nevojë për këto azhurnime:

Ne i dĂ«rgojmĂ« atij njĂ« listĂ« ndryshimesh: nĂ«se dikush shĂ«non njĂ« gol â ndryshojmĂ« rezultatin e ndeshjes, nĂ«se ndodhin lĂ«ndime â gjithashtu dĂ«rgohet nĂ« kohĂ« reale. KĂ«shtu, nĂ« rrjedhĂ«n e ngjarjeve tĂ« ndeshjes, klientĂ«t menjĂ«herĂ« marrin tĂ« dhĂ«na aktuale. Periodikisht, pĂ«r t'i treguar klientit se serveri nuk Ă«shtĂ« ndalur, se nuk ka ndodhur ndonjĂ« gjĂ« me tĂ«, ne dĂ«rgojmĂ« çdo 15 sekonda njĂ« timestamp â pĂ«r ta siguruar qĂ« gjithçka Ă«shtĂ« nĂ« rregull dhe nuk ka nevojĂ« pĂ«r ri-lidhje.
Si menaxhohet lidhja live?
- Së pari, krijojmë një kanal, ku do të vijnë azhurnimet me një buffer.
- Më pas, e subscribojmë këtë kanal për të marrë azhurnime.
- Vendosim titullin e duhur, në mënyrë që klienti të dijë se gjithçka është në rregull.
- Dërgojmë pingun e parë. Thjesht regjistrojmë timestamp-in aktual të lidhjes.
- Pas kësaj, në cikël lexojmë nga kanali derisa kanali i azhurnimeve të mbyllet. Në kanalin periodikisht vjen ose timestampi aktual, ose ndryshimet që ne tashmë i regjistrojmë në lidhjet e hapura.

Problemi i parë me të cilin u përballëm ishte se për çdo lidhje të hapur me klientin krijonim një timer që tik-takonte çdo 15 sekonda - pra, nëse kishim 6 mijë lidhje të hapura me një makinë (me një API-server), krijoheshin 6 mijë timer-a. Kjo çonte në atë që makina nuk mbante ngarkesën e nevojshme. Problemi nuk ishte aq i dukshëm për ne, por na ndihmoi pak dhe e zgjidhem atë.
Si rrjedhojë, tani ping-u vjen nga i njëjti kanal nga i cili vjen azhurnimi.
Prandaj, ka vetëm një timer që tik-takonte çdo 15 sekonda.
KĂ«tu janĂ« disa funksione ndihmĂ«se â dĂ«rgimi i titullit, pingut dhe vetĂ« strukturĂ«s. Pra, kĂ«tu kalon emri i tabelĂ«s (person, ndeshje, sezon) dhe vetĂ« informata pĂ«r kĂ«tĂ« regjistrim:

Mekanizmi i dërgimit të azhurnimeve
Tani pak pĂ«r atĂ« se nga vijnĂ« ndryshimet. Kemi disa persona, redaktorĂ«, tĂ« cilĂ«t nĂ« kohĂ« reale shikojnĂ« transmetimin. Ata krijojnĂ« tĂ« gjitha ngjarjet: dikush Ă«shtĂ« fshirĂ«, dikush ka marrĂ« njĂ« lĂ«ndim, njĂ« zĂ«vendĂ«simâŠ
Me ndihmën e CMS, të dhënat kalojnë në bazë. Më pas, baza me mekanizmin Listen/Notify njofton për këtë API-serverat. API-serverat tashmë shpërndajnë këtë informacion tek klientët. Kështu, në thelb, vetëm disa serverë janë lidhur me bazën dhe nuk ka ndonjë ngarkesë të veçantë në bazë, sepse klienti nuk ndërvepron në asnjë mënyrë drejpërdrejt me bazën:

PostgreSQL: Listen/Notify
Mekanizmi Listen/Notify në «Postgres» lejon njoftimin e abonentëve për ngjarjet se diçka ka ndryshuar - është krijuar një regjistrim në bazë. Për këtë shkruam një trigger të thjeshtë dhe një funksion:

Për insertim ose ndryshim regjistrimi, ne thërrasim funksionin notify në kanalin data_updates, duke kaluar emrin e tabelës dhe identifikuesin e regjistrimit që është ndryshuar ose futur.
Për të gjitha tabelat që duhet të sinkronizohen me klientin, ne përcaktojmë një trigger, i cili pas ndryshimit/azhurnimit të regjistrimit thërret funksionin e caktuar në slajdin më poshtë.
Si nënshkruan API këto ndryshime?
Krijohet mekanizmi Fanout â ai shpĂ«rndan mesazhe pĂ«r klientĂ«t. Ai mbledh tĂ« gjitha kanalet e klientĂ«ve dhe dĂ«rgon pĂ«rditĂ«simet qĂ« merr nĂ« kĂ«to kanale:

Këtu është biblioteka standarde pq, e cila lidhet me bazën dhe thotë se dëshiron të dëgjojë kanalin (data_updates), kontrollon nëse lidhja është e hapur dhe gjithçka është në rregull. Po e lë pas kontrollin e gabimeve, për të kursyer hapësirë (moskontrollimi është i rrezikshëm).
Më pas ne caktojmë asinkronisht Ticker, i cili do të dërgojë ping çdo 15 sekonda, dhe fillojmë të dëgjojmë kanalin, në të cilin jemi abonuar. Nëse merrni një ping, e publikoni atë. Nëse merrni një regjistër, atëherë e publikoni këtë regjistër për të gjithë abonentët e këtij Fanout.
Si funksionon Fan-out?
Në shqip, kjo përkthehet si "çakëll". Ne kemi një objekt të vetëm, i cili regjistron abonentët që duan të marrin disa përditësime. Dhe sa herë që një përditësim i këtij objekti arrin, ai e shpërndan këtë përditësim për të gjithë abonentët që ka. Mjafton e thjeshtë:

Si është realizuar në Go:

Ka njĂ« strukturĂ«, e cila sinkronizohet me ndihmĂ«n e Mutex-eve. Ajo ka njĂ« fushĂ«, e cila ruan gjendjen e lidhjes Fanout me bazĂ«n, pra, nĂ« kĂ«tĂ« moment ajo Ă«shtĂ« duke dĂ«gjuar dhe do tĂ« marrĂ« pĂ«rditĂ«sime, si dhe njĂ« listĂ« tĂ« tĂ« gjitha kanaleve ekzistuese â njĂ« map, ku çelĂ«si Ă«shtĂ« kanali dhe njĂ« struct nĂ« formĂ« vlerash (nĂ« thelb nuk pĂ«rdoret fare).
Dy metoda â Connected dhe Disconnected â lejojnĂ« tĂ« shpjegohet Fanout-it se kemi njĂ« lidhje me bazĂ«n, ajo Ă«shtĂ« krijuar dhe se lidhja me bazĂ«n Ă«shtĂ« shkĂ«putur. NĂ« rastin e dytĂ«, duhet tĂ« çaktivizoni tĂ« gjithĂ« klientĂ«t dhe t'u thoni atyre se nuk mund tĂ« dĂ«gjojnĂ« mĂ« asgjĂ« dhe tĂ« rikthehen, pasi lidhja me ta Ă«shtĂ« mbyllur.
Ka gjithashtu një metodë Subscribe, e cila shton kanal në "dëgjuesit":

Ka një metodë Unsubscribe, e cila heq kanalin nga dëgjuesit, nëse klienti është shkëputur, si dhe një metodë Publish, që lejon të shpërndajë një mesazh për të gjithë abonentët.
Pyetje: - ĂfarĂ« transmetohet nĂ« kĂ«tĂ« kanal?
MS: - Transmetohet modeli, i cili është ndryshuar ose ping (në thelb është vetëm një numër, integer).
MS: - Mund tĂ« dĂ«rgoni çfarĂ«do, çdo strukturĂ« â ajo thjesht shndĂ«rrohet nĂ« JSON dhe mbaroi.
MS: â Ne marrim njĂ« notifikuese nga "PostgreSQL" - nĂ« tĂ« pĂ«rmban emrin e tabelĂ«s dhe identifikuesin. Sipas emrit tĂ« tabelĂ«s dhe identifikuesit ne marrim regjistrimin qĂ« kemi nevojĂ«, dhe kĂ«to struktura i dĂ«rgojmĂ« pĂ«r publikim.
Infrastruktura
Si duket kjo nga kĂ«ndvĂ«shtrimi i infrastrukturĂ«s? Ne kemi 7 serverĂ« fizikĂ«: njĂ«ri prej tyre Ă«shtĂ« plotĂ«sisht i dedikuar pĂ«r bazĂ«n, ndĂ«rsa nĂ« gjashtĂ« tĂ« tjerĂ« nuk janĂ« duke funksionuar virtualizime. Ka 6 kopje API: secila virtualizim me API funksionon nĂ« njĂ« server fizik tĂ« veçantĂ« â kjo Ă«shtĂ« pĂ«r besueshmĂ«ri.

Ne kemi dy frontend-e, tĂ« cilat kanĂ« tĂ« instaluar Keepalived pĂ«r tĂ« pĂ«rmirĂ«suar disponueshmĂ«rinĂ«, nĂ« mĂ«nyrĂ« qĂ« nĂ« rast tĂ« ndonjĂ« problemi njĂ« frontend tĂ« mund tĂ« zĂ«vendĂ«sojĂ« tjetrin. Gjithashtu â dy kopje CMS.
Ka gjithashtu njĂ« importer statistike. Ka njĂ« DB Slave, nga e cila herĂ« pas here bĂ«hen kopje rezervĂ«. Ka Pigeon Pusher â ajo aplikacioni qĂ« dĂ«rgon njoftimet pĂ«r klientĂ«t, si dhe gjĂ«rat infrastrukturore: Zabbix, Graylog2 dhe Chef.
NĂ« tĂ« vĂ«rtetĂ«, kjo infrastrukturĂ« Ă«shtĂ« e tejkaluar, sepse 100 mijĂ« mund tĂ« shĂ«rbehen edhe me njĂ« numĂ«r mĂ« tĂ« vogĂ«l serverĂ«sh. Por kishte pajisje â ne e pĂ«rdorĂ«m (na thanĂ« qĂ« ishte e mundur â pse jo).
Avantazhet e Go
Pas punës në këtë aplikacion, dolën disa avantazhe evidente të Go.
- Biblioteka http është e shkëlqyer. Me të, mund të krijosh mjaft gjëra "nga kutia".
- Gjithashtu, kanalet na lejuan të realizojmë shumë lehtë mekanizmin e dërgimit të njoftimeve për klientët.
- Një gjë e shkëlqyer si Race detector na lejoi të eliminojmë disa bogë kritike (infrastruktura staging). Të gjitha që funksionojnë në staging janë nisur, kompiluar me çelësin Race; dhe ne, përkatësisht, mund të shohim në infrastrukturën staging, cilat janë problemet tona potenciale.
- Minimalizmi dhe thjeshtësia e gjuhës.

Ne po kĂ«rkojmĂ« zhvillues! NĂ«se dikush Ă«shtĂ« i interesuar â lutem.
Pyetje
Pyetja nga audienca (mĂ« pas â P): â MĂ« duket se ju e keni humbur njĂ« pikĂ« tĂ« rĂ«ndĂ«sishme nĂ« lidhje me Fan-out. A e kuptoj saktĂ« se kur ju dĂ«rgoni njĂ« pĂ«rgjigje pĂ«r klientin, bllokoheni, nĂ«se klienti nuk dĂ«shiron tĂ« lexojĂ«?
MS: â Jo, ne bllokohemi. SĂ« pari, tĂ« gjitha kĂ«to ndodhin pĂ«rmes nginx, çka do tĂ« thotĂ« se nuk ka probleme me klientĂ«t e ngadaltĂ«. SĂ« dyti, klienti ka njĂ« kanal me tampon â nĂ« thelb mund tĂ« dĂ«rgojmĂ« deri nĂ« njĂ«qind azhurnime atje... NĂ«se nuk mund ta shkruajmĂ« nĂ« kanal, ai e fshin atĂ«. NĂ«se shohim qĂ« kanali Ă«shtĂ« bllokuar, thjesht e mbyllim kanalin dhe gjithçka â klienti lidhet pĂ«rsĂ«ri nĂ«se ndodh ndonjĂ« problem. Prandaj, nĂ« kĂ«tĂ« rast nuk ka bllokim.
P: â A nuk do tĂ« ishte mĂ« mirĂ« tĂ« dĂ«rgonit menjĂ«herĂ« regjistrimin nĂ« Listen/Notify, e jo tabelĂ«n-identifikues?
MS: â Listen/Notify ka njĂ« kufi prej 8 mijĂ« bajtĂ«sh pĂ«r preload-in qĂ« dĂ«rgon. NĂ« thelb, do tĂ« ishte e mundur tĂ« dĂ«rgonte, nĂ«se do tĂ« kishim tĂ« bĂ«nim me njĂ« sasi tĂ« vogĂ«l tĂ« dhĂ«nash, por mĂ« duket se kĂ«shtu [sa e bĂ«jmĂ« ne] Ă«shtĂ« thjesht mĂ« e sigurt. Kufizimet janĂ« nĂ« vetĂ« "Postgres".
P: â A marrin klientĂ«t azhurnime pĂ«r ndeshjet qĂ« nuk i interesojnĂ«?
MS: â Po, nĂ« tĂ« vĂ«rtetĂ«. Zakonisht, ka 2-3 ndeshje qĂ« zhvillohen paralelisht, dhe kjo ndodh mjaft rrallĂ«. NĂ«se klienti po shikon diçka, zakonisht ai zakonisht shikon ndeshjen qĂ« po zhvillohet. Pastaj, nĂ« klient ekziston njĂ« bazĂ« lokale, nĂ« tĂ« cilĂ«n ruhet tĂ« gjitha kĂ«to azhurnime, dhe madje pa lidhjen me internetin, klienti mund tĂ« shikojĂ« tĂ« gjitha ndeshjet e kaluara pĂ«r tĂ« cilat ka azhurnime. NĂ« thelb, ne e sinkronizojmĂ« bazĂ«n tonĂ« nĂ« server me bazĂ«n lokale tĂ« klientit, nĂ« mĂ«nyrĂ« qĂ« ai tĂ« mund tĂ« punojĂ« edhe nĂ« offline.
P: â Pse krijuat ORM tuaj?
Aleksei (njĂ« nga zhvilluesit e "Shiko+"): â NĂ« atĂ« kohĂ« (kjo ishte njĂ« vit mĂ« parĂ«) kishte mĂ« pak ORM se tani, kur ato janĂ« mjaft tĂ« shumta. Nga shumica e ORM-ve ekzistuese, mĂ« shumĂ« mĂ« pengon se shumica e tyre punojnĂ« me interface tĂ« zbrazĂ«ta. Do tĂ« thotĂ« se metodat qĂ« kanĂ« kĂ«to ORM janĂ« gati tĂ« pranojnĂ« gjithçka: strukturĂ«, tregues strukture, numĂ«r, diçka qĂ« nuk ka lidhje fare me kĂ«tĂ«...
ORM-ja jonë gjeneron struktura në bazë të modelit të të dhënave. Vetë. Dhe prandaj të gjitha metodat janë specifike, nuk përdorin refleksionin etj. Ato pranojnë struktura dhe presin të përdorin ato struktura që do të vijnë.
P: â Sa njerĂ«z morĂ«n pjesĂ«?
MS: â NĂ« fazĂ«n fillestare morĂ«n pjesĂ« dy njerĂ«z. Diku nĂ« qershor filluam, nĂ« gusht nĂ«ndesa principale ishte e gatshme (versioni i parĂ«). NĂ« shtator ishte lĂ«shimi.
P: â Aty ku pĂ«rshkruani SSE, nuk pĂ«rdorni timeout. Pse kĂ«shtu?
MS: â NĂ«se flasim hapur, SSE Ă«shtĂ« nĂ« tĂ« vĂ«rtetĂ« njĂ« protokoll html5: standardi SSE Ă«shtĂ« i destinuar pĂ«r komunikimin me shfletuesit, sa kuptoj. Ka disa funksione shtesĂ« qĂ« lejojnĂ« shfletuesit tĂ« risigurohen (dhe tĂ« tjera), por ato nuk na duhen, sepse kemi pasur klientĂ« qĂ« kanĂ« qenĂ« tĂ« aftĂ« tĂ« implementonin çdo logjikĂ« lidhjeje dhe marrjeje informacioni. Kemi bĂ«rĂ« mĂ« shumĂ« se SSE, ndoshta diçka e ngjashme me SSE. Nuk Ă«shtĂ« vetĂ« protokolli.
Nuk kishte nevojë. Sa kuptoj, klientët e implementuan mekanizmin e lidhjes praktikisht nga zero. Në thelb, nuk e kishin problem.
P: â ĂfarĂ« mjete shtesĂ« keni pĂ«rdorur?
MS: â PĂ«rdorĂ«m mĂ« aktivisht govet dhe golint, qĂ« tĂ« kishim njĂ« stil tĂ« njĂ«jtĂ«, si dhe gofmt. Nuk kemi pĂ«rdorur asgjĂ« tjetĂ«r.
P: â Me çfarĂ« e keni bĂ«rĂ« debugimin?
MS: â Debugimi kryesisht ka ndodhur pĂ«rmes testeve. Nuk kemi pĂ«rdorur asnjĂ« debagger, GOP.
P: â Mund tĂ« ktheni sklin ku Ă«shtĂ« implementuar funksioni Publish? A ju duken emrat e variablave me njĂ« shkronjĂ« tĂ« çuditshĂ«m?
MS: â Jo. Ata kanĂ« njĂ« fushĂ« tĂ« mjaftueshme "tĂ« ngushtĂ«" shikimi. Nuk pĂ«rdoren askund tjetĂ«r, pĂ«rveç kĂ«tu (pĂ«rveç brendĂ«sisĂ« sĂ« kĂ«saj klase), dhe Ă«shtĂ« shumĂ« kompakte â zĂ« vetĂ«m 7 rreshta.
P: â Duket paksa jo intuitiv...
MS: â Jo-jo, kjo Ă«shtĂ« njĂ« kod i vĂ«rtetĂ«! Nuk Ă«shtĂ« çështje stili. ĂshtĂ« thjesht njĂ« klasĂ« utilitare, shumĂ« e vogĂ«l â vetĂ«m 3 fusha brenda klasĂ«s...

MS: â NĂ« thelb, tĂ« gjitha ato tĂ« dhĂ«na qĂ« sinkronizohen me klientĂ«t (ndeshjet sezonale, lojtarĂ«t), nuk ndryshojnĂ«. NĂ« thelb, nĂ«se do tĂ« bĂ«jmĂ« njĂ« sport tjetĂ«r, ku do tĂ« jetĂ« e nevojshme tĂ« ndryshojmĂ« ndeshjen, do ta parashikojmĂ« thjesht nĂ« versionin e ri tĂ« klientit, ndĂ«rsa versionet e vjetra tĂ« klientit do tĂ« bllokohen.
P: â A ka ndonjĂ« paketĂ« tĂ« jashtme pĂ«r menaxhimin e varĂ«sive?
MS: â Ne kemi pĂ«rdorur go dep.
P: â NĂ« temĂ«n e referatit kishte diçka pĂ«r video, por nuk ka nĂ« referat.
MS: â Jo, unĂ« nuk kam asgjĂ« nĂ« temĂ«n time pĂ«r video. Quhet "Shiko+" â ashtu e quajnĂ« aplikacionin.
P: â TĂ« keni thĂ«nĂ« se transmetohet pĂ«r klientĂ«t?..
MS: â Me video streaming nuk merreshim. Kjo e bĂ«nte plotĂ«sisht "Megafoni". Po, nuk thashĂ« se aplikacioni Ă«shtĂ« nga Megafoni.
MS: â Go â pĂ«r dĂ«rgimin e tĂ« gjitha tĂ« dhĂ«nave â pĂ«r llogarinĂ«, pĂ«r ngjarjet e ndeshjes, statistikĂ«n⊠Go â Ă«shtĂ« krejtĂ«sisht backend pĂ«r aplikacionin. Klienti duhet tĂ« dijĂ« se cila lidhje tĂ« pĂ«rdorĂ« pĂ«r lojtarin, nĂ« mĂ«nyrĂ« qĂ« pĂ«rdoruesi tĂ« mund tĂ« shikojĂ« ndeshjen. Ne kemi lidhje pĂ«r video dhe transmetime, qĂ« janĂ« pĂ«rgatitur.

Pak reklamĂ« đ
Faleminderit që po qëndroni me ne. Ju pëlqen artikujt tanë? Doni të shihni më shumë materiale interesante? Na mbështesni duke bërë një porosi ose duke rekomanduar tek miqtë tuaj, , një analog unik i serverëve entry-level që e kemi shpikur për Ju: (opcionet me RAID1 dhe RAID10, deri në 24 bërthama dhe deri në 40GB DDR4 janë të disponueshme).
Dell R730xd dyfish mĂ« i lirĂ« nĂ« qendĂ«r tĂ« tĂ« dhĂ«nave Equinix Tier IV nĂ« Amsterdam? VetĂ«m te ne nĂ« HolandĂ«! Dell R420 â 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB â nga $99! Lexoni rreth
Burimi: habr.com
