Toon posts:

[VB.net] connectie met msn messenger service maken

Pagina: 1
Acties:
  • 1.145 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik probeer mijn eigen msn client te maken voor pocketpc (windows mobile 5) met vb.net in visual studio 2005.
De msn messenger service wil spijtig genoeg niet echt meewerken...

Ik slaag erin om de eerste opdracht (namelijk VER MSNP8 CVR0) door te sturen, maar ik krijg geen antwoord terug.
Als ik hetzelfde doe via netcat, dan krijg ik meteen antwoord.
Of als ik mijn programmaatje laat verbinding maken met een webserver, dan krijg ik ook meteen antwoord. Enkel de msn server wilt niet meewerken.

Wat het programmaatje wel en niet doet:

Verbinding maken met messenger.hotmail.com:1863 OK
Een streamwriter en streamreader object maken OK
Schrijven naar de streamwriter OK
Lezen van de streamreader NIET OK: Ik krijg ik steeds EOF

Het bewuste stukje code:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  Public Sub Connect()
        messages.Add("trying to open a connection...")
        client = New TcpClient(host, port)
        stream = client.GetStream()
        If Not stream.CanRead Or Not stream.CanWrite Then
            Throw New IOException("Could not connect to MSN messenger service.")
        End If
        Try
            writer = New StreamWriter(stream, UTF8)
            writer.AutoFlush = True
            reader = New StreamReader(stream, UTF8)
        Catch ex As Exception
            Throw New IOException("Error opening stream")
        End Try
        messages.Add("connection open")
    End Sub

    Public Sub Authenticate()
        messages.Add("starting authentication")
        Dim versions As String = "VER"
        Dim s As String
        For Each s In ver
            versions = versions + " " + s
        Next s
        Dim toSend As String = versions
        writer.WriteLine(toSend)
        messages.Add("sent:" + toSend)
        Dim res As String = ""
        messages.Add(reader.EndOfStream)
        messages.Add(reader.Peek)
        While reader.Peek() > -1 'Deze geeft blijkbaar steeds -1...
            res += reader.ReadLine()
        End While
        messages.Add("server said: " + res)
    End Sub


Iemand een idee hoe ik wel antwoord krijg van msn?

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:05
Kijk eens of er data op de stream zit mbhv DataAvailable member van de onderliggende stream ipv de Peek member v/de streamreader.

https://fgheysels.github.io/


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

zeker dat er geen CRLF nodig is ?

Bovendien is er volgens mij een messenger COM object beschikbaar. Waarom gebruik je dat niet ?

[ Voor 60% gewijzigd door H!GHGuY op 01-02-2006 21:28 ]

ASSUME makes an ASS out of U and ME


Verwijderd

Topicstarter
messages.Add("server has data available: " + CStr(stream.DataAvailable())) geeft mij false, dus daar is het al niet in orde.
Ik heb ook even getest met writer.write(toSend+"\r\n") en writer.write(toSend+vbCrLf), maar ik krijg dan juist hetzelfde resultaat.

De reden dat ik zelf met de sockets zit te spelen is omdat zo weinig mogelijk extra code te gebruiken omdat het op mijn pda moet terechtkomen.
(oorspronkelijk wou ik het in java programmeren, maar de java ondersteuning op windows mobile is niet in orde)

Ik heb een voorbeeldje gevonden waar ze het als volgt doen:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
Function GetMSNReturn() As MSNServerCMD

        Dim sOutput As String
        sOutput += streamReader.ReadLine
        While streamReader.Peek <> -1
            sOutput += vbCrLf + streamReader.ReadLine
        End While
        If sOutput.Length > 0 Then Me.LogToFile("MSN Return Value:" + sOutput.ToString)
        Return New MSNServerCMD(sOutput)
    End Function


Ze roepen deze code ook meteen na het verzenden van de opdracht.
De code is afkomstig van http://www.codeproject.com/vb/net/TcpClientMsnProtocol.asp

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 28-03 23:48

Gerco

Professional Newbie

