Search code examples
vb.netwebserverbackground-processwindowsiot

Web Server with Windows 10 IoT (vb.net)


I'm trying to import and convert from various sources in c# for create a web-server. The configuration is this:

CONFIG

Development platform: VS Community in 2015

Type of application: VB / Windows IoT Core / Background Application

Hardware: Raspberry Pi 3

OS: Windows 10 IoT (v. 10.0.14393.693)


PROBLEM

In some cases it is unable to send the page output. But in any case (even if it display the output), the page continues to load up to the crash of the application or stays in an endless loop.

CODE

The task

Public NotInheritable Class StartupTask
    Implements IBackgroundTask
    Private _Deferral As BackgroundTaskDeferral
    Public Async Sub Run(taskInstance As IBackgroundTaskInstance) Implements IBackgroundTask.Run
        taskInstance.GetDeferral()
        Dim server As New webServer()
        Await Windows.System.Threading.ThreadPool.RunAsync(AddressOf server.Start)
    End Sub
End Class

The class of webserver

Imports System.Text
Imports Windows.Networking.Sockets
Imports Windows.Storage.Streams

Friend Class webServer

    Private Const BufferSize As UInteger = 8192
    Public Async Sub Start()
        Try
            Dim listener As New StreamSocketListener()
            Debug.WriteLine("Debug: 1.1")
            Await listener.BindServiceNameAsync("8081").AsTask()
            Debug.WriteLine("Debug: 1.2")
            AddHandler listener.ConnectionReceived, Async Sub(sender, args)

                                                        Debug.WriteLine("Debug: 2")

                                                        Dim request As New StringBuilder()
                                                        Using input As IInputStream = args.Socket.InputStream
                                                            Dim data As Byte() = New Byte(BufferSize - 1) {}
                                                            Dim buffer As IBuffer = data.AsBuffer()
                                                            Dim dataRead As UInteger = BufferSize
                                                            While dataRead = BufferSize
                                                                Await input.ReadAsync(buffer, BufferSize, InputStreamOptions.[Partial])
                                                                request.Append(Encoding.UTF8.GetString(data, 0, data.Length))
                                                                dataRead = buffer.Length

                                                                Debug.WriteLine("Debug: 2.2 - " & request.ToString)

                                                            End While
                                                        End Using

                                                        Debug.WriteLine("Debug: 3")

                                                        Using output As IOutputStream = args.Socket.OutputStream

                                                            Debug.WriteLine("Debug: 3.1")

                                                            Using response As Stream = output.AsStreamForWrite()

                                                                Debug.WriteLine("Debug: 3.2")

                                                                Dim page As String = ""
                                                                Dim folder = Package.Current.InstalledLocation
                                                                Dim file = Await folder.GetFileAsync("index.html")
                                                                Dim readFile = Await Windows.Storage.FileIO.ReadLinesAsync(file)
                                                                For Each line In readFile
                                                                    page += line
                                                                Next

                                                                Debug.WriteLine("Debug: 3.3 - " & page)

                                                                Dim bodyArray As Byte() = Encoding.UTF8.GetBytes(page)
                                                                Dim bodyStream = New MemoryStream(bodyArray)

                                                                Debug.WriteLine("Debug: 3.4")

                                                                Dim header = "HTTP/1.1 200 OK" & vbCr & vbLf + "Content-Length: {bodyStream.Length}" & vbCr & vbLf + "Connection: close" & vbCr & vbLf & vbCr & vbLf
                                                                Dim headerArray As Byte() = Encoding.UTF8.GetBytes(header)

                                                                Debug.WriteLine("Debug: 3.5")

                                                                Await response.WriteAsync(headerArray, 0, headerArray.Length)

                                                                Debug.WriteLine("Debug: 3.6")

                                                                Await bodyStream.CopyToAsync(response)

                                                                Debug.WriteLine("Debug: 3.7")

                                                                Await response.FlushAsync()

                                                                Debug.WriteLine("Debug: 3.8")

                                                            End Using
                                                        End Using

                                                        Debug.WriteLine("Debug: 4")

                                                    End Sub

            Debug.WriteLine("Debug: 1.3")

        Catch generatedExceptionName As Exception
            Debug.WriteLine("Error: " & generatedExceptionName.Message)
        End Try
    End Sub



End Class

The Manifest

  <Capabilities>
    <Capability Name="internetClient" />
    <Capability Name="internetClientServer" />
    <Capability Name="privateNetworkClientServer" />
  </Capabilities>

Debug output

Debug: 1.1

Debug: 1.2

Debug: 1.3

Debug: 2

Debug: 2.2 - GET /index.html HTTP/1.1 Host: 192.168.1.146:8081 Connection: keep-alive (and all the header...)

Debug: 3

Debug: 3.1

Debug: 3.2

Debug: 3.3 - Baro Raspy WIoT Hello world :D

Debug: 3.4

Debug: 3.5

Debug: 3.6

Debug: 3.7

Debug: 3.8

Debug: 4

Il thread 0x64c è terminato con il codice 0 (0x0).

Il thread 0xcfc è terminato con il codice 0 (0x0).

I suppose I did something wrong with the asynchronous thread but I just can not understand.

Thanks in advance


Solution

  • I found the problem myself. The http header format was wrong. During the conversion from c# to vb I don't change this {bodyStream.Length} in the vb variable.

    From this

    Dim header = "HTTP/1.1 200 OK" & vbCr & vbLf + "Content-Length: {bodyStream.Length}" & vbCr & vbLf + "Connection: close" & vbCr & vbLf & vbCr & vbLf
    

    To this

    Dim header = "HTTP/1.1 200 OK" & vbCr & vbLf + "Content-Length: " & bodyStream.Length & vbCr & vbLf + "Connection: close" & vbCr & vbLf & vbCr & vbLf
    

    Now I just hope that this code will be usefull to someone, at least I will not have lost so much time unnecessarily :)