Web server problems - General Discussion - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Web server problems


  • Please log in to reply
8 replies to this topic

#1 OZ8ET

OZ8ET

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts
  • LocationHundested, Denmark

Posted 14 July 2013 - 08:29 AM

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]Hi[/color][/font]

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]I am running a web server on NP2 (previously on NP1) and it seems to run ok.[/color][/font]

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]The problem is, when I start pushing it - a little too much processing for each received message combined with hysterical pushing the refresh button on the browser (more than 4 times in Debug mode - a little more en Release mode) - it falls over!.[/color][/font]

 

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]I have tried most of the servers shown in this forum, and they usually works when testing, but when pushing them as above, the same thing happens. [/color][/font]

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]I have not been successful trying to multitask.[/color][/font]

 

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]I have nailed Down the problem to the "socket.Accept" statement.[/color][/font]

 

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]I get this exception: “[/color][color=rgb(30,30,30);]A first chance exception of type 'System.Net.Sockets.SocketException' occurred in Microsoft.SPOT.Net.dll[/color][color=rgb(34,34,34);]”, the first message is received and then everything stops. Other tasks (Onewire and display) are still running.[/color][/font]

 

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]Questions:[/color][/font]

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]Is there a limit to how many outstanding messages the socket Accept wil have? And if så – how many?[/color][/font]

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]Is there a way to overcome the problem?[/color][/font]

 

[font="arial, helvetica, sans-serif;"][color=rgb(34,34,34);]Any help is appreciated.[/color][/font]



#2 Anthony Glenwright

Anthony Glenwright

    Advanced Member

  • Members
  • PipPipPip
  • 71 posts

Posted 14 July 2013 - 09:48 AM

I believe the limit on sockets for the netduino is 16, and if you are hitting refresh madly then you could hit that limit easily enough. In my web server implementation, I have added a counter for active worker threads and a bit of code that does not create a new worker unless there are less than 4 workers running already. Also I added a setsockoption DontLinger and that seemed to help. With these two enhancements, the web server isn't fast, but it is reliable...

#3 OZ8ET

OZ8ET

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts
  • LocationHundested, Denmark

Posted 14 July 2013 - 11:34 AM

Thanks Anthony.

It sounds like a good solution. Could you share some code please?

Erik



#4 Anthony Glenwright

Anthony Glenwright

    Advanced Member

  • Members
  • PipPipPip
  • 71 posts

Posted 14 July 2013 - 11:25 PM

The SetSocketOption call goes in between your listening socket's bind and listen calls:

mobjListenSocket = New Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp)mobjListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)mobjListenSocket.Bind(New IPEndPoint(IPAddress.Any, Me.Port))mobjListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, True)mobjListenSocket.Listen(32)

The worker thread governor code consists of an ArrayList where I add in each worker thread as it is created, and a loop to check that there are less than MAX_WORKERS running:

Public Sub StartNewWorker(ByRef AcceptSocket As Socket)  Dim intWorkerCount As Integer = -1  ' If MAX_WORKERS is reached wait for a worker to complete  Do Until intWorkerCount <> -1 AndAlso intWorkerCount < MAX_WORKERS	        SyncLock mobjWorkerThreads      intWorkerCount = 0      If mobjWorkerThreads.Count <> 0 Then       For intWorkerIndex As Integer = (mobjWorkerThreads.Count - 1) To 0 Step -1			           If DirectCast(mobjWorkerThreads(intWorkerIndex), Thread).IsAlive Then			               ' only count the threads that are active			               intWorkerCount = intWorkerCount + 1			           End If		           Next      End If    End SyncLock	        ' thread limit reached, wait and try again    If intWorkerCount >= MAX_WORKERS Then      Thread.Sleep(100)      ' todo: timeout?  Loop  ' Create new worker thread  Dim objWorker As New HTTPServerWorker(AcceptSocket)  AddHandler objWorker.JSONRequest, AddressOf OnJSONRequest	    AddHandler objWorker.ConnectWebSocket, AddressOf ConnectWebSocket  Dim objWorkerThread As New Thread(New ThreadStart(AddressOf objWorker.ExecuteRequest))	    objWorkerThread.Start()  ' Add to thread pool  SyncLock mobjWorkerThreads	        mobjWorkerThreads.Add(objWorkerThread)	        Debug.Print("New worker thread added.  Worker Thread Count: " & mobjWorkerThreads.Count.ToString)  End SyncLockEnd Sub


#5 Anthony Glenwright

Anthony Glenwright

    Advanced Member

  • Members
  • PipPipPip
  • 71 posts

Posted 14 July 2013 - 11:34 PM

PS:  The web server is a substantially modified version of http://www.microframework.nl

 

Also if you implement the worker thread governor you will need to add in periodic calls to this function, to remove completed threads from the arraylist.

 

Private Sub MonitorConnections()   ' Endless loop   While Thread.CurrentThread.ThreadState <> ThreadState.AbortRequested   ' Allow other processes some time.  The pause needs to be long enough that this process doesn't have a SyncLock on mobjWorkerThreads   ' all of the time, but short enough that completed threads are removed from the thread pool in a timely manner   Thread.Sleep(750)

  ' Lock Thread Pool   If mobjWorkerThreads.Count <> 0 Then   SyncLock mobjWorkerThreads   Me.ActivityLED.SwitchOn()

  If mobjWorkerThreads.Count <> 0 Then   For intWorkerIndex As Integer = (mobjWorkerThreads.Count - 1) To 0 Step -1   ' If the thread has finished, remove it   If Not DirectCast(mobjWorkerThreads(intWorkerIndex), Thread).IsAlive Then   ' Remove worker from list   mobjWorkerThreads.RemoveAt(intWorkerIndex)   Debug.Print("Worker #" & intWorkerIndex.ToString() & " has stopped, removing from pool.  New Worker Pool Count: " & mobjWorkerThreads.Count.ToString)   Debug.GC(True)   End If   Next   End If   End SyncLock   Else   Me.ActivityLED.SwitchOff()   End If   End While End Sub



#6 Anthony Glenwright

Anthony Glenwright

    Advanced Member

  • Members
  • PipPipPip
  • 71 posts

Posted 14 July 2013 - 11:36 PM

By the way, I implemented the thread governor to stop the Netduino from running out of memory rather than running out of sockets - so you might just want to start with the .SetSocketOption call and see how you go.



#7 OZ8ET

OZ8ET

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts
  • LocationHundested, Denmark

Posted 15 July 2013 - 03:37 AM

Thanks again Anthony.I will study the code and do some experiments.

best regards

Erik



#8 OZ8ET

OZ8ET

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts
  • LocationHundested, Denmark

Posted 15 July 2013 - 05:04 AM

I have tried this, but I still have problems. It gives me however et better control of what happens.

The Socket.Accept falls over when it has more than 3 outstanding messages. It then fires a socket excepton but it is not caught by the try-catch.

Because of this, the thread never dies and the clean-up wil not remove the thread from the array.

I cannot see how I can stop the socket from accepting messages.

This is odd!



#9 OZ8ET

OZ8ET

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts
  • LocationHundested, Denmark

Posted 15 July 2013 - 01:17 PM

I found his article: http://blogs.msdn.co...work-netmf.aspx

It works quite good.

Erik






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.