Je geeft de MSN server geen tijd om te reageren. Zet eens een vertraging tussen het schrijven en lezen, een seconde zou ruim voldoende moeten zijn.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
Even in een aparte post, omdat het anders wat te lang wordt.
Ik heb wat extra tests toegevoegd (die allemaal true geven, behalve dataAvailable) en nu ook de leescode herschreven zodat hij wacht totdat er antwoord is.
Geen resultaat echter.
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    Public Sub Authenticate()
        messages.Add("starting authentication")
        Dim versions As String = "VER"
        Dim s As String

        For Each s In ver
            versions = versions + " " + s
        Next s
        Dim toSend As String = versions
        messages.Add("socket is open before writing: " + CStr(client.Client.Connected))
        messages.Add("stream is writable: " + CStr(stream.CanWrite))
        writer.WriteLine(toSend)

        messages.Add("sent: " + toSend)
        messages.Add("socket is open after writing: " + CStr(client.Client.Connected))
        messages.Add("socket is readable: " + CStr(stream.CanRead))
        messages.Add("server has data available: " + CStr(stream.DataAvailable()))

        Dim res As String = ""
        messages.Add(reader.EndOfStream)
        messages.Add(reader.Peek)
        Dim foundData As Boolean = False
        While Not foundData
            While stream.DataAvailable

                res += reader.ReadLine()
                foundData = True
            End While
        End While
        messages.Add("server said: " + res)

    End Sub


EDIT:
Gerco schreef op woensdag 01 februari 2006 @ 23:39:
Het kan aan mij liggen, maar ik zie nog geen vertragingscode. Zet eens System.Threading.Thread.Sleep(1000) na writer.WriteLine(toSend).
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
messages.Add("sent: " + toSend)

        System.Threading.Thread.Sleep(1000)

        messages.Add("socket is open after writing: " + CStr(client.Client.Connected))
        messages.Add("socket is readable: " + CStr(stream.CanRead))
        messages.Add("server has data available: " + CStr(stream.DataAvailable()))

        Dim res As String = ""
        messages.Add(reader.EndOfStream)
        messages.Add(reader.Peek)


        While stream.DataAvailable

            res += reader.ReadLine()

        End While

Dit levert een een IOException op (verbinding verbroken) na de server has data available message (die overigens nog steeds false is, spijtig genoeg).

[ Voor 29% gewijzigd door Verwijderd op 01-02-2006 23:45 ]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 28-03 23:48

Gerco

Professional Newbie

Het kan aan mij liggen, maar ik zie nog geen vertragingscode. Zet eens System.Threading.Thread.Sleep(1000) na writer.WriteLine(toSend).

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
Het is in orde geraakt, volgens mij waren er gewoon wat problemen met de messenger service :).
Ik heb alles in een aparte klasse gestoken en alles werkt perfect.
Alleen die stream.dataAvailable geeft altijd false, maar met peek() lukt ook.

Ik ben nu bezig met connectie te maken via ssl naar de Passport-server.
Maar visual studio 2005 beta 2 vond de klasse WebClient niet.
De volledige versie (legaal) is aan het installeren, nadien zou alles moeten werken.

Verwijderd

Ik zou voor de gein hier eens kijken http://www.xihsolutions.net/dotmsn/. Is een open source client library voor MSN (inclusief file transfers, user avatars, de laatste features). Werkt als een trein, en je kunt hem wellicht voor het compact framework kunnen compileren. Spaart je een hoop uurtjes werk.

Verwijderd

Topicstarter
Ik heb al even naar dotMSN gekeken, maar ik wil eigenlijk gewoon mijn eigen msn-client maken :).

Ik ben de code die ik al heb in threads aan het stoppen zodat het programma blijft reageren.
Maar er is blijkbaar een raar probleempje met de volgende code, die ik in een thread gebruik:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
    Public Sub displayMessages()
        Dim i As Integer = 0
        While running
            While i < messages.length
                lstStatus.Items.Add(messages.getMessage(i)) ' Hij geeft hier een exception. Het maakt trouwens niet uit of hier nu messages... staat of gewoon een string, de fout blijft.
                i += 1
            End While
            Thread.Sleep(500)
        End While
    End Sub

