Verken HTML eller HTTP ble opprettet for dynamiske webapplikasjoner. Vi er i utgangspunktet avhengige av hack, på toppen av hack, for å gi våre apper et responsivt brukergrensesnitt. AngularJS fjerner noen begrensninger fra HTML, slik at vi kan lage og administrere brukergrensesnittkoden lettere. Socket.IO, hjelper oss på den annen side med å sende data fra serveren, ikke bare når kunden ber om det, men også når serveren trenger det. I denne artikkelen vil jeg vise deg hvordan du kombinerer disse to, for å forbedre responsen til enkeltversjonene dine.
I den første delen av denne opplæringen vil vi opprette en gjenbrukbar AngularJS-tjeneste for Socket.IO. På grunn av det gjenbruk del, dette vil være litt vanskeligere enn bare å bruke module.service ()
eller module.factory ()
. Disse to funksjonene er bare syntaktisk sukker på toppen av det mer lave nivået module.provider ()
metode, som vi skal bruke for å gi noen konfigurasjonsalternativer. Hvis du aldri har brukt AngularJS før, anbefaler jeg på det sterkeste at du i det minste følger den offisielle opplæringen og noen av veiledningene her på Tuts+.
Før vi begynner å skrive vår AngularJS-modul, trenger vi en enkel backend for testing. Hvis du allerede er kjent med Socket.IO, kan du bare bla ned til slutten av denne delen, kopiere back-end-kilden og fortsette til neste, hvis ikke - les videre.
Vi trenger bare socket.io
. Du kan enten installere den direkte ved hjelp av NPM
kommando slik:
npm installere socket.io
Eller opprett en package.json
fil, sett denne linjen i avhengig
seksjon:
"socket.io": "0.9.x"
Og utfør npm installasjon
kommando.
Siden vi ikke trenger noe komplisert webramme som Express, kan vi opprette serveren ved hjelp av Socket.IO:
var io = krever ('socket.io') (8080);
Det er alt du trenger for å konfigurere Socket.IO-serveren. Hvis du starter appen din, bør du se lignende utdata i konsollen:
Og du bør kunne få tilgang til socket.io.js
fil i nettleseren din på http: // localhost: 8080 / socket.io / socket.io.js:
Vi håndterer alle innkommende tilkoblinger i forbindelse
hendelseslytter av io.sockets
gjenstand:
io.sockets.on ('tilkobling', funksjon (socket) );
De stikkontakt
Attributt sendt til tilbakekallingen er klienten som er tilkoblet, og vi kan lytte til hendelser på den.
Nå legger vi til en grunnhendelselytter i tilbakeringingen ovenfor. Det vil sende data mottatt, tilbake til klienten ved hjelp av socket.emit ()
metode:
socket.on ('echo', funksjon (data) socket.emit ('echo', data););
ekko
er det egendefinerte begivenhetsnavnet som vi vil bruke senere.
Vi vil også bruke bekreftelser i vårt bibliotek. Denne funksjonen lar deg passere en funksjon som den tredje parameteren til socket.emit ()
metode. Denne funksjonen kan kalles på serveren for å sende noen data tilbake til klienten:
socket.on ('echo-ack', funksjon (data, tilbakeringing) callback (data););
Dette gjør at du kan svare på klienten uten å kreve det å lytte til noen hendelser (som er nyttig hvis du bare vil be om data fra serveren).
Nå er vår testback-end ferdig. Koden skal se slik ut (Dette er koden du bør kopiere hvis du utelatt denne delen):
var io = krever ('socket.io') (8080); io.sockets.on ('connection', funksjon (socket) socket.on ('echo', funksjon (data) socket.emit ('echo', data);); socket.on ', funksjon (data, tilbakeringing) tilbakeringing (data);););
Du bør nå kjøre appen og la den gå, før du fortsetter med resten av opplæringen.
Vi vil selvfølgelig trenge litt HTML for å teste biblioteket vårt. Vi må inkludere AngularJS, socket.io.js
fra vår back-end, vår vinkel-socket.js
bibliotek og en grunnleggende AngularJS-kontroller for å kjøre noen tester. Kontrolleren vil bli innstilt i av dokumentet for å forenkle arbeidsflyten:
Dette er alt vi trenger for nå, vi kommer tilbake til det tomme skriptet, siden vi ennå ikke har biblioteket.
I denne delen skal vi opprette vinkel-socket.js
bibliotek. Alle koden må settes inn i denne filen.
La oss begynne med å lage modulen for vår lib:
var modul = angular.module ('socket.io', []);
Vi har ingen avhengigheter, så arrayet i det andre argumentet til angular.module ()
er tom, men ikke fjern den helt eller du vil få en $ Injektor: nomod
feil. Dette skjer fordi det ene argumentet for angular.module ()
henter en referanse til den allerede eksisterende modulen, i stedet for å opprette en ny.
Leverandører er en av måtene å opprette AngularJS-tjenester. Syntaxen er enkel: Det første argumentet er navnet på tjenesten (ikke navnet på leverandøren!) Og den andre er konstruktørfunksjonen for leverandøren:
module.provider ('$ socket', $ socketProvider () );
For å gjøre biblioteket gjenbrukbart, må vi tillate endringer i Socket.IOs konfigurasjon. Først la oss definere to variabler som vil holde URL-adressen for forbindelsen og konfigurasjonsobjektet (kode i dette trinnet går til $ SocketProvider ()
funksjon):
var ioUrl = "; var ioConfig = ;
Nå siden disse variablene ikke er tilgjengelige utenfor $ SocketProvider ()
funksjon (de er slags privat), må vi lage metoder (settere) for å endre dem. Vi kunne selvfølgelig bare gjøre dem offentlig som dette:
this.ioUrl = "; this.ioConfig = ;
Men:
Function.bind ()
senere for å få tilgang til riktig kontekst for dette
falsk
som 'koble timeout'
alternativEn fullstendig liste over alternativer for Socket.IOs klient kan ses på deres GitHub wiki. Vi vil opprette en setter for hver av dem pluss en for nettadressen. Alle metodene ser like ut, så jeg vil forklare koden for en av dem og sette resten under.
La oss definere den første metoden:
this.setConnectionUrl = funksjon setConnectionUrl (url)
Det bør sjekke hvilken type parameter som er sendt inn:
hvis (typeof url == 'streng')
Hvis det er det vi forventet, sett inn alternativet:
ioUrl = url;
Hvis ikke, bør det kaste Typeerror
:
ellers Kast ny TypeError ('URL må være av typen streng'); ;
For resten av dem kan vi opprette en hjelperfunksjon for å holde den tørr:
funksjon setOption (navn, verdi, type) if (typeof verdi! = type) kaste ny TypeError ("'" + navn + "' må være av typen '" + type + "'"); ioConfig [navn] = verdi;
Det kaster bare Typeerror
Hvis typen er feil, angir ellers verdien. Her er koden for resten av alternativene:
this.setResource = funksjon setResource (verdi) setOption ('ressurs', verdi, 'streng'); ; this.setConnectTimeout = funksjon setConnectTimeout (verdi) setOption ('connect timeout', verdi, 'tall'); ; this.setTryMultipleTransports = funksjon setTryMultipleTransporter (verdi) setOption ('prøv flere transporter', verdi, 'boolean'); ; this.setReconnect = funksjon setKoble til (verdi) setOption ('reconnect', value, 'boolean'); ; this.setReconnectionDelay = funksjon setReconnectionDelay (verdi) setOption ('tilbakekoblingsforsinkelse', verdi, 'tall'); ; this.setReconnectionLimit = funksjon setReconnectionLimit (verdi) setOption ('gjenkoblingsgrense', verdi, 'tall'); ; this.setMaxReconnectionAttempts = function setMaxReconnectionAttempts (value) setOption ('maks tilbakekoblingsforsøk', verdi, 'tall'); ; this.setSyncDisconnectOnUnload = funksjon setSyncDisconnectOnUnload (verdi) setOption ('synk koble fra på losse', verdi, 'boolean'); ; this.setAutoConnect = funksjon setAutoConnect (verdi) setOption ('auto connect', verdi, 'boolean'); ; this.setFlashPolicyPort = funksjon setFlashPolicyPort (verdi) setOption ('flash policy port', verdi, 'tall'); this.setForceNewConnection = funksjon setForceNewConnection (value) setOption ('force new connection', verdi, 'boolean'); ;
Du kan erstatte det med en enkelt setOption ()
metode, men det virker lettere å skrive alternativets navn i kamel-tilfelle, i stedet for å sende det som en streng med mellomrom.
Denne funksjonen vil opprette serviceobjektet som vi kan bruke senere (for eksempel i kontroller). Først, la oss ringe io ()
Fungerer for å koble til Socket.IO-serveren:
dette. $ get = funksjon $ socketFactory ($ rootScope) var socket = io (ioUrl, ioConfig);
Legg merke til at vi tilordner funksjonen til $ get
Egenskapen til objektet opprettet av leverandøren - dette er viktig siden AngularJS bruker den egenskapen til å ringe den. Vi har også satt $ rootScope
som parameter. På dette tidspunktet kan vi bruke AngularJS's avhengighetsinjeksjon for å få tilgang til andre tjenester. Vi vil bruke den til å formidle endringer i alle modeller i Socket.IO tilbakeringinger.
Nå må funksjonen returnere et objekt:
komme tilbake ; ;
Vi vil sette alle metoder for tjenesten i den.
på()
MetodeDenne metoden vil vedkoble en hendelseslytter til stikkobjektet, slik at vi kan bruke alle data som sendes fra serveren:
på: funksjon på (arrangement, tilbakeringing)
Vi bruker Socket.IO socket.on ()
å feste vår tilbakeringing og ringe den i AngularJS $ Omfang. $ Gjelder ()
metode. Dette er veldig viktig, fordi modeller kun kan endres på innsiden av det:
socket.on (arrangement, funksjon ()
Først må vi kopiere argumentene til en midlertidig variabel slik at vi kan bruke dem senere. Argumenter er selvfølgelig alt som serveren sendte til oss:
var args = argumenter;
Deretter kan vi ringe vår tilbakeringing ved hjelp av Function.apply ()
å passere argumenter til det:
$ rootScope. $ apply (funksjon () callback.apply (socket, args);); ); ,
Når stikkontakt
Event-emitter kaller lytterfunksjonen den bruker $ RootScope. $ Gjelder ()
å ringe tilbakeringingen som tilbys som det andre argumentet til .på()
metode. På denne måten kan du skrive dine hendelseslyttere som du ville for noen annen app ved hjelp av Socket.IO, men du kan endre AngularJS modeller i dem.
av()
MetodeDenne metoden fjerner en eller alle hendelseslyttere for en bestemt hendelse. Dette hjelper deg å unngå minnelekkasje og uventet oppførsel. Tenk deg at du bruker ngRoute
og du legger til få lyttere i hver kontroller. Hvis brukeren navigerer til en annen visning, blir kontrolleren ødelagt, men hendelseslytteren forblir festet. Etter noen få navigasjoner og vi har en minnelekkasje.
av: funksjon av (hendelse, tilbakeringing)
Vi må bare sjekke om Ring tilbake
ble levert og ringe socket.removeListener ()
eller socket.removeAllListeners ()
:
hvis (type tilbakering == 'funksjon') socket.removeListener (hendelse, tilbakeringing); ellers socket.removeAllListeners (event); ,
avgir ()
MetodeDette er den siste metoden vi trenger. Som navnet antyder, vil denne metoden sende data til serveren:
avgir: funksjonsemisjon (hendelse, data, tilbakeringing)
Siden Socket.IO støtter bekreftelser, vil vi sjekke om Ring tilbake
ble levert. Hvis det var, vil vi bruke det samme mønsteret som i på()
metode for å ringe tilbakekallingen innsiden av $ Omfang. $ Gjelder ()
:
hvis (type tilbakering == 'funksjon') socket.emit (hendelse, data, funksjon () var args = argumenter; $ rootScope. $ apply (funksjon () callback.apply (socket, args);); );
Hvis det er nei Ring tilbake
vi kan bare ringe socket.emit ()
:
ellers socket.emit (hendelse, data);
For å teste biblioteket, vil vi lage en enkel skjema som vil sende noen data til serveren og vise svaret. Alle JavaScript-kodene i denne delen skal gå i >