Aller au contenu | Aller au menu | Aller à la recherche


Développement de Web Service pour Windows Mobile

Comment utiliser un Service Web depuis un client sur Windows Mobile ?

Voyez les articles de Tébourbi Riadh

Sur page enseignement dans la partie .NET Compact Framework

developpez.com

Une explication sur les lenteurs lors de l'instanciation du premier appel web service : Webservice first call slow in C#

Try Catch System.net.web

N'oubliez pas de try/catch vos appels aux webservices pour éviter les erreurs :

          L'exception System.Net.WebException n'a pas été gérée
Message="Impossible d'établir une connexion au réseau."
using System.Web.Services;
using System.Net;
 
            try
            {
                MyProject.ws.User user = ws.auth("myLog", "myPass");
                Console.WriteLine(System.DateTime.Now + " WS - STOP [OK]");
            }
            //catch (SoapException error)
            catch (WebException error)
            {
                //error.InnerException
                //error.Message
                //error.Response
                //error.Status
                //error.StackTrace
 
                Console.WriteLine(System.DateTime.Now + " WS - STOP [Exception:" + error + "]");
                Console.WriteLine(System.DateTime.Now + " WS - STOP [Exception.InnerException:" + error.InnerException + "]");
                Console.WriteLine(System.DateTime.Now + " WS - STOP [Exception.Message:" + error.Message + "]");
                Console.WriteLine(System.DateTime.Now + " WS - STOP [Exception.Response:" + error.Response + "]");
                Console.WriteLine(System.DateTime.Now + " WS - STOP [Exception.Status:" + error.Status + "]");
                Console.WriteLine(System.DateTime.Now + " WS - STOP [Exception.StackTrace:" + error.StackTrace + "]"); 
            }
 
//04/01/07 05:30:00 WS - START
//04/01/07 05:30:01 WS - CALL
//04/01/07 05:30:05 WS - STOP [Exception:System.Net.WebException: Un message d'erreur ne peut pas être affiché, car un assembly de ressource facultatif le contenant est introuvable ---> System.Net.Sockets.SocketException: Un message d'erreur ne peut pas être affiché, car un assembly de ressource facultatif le contenant est introuvable
//à System.Net.Sockets.Socket.ConnectNoCheck()
//à System.Net.Sockets.Socket.Connect()
//à System.Net.Connection.doConnect()
//à System.Net.Connection.connect()
//at WorkItem.doWork()
//à System.Threading.Timer.ring()
 
//à System.Net.HttpWebRequest.finishGetResponse()
//à System.Net.HttpWebRequest.GetResponse()
//à System.Web.Services.Protocols.WebClientProtocol.GetWebResponse()
//à System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse()
//à System.Web.Services.Protocols.SoapHttpClientProtocol.doInvoke()
//à MyProject.ws.WsService.auth()
//à MyProject.FormLogin.menuItemConnexion_Click()
//à System.Windows.Forms.MenuItem.OnClick()
//à System.Windows.Forms.Menu.ProcessMnuProc()
//à System.Windows.Forms.Form.WnProc()
//à System.Windows.Forms.Control._InternalWnProc()
//à Microsoft.AGL.Forms.EVL.EnterMainLoop()
//à System.Windows.Forms.Application.Run()
//à MyProject.Program.lancerFormLogin()
//à MyProject.Program.Main()
//]
//04/01/07 05:30:05 WS - STOP [Exception.InnerException:System.Net.Sockets.SocketException: Un message d'erreur ne peut pas être affiché, car un assembly de ressource facultatif le contenant est introuvable
//à System.Net.Sockets.Socket.ConnectNoCheck()
//à System.Net.Sockets.Socket.Connect()
//à System.Net.Connection.doConnect()
//à System.Net.Connection.connect()
//at WorkItem.doWork()
//à System.Threading.Timer.ring()
//]
//04/01/07 05:30:05 WS - STOP [Exception.Message:Un message d'erreur ne peut pas être affiché, car un assembly de ressource facultatif le contenant est introuvable]
//04/01/07 05:30:05 WS - STOP [Exception.Response:]
//04/01/07 05:30:05 WS - STOP [Exception.Status:ConnectFailure]
//04/01/07 05:30:05 WS - STOP [Exception.StackTrace:à System.Net.HttpWebRequest.finishGetResponse()
//à System.Net.HttpWebRequest.GetResponse()
//à System.Web.Services.Protocols.WebClientProtocol.GetWebResponse()
//à System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse()
//à System.Web.Services.Protocols.SoapHttpClientProtocol.doInvoke()
//à MyProject.ws.WsService.auth()
//à MyProject.FormLogin.menuItemConnexion_Click()
//à System.Windows.Forms.MenuItem.OnClick()
//à System.Windows.Forms.Menu.ProcessMnuProc()
//à System.Windows.Forms.Form.WnProc()
//à System.Windows.Forms.Control._InternalWnProc()
//à Microsoft.AGL.Forms.EVL.EnterMainLoop()
//à System.Windows.Forms.Application.Run()
//à MyProject.Program.lancerFormLogin()
//à MyProject.Program.Main()
//]

