Implementere toveis SMS i .Net

At en tjeneste benytter toveis SMS vil si at den både kan motta meldinger fra brukere (mobile originated, MO), og at den kan sende meldinger til brukere (mobile terminated, MT). Å lage en slik tjenste som bruker PSWinCom’s SMS gateway er veldig enkelt, takket være gode integrasjonsgrensesnitt. I denne artikkelen vil jeg implementere en slik tjeneste i .NET / C#.

Jeg registrerer meg hele tiden på ulike nettsteder, som alle ber meg om å spesifisere et passord. Og da er det veldig dumt å bruke det samme passordet hele tiden. Jeg ønsker derfor å kunne sende kodeord PASSORD til et bestemt telefonnummer, og få tilbake et garantert tilfeldig passord jeg kan bruke. Denne tjenesten er altså tiltenkt sikkerhetsfanatikere med dårlig fantasi.

toveis_sms

For å lage tjenesten vil jeg implementere en web service som jeg kan hoste i IIS. Tjenesten har to integrasjonspunkt: Ett SOAP-endepunkt må implementeres for å motta SMS-meldinger fra gateway’en, og i tillegg må tjenesten kalle en tilsvarende SOAP-tjeneste som gateway’en eksponerer når vi ønsker å sende melding tilbake til brukeren som ber om et passord.

For å lage en slik tjeneste trenger jeg produktet Gateway standard (produktark), og PSWinCom må registrere URLen til tjenesten min for kodeordet jeg vil bruke. Det er mulig å få demokonto for dem som ønsker å teste mulighetene. Det kan også være lurt a lage sin egen test-gateway (fakeway) om man vil teste tjenesten uten å nødvendigvis sende og motta SMS’er – det vil komme en egen blogpost om hvordan man enkelt kan gjøre dette.

Grensesnitt for innkommende meldinger

Å bruke SOAP-grensesnittet for mottak av SMS-meldinger i .Net er veldig enkelt. Først starter du Visual Studio Command Prompt, og bruker kommandoen wsdl for å generere et service interface.

Kommando for å generere SMS receive service interfaces:
wsdl /namespace:RandomPasswordService /serverInterface https://secure.pswin.com/SOAP/Receive.asmx?wsdl

Dette vil resultere i en fil som heter SMSReceiveInterfaces.cs. Den inneholder blant annet et interface som heter ISMSReceiveSoap. For å kunne ta imot meldinger må vi lage en web service som implementerer dette interfacet.

Grensesnitt for utgående meldinger

For å sende SMS-meldinger fra passord-tjenesten kan vi bruke et lite bibliotek, PSWinCom SMS Gateway Client for .NET, som kan lastes ned fra pswin.com. Om du ønsker å generere en SOAP proxy selv kan du gjøre det i stedet. All informasjon du trenger finner du i dokumentasjonen over grensesnittene.

RandomPasswordService-prosjektet

Jeg oppretter så et nytt ASP.NET Web Application prosjekt i Visual Studio som skal bli passord-tjenesten vår. Jeg sletter Default.aspx, og legger i stedet til SMSReceiverInterfaces.cs som jeg genererte, samt en referanse til PSWinCom.Gateway.Client.

Deretter legger jeg til en web service jeg kaller Password.asmx. Det er i denne servicen vi skal implementere interfacet for å håndtere innkommende meldinger. Til slutt legger jeg til en ny klasse-fil jeg kaller RandomDotOrg.cs hvor jeg vil implementere generering av passord, og rydder litt opp i dll-referansene.

CropperCapture[72]