Deze code gebruik ik om bij het ontwerpen en debuggen de berichten, die in de lijst in messages staan, op het scherm te krijgen.
lstStatus is niets anders dan een listbox in mijn form.
Deze code compilet perfect, en ik kan ze uitvoeren onder windows xp. Als ik deploy naar mijn pda, dan krijg ik een NotSupportedException was unhandled bericht.
Meer info krijg ik niet, want er staat: 'Er kan geen foutmelding worden weergegeven omdat een optionele bron-assembly niet kan worden gevonden'.

Het grappige is dat ik wel dingen van buiten deze thread aan lstStatus kan toevoegen, maar niet van binnen de thread (althans op mijn pda).

Doe ik hier nu iets echt fout of doet visual studio weer eens raar?

EDIT: Ik denk dat het aan mij ligt. Controls kunnen blijkbaar enkel aangesproken worden vanuit de thread waarin ze werden gemaakt. Ik laat wel weten als het lukt (en anders ook). Toch raar dat VS geen compile-fout geeft én juist werkt onder windows, maar niet op pocket pc.

@Whoami: Ik heb bij het creëren van een nieuw project gekozen voor smart device, dus ik veronderstel dat VS enkel de controls uitkiest die draaien op het .net compact framework (anders is het erg gesteld met VS).
Het zit hem dus in de lstStatus.add(...), deze kan blijkbaar niet worden aangeroepen vanuit een andere thread dan de thread waarin de control is gemaakt.
Ik moet control.invoke gebruiken.

[ Voor 20% gewijzigd door Verwijderd op 04-02-2006 14:05 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 01:05
Blijkbaar roep jij een method op die niet ondersteund is door het compact framework.
Is het de getMessage of de Add method die exceptie gooit ?

Als je een applicatie maakt voor een smart device, zoals een pda, kan je dan wel een gewone 'windows app' daar naar uploaden ?
Moet je daar geen andere UI voor maken ? Moet je geen Smart Device UI maken voor je PDA ?

(Als je je applicatie goed hebt opgezet, kan je nog steeds gebruik maken van je 'core classes' en moet je enkel een andere UI bouwen).

[ Voor 83% gewijzigd door whoami op 04-02-2006 11:50 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Zoals beloofd de oplossing (met dank aan forums.microsoft.com).

Om de controls van een form aan te spreken vanuit een thread, moet je (als het nodig is) invoke aanroepen.
In het gewone .net framework gaat dit makkelijk, maar in het .net compact framework zit er een addertje onder het gras. Je moet eerst zelf een delegate definiëren.

De code:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    Private Delegate Sub printMessageInvoker(ByVal messageToPrint As stMess)
    Private Sub displayMessages()
        Dim i As Integer = 0
        While running
            While i < messages.length
                Dim res As stMess = messages.getMessage(i)
                If lstStatus.InvokeRequired Then
                    lstStatus.Invoke(New printMessageInvoker(AddressOf printMessage), New Object() {res})
                Else
                    lstStatus.Items.Add(res)
                End If
                i += 1
            End While
            Thread.Sleep(500)
        End While

    End Sub
    Private Sub printMessage(ByVal messageToPrint As stMess)
        lstStatus.Items.Add(messageToPrint.toString)
        lstStatus.Update()

    End Sub

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:05
Verwijderd schreef op zondag 05 februari 2006 @ 10:37:
Zoals beloofd de oplossing (met dank aan forums.microsoft.com).

Om de controls van een form aan te spreken vanuit een thread, moet je (als het nodig is) invoke aanroepen.
Eh ja, dat moet je inderdaad doen; maar jij hebt het hier nergens over multi-threading gehad, dus hoe konden we jou dan goed helpen ?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ah, mijn excuses.
Ik heb blijkbaar vergeten duidelijk aan te geven dat ik tussen mijn eerste posts en de laatste alles in threads heb gestopt!
In iedere geval: het werkt.

Nu ben ik bezig aan de implementatie van enkele methodes die de berichten die de notification server stuurt, moeten opvangen en afhandelen.
Pagina: 1