System.Net.WebException : Unable to read data from the transport connection.

System.Net.WebException:
Message:Unable to read data from the transport connection.
InnerException:System.Net.Sockets.SocketException: Unknown error (0x0).

Unable to read data from the transport connection.

Le problème semble venir du MTU qui est réparable dans la base de registre :

Problem description:
There is a parameter called MTU (Maximum Transportation Unit) which is part of TCP/IP settings. Since I'm not network engineer, I'll try to explain on my way (for more information you can see the link Maximum Transmission Unit (MTU).
This parameter defines how big packets of data (in bytes) can be used for sending data (requests) over the network. Each web request is splitted into the packets which size is defined by MTU.
Now, the device (which sends request) has (or not) its own value for MTU. On the other hand the GPRS and network has their own MTU value (which is by default 1500).
Now, if device sends some request which is divided into the packets which size is BIGGER than the network's (or GPRS) MTU, the request arrived on the server side looks like the one above (with dots). As I understand, the GPRS cannot "understand" (read) all those packets that oversizes the it's own packets size, and just clears them (set them to zero). All those packets which size is less then GPRS's MTU, come to the server side correctly.

Anyhow, the SOLUTION is - to reduce the MTU value on the HandHeld device to the size which is SMALLER than GPRS's MTU.
On the link: TCP/IPv4 Configurable Registry Settings you can see some registry keys with their explanations. I use the MTU registry key and ADDED IT INTO THE registry path HKEY_LOCAL_MACHINE\Comm\Tcpip\Parms (as its written on the mentioned link). I set the value of MTU to the 1300 bytes (in decimal prezentation) or 514 as Hexadecimal presentation.
One more important registry key which is obviously (after testing) MUST to be added is :
EnablePMTUDiscovery (as DWORD) with decimal value set to 0. You need to add this registry key at the same registry path (HKEY_LOCAL_MACHINE\Comm\Tcpip\Parms). I was thinking it is not important, but YES it is important !

After adding mentioned two registry keys, should be good to restart the HandHeld (just warm reset).

When I did it - ALL MY REQUESTS arrived to the server correctly with all the values contained in my big object.

EnablePMTUDiscovery

  • Clé : Tcpip\Parameters
  • Type de valeur : REG_DWORD
  • Valeurs possibles : 0, 1 (False, True)
  • Par défaut : 1 (True)

La liste suivante décrit les paramètres que vous pouvez utiliser avec cette valeur du registre 'EnablePMTUDiscovery' :

  • 1 : Lorsque vous définissez EnablePMTUDiscovery sur 1, TCP tente de découvrir la taille de l'unité MTU (Maximum Transmission Unit ) ou la taille de paquet la plus élevée sur le chemin d'accès à un hôte distant. TCP peut éliminer la fragmentation sur les routeurs sur le chemin d'accès qui connecte des réseaux à différentes unités MTU, en découvrant l'unité MTU du chemin et en limitant les segments TCP à cette taille. Inversement, la fragmentation affecte le débit TCP.
  • 0 : Nous vous recommandons de définir EnablePMTUDiscovery sur 0. Ainsi, une unité MTU de 576 octets est utilisée pour toutes les connexions qui ne sont pas des hôtes sur le sous-réseau local. Si vous ne définissez pas cette valeur sur 0, un attaquant peut forcer la valeur de l'unité MTU à une très petite valeur et ainsi surmener la pile.

Auth BASIC : protocol error with C#

Basic HTTP Authentication in a Web Service : C# doesn't support HTTP 1.1 correctly, so you will have to do quite a bit to get it to work properly. First, you have to force it to run HTTP 1.0 instead, and you do that by subclassing your proxy class:

class OMyService : My.MyService
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        HttpWebRequest webRequest = (HttpWebRequest)base.GetWebRequest(uri);
        webRequest.ProtocolVersion = HttpVersion.Version10;
        return webRequest;
    }
}
 
iface.Credentials = new NetworkCredential("user1", "password1");

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.

Fil des commentaires de ce billet