Jeg er nå klar til å implementere tjenesten. I web servicen sin code behind sørger jeg først for å endre WebService namespace til http://pswin.com/SOAP/Receive (ikke glem dette!). Deretter sier jeg at Password skal arve fra ISMSReceiveSoap, og får Visual Studio til å generere stubs for metodene jeg trenger. Etter et par minutter er tjenesten ferdig:

    1 using System;
    2 using System.Web.Services;
    3 using PSWinCom.Gateway.Client;
    4 
    5 namespace RandomPasswordService
    6 {
    7     [WebService(Namespace = "http://pswin.com/SOAP/Receive")]
    8     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    9     [System.ComponentModel.ToolboxItem(false)]
   10     public class Password : WebService, ISMSReceiveSoap
   11     {
   12         #region ISMSReceiveSoap Members
   13 
   14         public ReturnValue ReceiveSMSMessage(IncomingSMSMessage m)
   15         {
   16             try
   17             {
   18                 Send(new Message
   19                 {
   20                     ReceiverNumber = m.SenderNumber, // return to sender
   21                     SenderNumber = m.ReceiverNumber,
   22                     Text = RandomDotOrg.GetNewPassword(),
   23                 });
   24             }
   25             catch { /* Log this !! */ }
   26             return new ReturnValue { Code = 200 };
   27         }
   28 
   29         public ReturnValue ReceiveDeliveryReport(DeliveryReport dr) {
   30             throw new NotImplementedException(); // not interested
   31         }
   32 
   33         public ReturnValue ReceiveMMSMessage(IncomingMMSMessage m) {
   34             throw new NotImplementedException(); // not interested
   35         }
   36         #endregion
   37 
   38         private void Send(Message message)
   39         {
   40             var smsClient = new SMSClient()
   41             {
   42                 Username = "",          // your Gateway username
   43                 Password = "",          // your Gateway passord
   44                 PrimaryGateway = "",    // the Gateway URL
   45                 SecondaryGateway = ""// backup Gatetway URL
   46             };
   47             smsClient.Messages.Add(0, message);
   48             smsClient.SendMessages();
   49         }
   50     }
   51 }

Metoden ReceiveSMSMessage kalles av gatewayen når det ankommer en ny melding. Interfacet har et par metoder til, for å ta imot meldingskvitteringer og MMS-meldinger, men de er jeg ikke interessert i her.

Jeg har laget en egen metode for å sende ut meldinger (linje 38), og det er her jeg bruker PSWinCom.Gateway.Client. Her kan du hente inn brukernavn, passord etc. fra konfigurasjonsfilen eller lignende.

Merk at jeg må returnere statuskode 200 fra ReceiveSMSMessage for å bekrefte at jeg klarte å ta imot meldingen. Hvis jeg ikke gjør dette vil gatewayen forsøke å sende meldingen på nytt (i henhold til definerte retry-regler).

Det er selvsagt mye som kan gjøres i forhold til feilhåndtering etc. Jeg ville normalt også inkludert endel logging. I tillegg kunne jeg ha benyttet meg av informasjonen i den innkommende meldingen, som hvilket kodeord som ble benyttet, eller hva den øvrige meldingsteksten var. Jeg kunne for eksempel lagt opp en mulighet for at brukerne kunne spesifisere hvor langt passordet skulle være ved å sende PASSORD n, hvor n er antall tegn.

Random passord

Det eneste som gjenstår er å implementere generering av passord. Til det vil jeg bruke en tjeneste som heter random.org, som gir meg ekte tilfeldighet, noe jeg ikke kan få til selv på windows. Her er GetNewPassord, som gjør et web-kall til random.org for å hente en random streng á 8 tegn.

    1 using System.Net;
    2 
    3 namespace RandomPasswordService
    4 {
    5     public static class RandomDotOrg
    6     {
    7         public static string GetNewPassword()
    8         {
    9             using (var webClient = new WebClient())
   10             {
   11                 return webClient
   12                     .DownloadString(
   13                     "http://www.random.org/strings/?" +
   14                     "num=1&len=8&digits=on&upperalpha=on" +
   15                     "&loweralpha=on&unique=on&format=plain&rnd=new")
   16                     .Trim();
   17             }
   18         }
   19     }
   20 }

(Merk at random.org har en quota per IP-adresse. Les guidelines for automated clients om du ønsker å benytte deg av random.org.)

Så der har du det altså, en komplett, toveis SMS-tjeneste i .Net / C# (som i tillegg kommuniserer med en ekstern tjeneste) på 71 linjer. Så hvis du har en god idé til en SMS-tjeneste bør du i alle fall ikke la kompleksiteten stopp deg, for så veldig mye enklere blir det ikke. 

