Introduction
Hello, name's Bobby. Was curious about the way I am doing threading on this app? I know we've all seen by now the Cassini web server Microsoft put out. I have worked in the internet website/video/chat industry for years. I was curious when .NET first came out, if it were possible to create a video server, and chat server in VB.NET. This would become my first dealings with doing threading outside of Java or really crappy VB controls that did threading.
I have since completed both servers in VB.NET. The first was the video server using server push JPG images streamed to a simple Java applet. This server was a better solution to video as my prior solution required an Apache build for Windows, and a friend who knew a lot of C++ but little MFC. :) However in the end I believe both the Apache server and my video server had one fatal problem, the way they are threaded?
This project contains one chat server currently inside a .NET application. It of course will end its run in a service form but I am still testing. Unlike Apache, and my previous servers, this one does not preload 100-200-800 threads to serve clients, store images/chat text. This one uses Socket.BeginRecieve
and Socket.BeginConnect
and Socket.BeginAccept
etc... As I assume you all know, these are asynchronous calls. For those who don't know, these socket functions don't block, but rather use a callback function/sub when they are done with executing. Supposedly there is some sort of Windows API for IO W/ sockets and drives and even memory. I am curious to see if this will hold up to 1000 clients all queuing server for new lines, bans, kicks, words etc.....
Please if you are interested in this, feel free to contact me, I am also working on a ASYNC Video server and video CAPTURE program and have written the Java clients for both, including a Java client that receives and displays live video but allows you to TIVO like rewind and pause etc...
Here are some source snips:
Private Sub Recieved(ByVal AR As IAsyncResult)
Dim inBytes As Long
Try
inBytes = mySock.EndReceive(AR)
Catch
Console.WriteLine("Socket Closed")
myState = ClientStates.Idle
mySock.Close() : LeaveRoom()
Exit Sub
End Try
rBufLen += inBytes
rString = System.Text.ASCIIEncoding.ASCII.GetString(rBuffer, _
0, rBufLen)
If inBytes <= 0 Then
Console.WriteLine("Socket Closed")
mySock.Close() : LeaveRoom()
Exit Sub
End If
If myState = ClientStates.Sending Then myState = myStateLast
If Not rString.IndexOf("<") >= 0 And _
rString.IndexOf(">") >= 2 Then
Exit Sub
End If
SyncLock Me
LastTimeHeard = Now
If Not IsNothing(myUser) Then
Console.WriteLine("Setting " & myUser.Username & Now)
End SyncLock
Select Case myState
Case ClientStates.WaitingCmd
If IsCmdDone() Then
If DEBUGME Then
Console.WriteLine("RECIEVED: " & rString)
DoCmd()
End If
Else
If DEBUGME Then
End If
mySock.BeginReceive(rBuffer, rBufLen, 2048,
SocketFlags.None, RecievedCB, Me)
End If
Case Else
End Select
End Sub
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Runtime.InteropServices
Public Class ServerListen
Private mySock As Socket
Private SockConnectCB As AsyncCallback
Private sockMode As Long
Public Sub New(ByVal IP As String, ByVal Port As Integer, _
ByVal Mode As Long)
mySock = New Socket(AddressFamily.InterNetwork, _
SocketType.Stream, ProtocolType.Tcp)
mySock.SetSocketOption(SocketOptionLevel.Socket, _
SocketOptionName.KeepAlive, 1)
mySock.Bind(New IPEndPoint(IPAddress.Parse(IP), Port))
mySock.Listen(7)
SockConnectCB = AddressOf SockConnect
sockMode = Mode
mySock.BeginAccept(SockConnectCB, Me)
End Sub
Public Sub SockConnect(ByVal AR As IAsyncResult)
Try
Dim S As Socket
Dim C As Client
S = mySock.EndAccept(AR)
S.SetSocketOption(SocketOptionLevel.Socket, _
SocketOptionName.DontLinger, 1)
S.SetSocketOption(SocketOptionLevel.Socket, _
SocketOptionName.KeepAlive, 1)
C = New Client
Select Case sockMode
Case ClientSockModes.modeADMIN
C.isADMIN = True
Case ClientSockModes.modeHTTP
C.isHTTP = True
Case ClientSockModes.modeCHAT
C.isCHAT = True
End Select
C.Accept(S)
mySock.BeginAccept(SockConnectCB, mySock)
SyncLock ezClients.SyncRoot
If Not ezClients.ContainsKey(C.ThreadId) Then _
ezClients.Add(C.ThreadId, C)
End If
End SyncLock
Catch ex As Exception
If DEBUGME Then
MsgBox("ERROR In ServerListen: " & ex.ToString())
End If
End Try
End Sub
End Class
I would be happy to share any code with those who have comments, wish to see it, or are developers working in the same field. If the code I post here is good enough to steal without contacting me in any way, then let's just say I am flattered, and happy stealing. However those looking for a quick download and work solution to internet chat are in for a surprise :) This server uses a non-RFC way of two way communication so it requires a client.