Som nevnt skal jeg også skrive en artikkel om hvordan du kan teste tjenesten din uten å bruke PSWinCom’s gateway, så følg med om du er interessert i det.

Relatert artikkel: Dagens sitat via SMS (énveis SMS m/Ruby og XML over TCP).

Kategorier: Jobb, Software/verktøy.
RSS feed for kommentarene. Tilbaketråkk.

2 kommentarer til “Implementere toveis SMS i .Net”

  1. Mogens Johannessen Says:

    Dette er en meget nyttig funksjon. Du kan også gjøre nøyaktig det samme med SysMan’s SMS gateway, med den forskjell at du ikke sender dine passord ut på internett, men i stedet leverer og mottar direkte i GSM nettverket, hvor som helst i verden. Her kan du også holde rede på når meldinger blir sendt og mottatt, samt gjøre automatisk re-routing om en melding ikke kan leveres. Ta en titt på http://www.sysman.no/alert.htm

  2. Torbjørn Says:

    Heisann, Mogens. Jeg vet ikke om det har kommet klart fram, men jeg jobber altså i PSWinCom, så er det presisert.

    SMS via GSM modem kan være greit i noen sammenhenger, men i de fleste tilfeller vil en internett-basert tjeneste være å foretrekke. Blant fordelene er høyere kapasitet, raskere levering, fri avsender, korte nummer og en langt mer robust infrastruktur. Ved å bruke SSL sertifikat i begge ender, IP-restriksjoner etc kan sikkerhet også ivaretas på en tilfredsstillende måte. Bedrifter flest foretrekker å slippe å ha hardwarebaserte løsninger å drifte for dette formålet.

Skriv en kommentar

Tillatte tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Einar W. Høst: Det er jo læringen som gjør det morsomt! Se også http://norvig.com/21-days...

Pagliacci: OBS! tl;wr. Det er vel akuratt det jeg sliter med med min læring innenfor pr...

Torbjørn: La oss anta to ulike definisjoner av Template Method pattern - de to ytterpunkte...

Lars-Petter: Hei igjen. Siden du inviterer til å ta diskusjonen i bloggen, og har tatt deg t...

Torbjørn: Lars-Petter: Det er én måte å se det på. Det er absolutt fortsatt Template M...

Lars-Petter: Hei. Har du ikke i prinsippet her gått over fra Template Method (arv) til Strat...

Christian Abildsø: I alle fall i C#, så føles dette som kode som blir mer fleksibel men vanskelig...

Torbjørn: Hei Henrik, og takk for tilbudet. Ble oppmerksom på Rasberry Pi for under en uk...

Henrik Sandaker Palm: Ang. større hobby prosjekt. Du er som er en slik rakker på programmering har j...

Øivind Nilsen: Slutt å bruke mobilnummeret mitt som eksempel !...

Mulig relaterte linker

 Hold deg oppdatert

Søk i bloggen

Ferske innlegg

  • En historie om programmering
  • Template Method del 4: Multippel arv
  • Template Method Intermesso
  • Template Method del 3: Bare funksjoner
  • Kategorier

  • .net ninja (37)
  • Bøker (17)
  • Diverse prosjekter (35)
  • DSL (10)
  • Erlang (10)
  • F# (5)
  • Hardware (1)
  • Jobb (77)
  • Julekalender (51)
  • kjempekjekt.com (23)
  • LISP/Clojure (33)
  • NNUG / community (60)
  • O/RM & databaser (10)
  • Off topic (116)
  • OO-design/clean code (30)
  • Podcasts (14)
  • Polyglot (77)
  • Ruby (27)
  • Silverlight / RIA (3)
  • Software/verktøy (20)
  • Softwareutvikling (21)
  • Testing / TDD (30)
  • the contiki strip (13)
  • User experience (3)
  • WCF (3)
  • Webutvikling (32)
  • WPF (9)
  • WTF (12)
  • Last ned Wallpaper

    Programmeringsbloggens tøffe skrivebordsbakgrunn med snippets fra ulike språk laster du ned her!

    Abonner via epost

    Om du vil kan du få alle nye blogposter tilsendt til din epost. Abonner nå, det er kjempeenkelt!

    Meta