Correct way to avoid a ObjectDisposedException, in this case? - c#

I am currently getting an ObjectDisposedException on the following line.
var client = ((Socket) asyncResult.AsyncState).EndAccept(asyncResult);
System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.'
I was just wondering, what is the right way (in terms of best practice) to avoid an error like this? I'm unsure on how to handle it, how do I check if its disposed before hand, but is that what I should be doing? Or checking something else.
I'm self taught C# so I never learnt things like this, could someone give some insight?
Here is the full class:
internal sealed class SocketHandler : IDisposable
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
private readonly Socket _serverSocket;
public SocketHandler()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Load();
}
public void Dispose()
{
_serverSocket?.Close(); // close also calls dispose...
}
private void Load()
{
var config = Program.Server.ConfigHandler;
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, config.GetConfigValueByKey("network.sockets.port").ToInt()));
_serverSocket.Listen(int.Parse(config.GetConfigValueByKey("network.sockets.backlog")));
_serverSocket.BeginAccept(OnAcceptConnection, _serverSocket);
}
private void OnAcceptConnection(IAsyncResult asyncResult)
{
try
{
if (_serverSocket == null)
{
return;
}
var client = ((Socket) asyncResult.AsyncState).EndAccept(asyncResult);
var playerHandler = Program.Server.BaseHandler.PlayerHandler;
var players = playerHandler.Players;
var config = Program.Server.ConfigHandler;
var maxConnections = int.Parse(config.GetConfigValueByKey("game.players.limit"));
var maxConnectionsPerIp = int.Parse(config.GetConfigValueByKey("game.players.ip_limit"));
if (players.Count >= maxConnections)
{
Logger.Warn("Incoming connection was refused because the player limit was exceeded.");
client.Shutdown(SocketShutdown.Both);
client.Close();
return;
}
if (players.Values.Count(x => x != null && !x._disconnected && x.getIp() == client.RemoteEndPoint.ToString().Split(':')[0]) > maxConnectionsPerIp)
{
Logger.Warn("Incoming connection was refused because the IP limit was exceeded.");
client.Shutdown(SocketShutdown.Both);
client.Close();
return;
}
var clientId = Randomizer.Next(1, 10000);
Program.Server.BaseHandler.PlayerHandler.TryAddPlayer(clientId, new Player(clientId, client, new InitialPacketParser()));
}
catch (SocketException socketException)
{
Logger.Fatal(socketException, "Failed to accept socket connection.");
}
finally
{
_serverSocket?.BeginAccept(OnAcceptConnection, _serverSocket);
}
}
}

As far as I understand the reference source a Socket does not Dispose itself. So, since your _serverSocket is private, you are the only one to control when it is disposed.
Your OnAcceptConnection() method already started to try to check that, but not completely.
In your Dispose() method (or any other place where you Close() or Dispose() your _serverSocket) you need to also set _serverSocket to null. You can do it like this in a thread-safe way:
public class SocketHandler
{
private Socket _serverSocket; // not read-only
/* ... */
public void Dispose()
{
Socket tmp = _serverSocket; // save instance
_serverSocket = null; // set field to null
tmp?.Close();
}
Now your OnAcceptConnection() returns when it checks if (_serverSocket == null) and you avoid the exception.

The problem might also come from how you are using SocketHandler in the first place. I can see nothing wrong with how the IDisposable pattern is implemented in your class. The normal way to avoid accessing a Disposable class after it has been disposed is wrapping it in a using statement which will auto-dispose the class after leaving the block:
using( SocketHandler handler = new SocketHandler())
{
(...)
} //handler will be disposed and not accessible after here
For more information on this Microsoft Docs has a good article explaining IDispose
EDIT:
Thanks for pointing out that I was on a completely wrong way to understand the question.
I at least recreated the scenario to best of my knowledge:
class Program
{
static void Main(string[] args)
{
using (C1 instance = new C1())
{
Task.Factory.StartNew(() =>
{
Task.Delay(1000);
bool disposed = (bool)typeof(C1).GetField("disposed", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(instance);
if (disposed)
{
Console.WriteLine("Already disposed will not call DoSomething()");
}
else
{
instance.DoSomething();
}
});
}
Console.ReadKey(true);
}
}
class C1 : IDisposable
{
bool disposed = false;
public C1()
{
}
public void DoSomething()
{
if (disposed)
throw new ObjectDisposedException("C1");
Console.WriteLine("Still existing!");
}
public void Dispose()
{
Dispose(true);
Console.WriteLine("Disposed!");
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
disposed = true;
}
}
And managed to workaround the exception with a reflection. Assuming that microsoft will have used the same pattern + namings as they are according to their Framework Design Guidelines this solution could at least be used as a workaround.
But I highly doubt that this the best way.

Related

Is there any way to check if socket connection is available?

I have the following code:
class MyServer
{
TcpListener myList;
Socket socket;
public MyServer(string ip)
{
this.myList = new TcpListener(ip, 12001);
this.myList.Start();
Thread t = new Thread(new ThreadStart(GetConnection));
t.Start();
}
public void GetConnection()
{
try
{
socket = myList.AcceptSocket(); //(1)
}
catch
{
Console.WriteLine("Error");
}
}
public void StopListening()
{
this.myList.Stop();
}
}
And it works well: I start the server, and if I "regret" I call StopListening() (before connection has been made!) and because I close myList, (1) is failing.
Is there any way to write this code without the try{}catch{} - rewrite GetConnection() as:
public void GetConnection()
{
while ( myList is open && there is no connection)
{
//do nothing
}
if (myList is open)
{
this.socket = myList.AcceptConnection();
}
}
or another way? Thanks.
socket = myList.AcceptSocket()
Is a blocking call, so it will throw an exception if the underlying socket stops Listening so you will need a try/catch anyway for that blocking call.
You could test:
if (myList.Server.IsBound)
{
this.socket = myList.AcceptConnection();
}
This way you wouldn't block for the next connection unless the socket was actively listening. But like I said if you want the program to be able to stop listening at some point, then this will still throw an exception when you call myList.Stop()

Adding Events to .NET Sockets in C#

I have a CustomSocket class that extends the Socket that adds events to get some feedback about clients disconnecting from a server. I am wondering how to add my client disconnect method to the event delegate if the _listenerSocket.Accept() method returns a Socket and not my CustomSocket class which has the events in it?? The code is as below.
public class CustomSocket : Socket
{
private readonly Timer timer;
private const int INTERVAL = 1000;
public delegate void SocketEventHandler(Socket socket);
public CustomSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) : base(addressFamily, socketType, protocolType)
{
timer = new Timer { Interval = INTERVAL };
timer.Elapsed += TimerTick;
}
public CustomSocket(SocketInformation socketInformation) : base(socketInformation)
{
timer = new Timer { Interval = INTERVAL };
timer.Elapsed += TimerTick;
}
private readonly List<SocketEventHandler> onCloseHandlers = new List<SocketEventHandler>();
public event SocketEventHandler SocketClosed
{
add { onCloseHandlers.Add(value); }
remove { onCloseHandlers.Remove(value); }
}
public bool EventsEnabled
{
set
{
if (value)
timer.Start();
else
timer.Stop();
}
}
private void TimerTick(object sender, EventArgs e)
{
if (!Connected)
{
foreach (var socketEventHandler in onCloseHandlers)
socketEventHandler.Invoke(this);
EventsEnabled = false;
}
}
// Hiding base connected property
public new bool Connected
{
get
{
bool part1 = Poll(1000, SelectMode.SelectRead);
bool part2 = (Available == 0);
if (part1 & part2)
return false;
else
return true;
}
}
}
I was thinking that I would want to add for events on the Socket that is returned from the Socket.Accept(); method except that this is a Socket is not a CustomSocket so there there are no events. I think I going about this the wrong way.
static void ListenThread()
{
try
{
for (; ; )
{
_listenerSocket.Listen(5);
_clients.Add(new ClientData(_listenerSocket.Accept()));
}
}
catch
{
//
}
}
I tried this
static void ListenThread()
{
try
{
for (; ; )
{
_listenerSocket.Listen(5);
CustomSocket cs = (CustomSocket) _listenerSocket.Accept();
_clients.Add(new ClientData(cs));
cs.SocketClosed += CsOnSocketClosed;
}
}
catch
{
//
}
}
But I get casting errors etc..
Any help would be appreciated..
Matt
You can't cast a Socket to a CustomSocket. Because Accept returns a Socket and not a CustomSocket.
You could wrap a Socket in a CustomSocket which takes a Socket as parameter like this to solve your issue.
class CustomSocket
{
private Socket _socket;
public Socket Socket
{
get
{
return _socket;
}
}
public CustomSocket(Socket s)
{
_socket = s;
}
}
You definitely need to use composition instead of inheritance for this, due to the fact that the Accept() method will never return an instance of your own class. See existing socket wrappers like TcpClient, NetworkStream, etc. for inspiration. There's not enough detail here to be able to provide specific guidance as to how to compose your Socket instance. However, for dealing with the Accept() method scenario specifically, it would look something like this:
class CustomSocket
{
private Socket _socket;
public CustomSocket(Socket socket)
{
_socket = socket;
}
public CustomSocket Accept()
{
return new CustomSocket(_socket.Accept());
}
}
Finally, it's not entirely clear what the overall goal in sub-classing/wrapping the Socket class here is, but the code you posted so far looks like you are trying to abstract a polling mechanism on the Socket class.
But polling a Socket is the least efficient way to use it, and is unnecessary. You may find that by using the asynchronous model with the Socket (e.g. Socket.BeginAccept(), ...BeginRead(), etc.) that you don't need to abstract anything, and that you can use the Socket class directly.

C# TcpSockets Do I disconnect the clean/proper way?

So i know there are a lot of articles out there on this topic and i did read a lot of them i would say but for some reason im sure my code is not doing what it is supposed to do.
I want to close a connection between my Server and my Client.
Now on the serverside i start the disconnect with this code
public void shutdown()
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
And on the Client side i have some troubles understanding how i get to the disconnect what i believe is happening is the following: in my async receive callback i should get an error since the server started a shutdown sequence and i have to handle that (right???) so my code for the client looks like this:
ReceiveCallback:
private void ReceiveCallback(IAsyncResult result)
{
int bytesRecieved = 0;
byte[] tempBuff;
//Try to receive But if a Socket error occures disconnect otherwise start Receiving again
try
{
bytesRecieved = _socket.EndReceive(result);
}
catch (SocketException sockEx)
{
Disconnect(sockEx);
return;
}
catch (ObjectDisposedException disposeEx)
{
Disconnect(disposeEx);
return;
}
catch (Exception ex)
{
StartReceive();
return;
}
if (bytesRecieved == 0)
{
StartReceive();
return;
}
tempBuff = new byte[bytesRecieved];
Buffer.BlockCopy(_buffer, 0, tempBuff, 0, bytesRecieved);
StartReceive();
_packHandler.handlePacket(tempBuff);
}
Disconnect:
public void Disconnect()
{
if (!_socket.Connected)
{
return;
}
_socket.BeginDisconnect(false, DisconnectCallback, null);
}
DisconnectCallback
private void DisconnectCallback(IAsyncResult result)
{
_socket.EndDisconnect(result);
_socket.Close();
}
(The Disconnect Method is overloaded so if i get an exception it puts up a messageBox and then also calls Disconnect. Just so i know what happened.)
Where am i wrong and what can i improve uppon ???
I tried the code and it seemed to work but i then looked with netstat if all sockets are closed and the client socket was not. It was in FIN_WAIT_2 which means that it (or the server???) did not yet send the FIN packet right ?
Oh and then i tried it again with this line changed:
if (bytesRecieved == 0)
{
StartReceive();
return;
}
TO
if (bytesRecieved == 0)
{
Disconnect;
return;
}
which then threw an exception on the serverside and on the clientside the client said that the connection was closed by the server ???
EDIT: Even when i have closed both Programs Netstat still shows the port in a WAITING status. what does that tell me ?
Your normal disconnect has a shutdown which will clear the socket so it can disconnect properly but your async style never calls shutdown. I added it in a convenient location below.
public void Disconnect()
{
if (!_socket.Connected)
{
return;
}
_socket.Shutdown(SocketShutdown.Both); // Make sure to do this
_socket.BeginDisconnect(false, DisconnectCallback, null);
}
EDIT:
From the sounds of it you don't have a reason to be using the Async Method? The async methods are so you can send data in a separate execution thread freeing up your thread to do some data processing for instance while that occurs.
I don't see any processing going on so I suggest you change disconnect like this and see if it resolves the problem. Because I don't think you are waiting on the Async methods which will not work out well.
public void Disconnect()
{
if (!_socket.Connected)
{
return;
}
shutdown(); //Your standard disconnect that you showed up top. Scoping might be required.
}
A bit of data on Async can be scrounged up here: http://msdn.microsoft.com/en-us/library/38dxf7kt(v=vs.110).aspx
Important is:
If a server starts a shutdown sequence you DO have to handle it
Both sides have to call shutdown on their socket
You need a way to notice the disconnect (it does not give you an error, or least it didnt for me)
Therefor I created my own class customSocket which inherits from Socket
public class customSocket : Socket
{
#region Properties
private readonly Timer _timer;
private const int _interval = 1000;
private bool Connected
{
get
{
bool part1 = Poll(1000, SelectMode.SelectRead);
bool part2 = (Available == 0);
if (part1 && part2)
return false;
else
return true;
}
}
public bool EventsEnabled
{
set
{
if (value)
{
_timer.Start();
}
else
_timer.Stop();
}
}
#endregion
#region Constructors
public customSocket(AddressFamily addressFamily, SocketType sockType, ProtocolType protocolType)
: base(addressFamily, sockType, protocolType)
{
_timer = new Timer { Interval = _interval };
_timer.Elapsed += TimerTick;
}
public customSocket(SocketInformation sockInfo)
: base(sockInfo)
{
_timer = new Timer { Interval = _interval };
_timer.Elapsed += TimerTick;
}
#endregion
#region Events
public event EventHandler<EventArgs> Socket_disconected;
public void Raise_Socket_disconnected()
{
EventHandler<EventArgs> handler = Socket_disconected;
if (handler != null)
{
handler(this,new EventArgs());
}
}
private void TimerTick(object sender, EventArgs e)
{
if (!Connected)
{
Raise_Socket_disconnected();
}
}
#endregion
}
This version of a socket has an Event for a disconnect.
Now if you create an instance of your socket class you have to connect the handler and set the EventsEnabled true.
This handler then calls the shutdown and your socket does not stay in FIN_WAIT_2

How to let only one thread to run a critical section while discarding the other threads without hang

I'm developing a windows service with .NET framework 4.0 and C#.
This service will open a socket to receive commands.
I have this socket listener class:
public class SocketListener
{
private System.Net.Sockets.TcpListener m_server;
public SQLServerSocketListener()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, 5445);
m_server = new System.Net.Sockets.TcpListener(ip);
}
public void Start()
{
m_server.Start();
m_server.BeginAcceptTcpClient(new AsyncCallback(Callback), m_server);
}
public void Stop()
{
if (m_server != null)
m_server.Stop();
}
private void Callback(IAsyncResult ar)
{
if (!(m_server.Server.IsBound) ||
(m_server.Server == null))
return;
TcpClient client;
try
{
client = m_server.EndAcceptTcpClient(ar);
}
catch (ObjectDisposedException)
{
//Listener canceled
return;
}
DataHandler dataHandler = new DataHandler(client);
ThreadPool.QueueUserWorkItem(dataHandler.HandleClient, client);
m_server.BeginAcceptTcpClient(new AsyncCallback(Callback), m_server);
}
}
And this class to process the commands received through the socket:
class DataHandler
{
private bool m_disposed = false;
private TcpClient m_controlClient;
private IPEndPoint m_remoteEndPoint;
private string m_clientIP;
private NetworkStream m_controlStream;
private StreamReader m_controlReader;
public DataHandler(TcpClient client)
{
m_controlClient = client;
}
public void HandleClient(object obj)
{
m_remoteEndPoint = (IPEndPoint)m_controlClient.Client.RemoteEndPoint;
m_clientIP = m_remoteEndPoint.Address.ToString();
m_controlStream = m_controlClient.GetStream();
m_controlReader = new StreamReader(m_controlStream, true);
string line;
try
{
while (((line = m_controlReader.ReadLine()) != null) ||
(m_controlClient == null) ||
(!m_controlClient.Connected))
{
CommandHandler.ProcessCommand(line);
}
}
catch (Exception ex)
{
Console.WriteLine("CodeServerService.DataHandler error: {0}", ex.Message);
}
finally
{
Dispose();
}
}
}
And, the CommandHandler:
class CommandHandler
{
public static void ProcessCommand(string command, string connStringINICIC, string connStringTRZIC, byte codeLevel)
{
switch (command)
{
case "GetNewCodes<EOF>":
CodesIncremental.GetNewCodes();
break;
}
}
}
And CodesIncremental:
public class CodesIncremental
{
public static bool GetNewCodes()
{
[ ... ]
}
}
My problem is that I can receive GetNewCodes<EOF> command before the first one finish. So, I need to don't let GetNewCodes<EOF>runs if there is another GetNewCodes<EOF> running.
How can I don't let run CodesIncremental.GetNewCodes(); if this code its running in another thread?
I need something to discard the commands received while CodesIncremental.GetNewCodes(); is running.
In pseudo code:
If CodesIncremental.GetNewCodes(); is running do nothing.
This version does not block. CompareExchange ensures atomicity, so only one thread will swap the value of the _running variable, the rest of threads will just return inmediately.
public class CodesIncremental
{
static Int32 _running = 0;
public static bool GetNewCodes()
{
if (Interlocked.CompareExchange(ref _running, 1, 0) == 1)
return false;
try
{
// Do stuff...
return true;
}
finally
{
_running = 0;
}
}
}
A difference than monitors or other synchronization methods, there is little contention on this method, and it is quite faster.
Maybe like this using AutoResetEvent:
public class CodesIncremental
{
private AutoResetEvent _event = new AutoResetEvent(true);
public static bool GetNewCodes()
{
if(!_event.WaitOne(0))
return true; //is running
try
{
/*
actions in case if isn't running
*/
}
finally
{
_event.Set();
}
return false;
}
}
EDIT: Update to address the modification of the question.
A simple way is to use the Monitor.TryEnter and Monitor.Exit
Just call the ExecuteGetNewCodeCommand for the processing of your "GetNewCode" command.
object _myLock = new object();
void ExecuteGetNewCodeCommand( ArgType args)
{
bool result = false;
try
{
result = Monitor.TryEnter(_myLock); // This method returns immediately
if( !result) // check if the lock is acquired.
return;
// Execute your command code here
}
finally
{
if(result) // release the lock.
Monitor.Exit(_myLock);
}
}
Old answer (before the modification of the question):
Think about using a queue and a Thread Pool.
Every time you receive a new Command (including "GetNewCode") insert it into a queue. In addition, you will have a Thread Pool that will read requests from the queue and execute them.
If you are using only one thread in the Thread pool, or a dedicated thread for this type of commands (where there are other threads for other requests/commands in the queue/queus), then only one "GetNewCode" request will be running at the same time.
This way you can control the number of threads your server will run. Thus, also the resources your server uses.
If you just synchronize (via locks or other mechanism) then there are a performance penalties. And maybe a denial of service, if you reached a thread limit. Let's say for somehow the execution of a request is taking too long (Maybe a deadlock in your code). If you will not use a Thread pool, and will execute the commands/requests on the same thread the client connected to your, then your sever may hang.
Though, If you will synchronize the threads inside the thread pool, then the server will not hang. Maybe it will be really slow to execute the requests, but it will still run and work.
There is a default .Net ThreadPool implementation at MSDN.
Add a lock to your CodesIncremental Class:
public class CodesIncremental
{
private object m_threadLock = new object();
public static bool GetNewCodes()
{
lock(m_threadLock)
{
[ ... ]
}
}
}
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
This way when your GetNewCodes method is called the first time the 'lock' statement will get an exclusive lock on the 'm_threadLock' object and only release it when the execution leaves the lock block, if any other thread calls the methods while the first thread is still inside the lock block it will not be able to get an exclusive lock and execution will suspend until it can.
Update:
Since you want to discard other calls try this:
public class CodesIncremental
{
private static object m_threadLock = new object();
private static bool m_running = false;
public static bool GetNewCodes()
{
lock(m_threadLock)
{
if(m_running)
{
return;
}
m_running = true;
}
try
{
[ ... ]
}
finally
{
m_running = false;
}
}
}
there might be better ways but this should do the trick.
Update 2: Hadn't seen the static

Instance members of singleton object or static members of class

I am writing a listener class which creates a single HttpListener on random
unused port and listens on it. I tried to make it singleton. However I am
finding it difficult to keep that singleton object null when listening
to random HTTP port fails 10 times.
(I have shown port number and HttpListener instance as members of singleton
instance. However there are many other members that I have not shown for
simplicity.) This is my code:
class Listener
{
private static Listener listener = null; //singleton instance
//member variables
private HttpListener httpListener = null;
private int port = -1;
static Listener()
{
listener = new Listener();
}
private Listener()
{
try
{
port = //randomly generate
httpListener = new HttpListener();
//start listening
}
catch(Exception ex)
{
//cant listen on randomly chosen port
listener = null;
httpListener = null;
port = -1;
return;
}
}
}
However inside catch(), listener = null sets listener to null
just for a while. When default constructor returns it returns a new
instance of Listener, thus listener inside static constructor always have
instance assigned to it. Thus instead of listener = null inside default
constructor it should be this = null which is invalid.
Thus I moved the whole code inside static constructor. But that forcesd me to
Either make instance members (port and httpListener) static or
or use listener.port , listener.httpListener everywhere
class Listener
{
private static Listener listener = null; //singleton instance
//member variables
private HttpListener httpListener = null;
private int port = -1;
static Listener()
{
listener = new Listener();
try
{
listener.port = //randomly generate
listener.httpListener = new HttpListener();
//start listening
}
catch(Exception ex)
{
//cant listen on randomly chosen port
listener = null;
return;
}
}
private Listener()
{
}
}
I dont understand
Q1 whether to make port & httpListener static? (This I feel somewhat against OOP principles) or
Q2 whether to keep them as instance members and use listener. everywhere? (This is problematic since there are many such members and methods in my actual code and I have to attach listener. everywhere)
Or I am thinking it all wrong and should have followed different approach?
The immediate problem is that on failure the instance constructor is setting the static member listener to null. However, control then returns to the static constructor which sets the static member listener to the object that was created in the instance constructor. Hence, the behaviour you're seeing.
I'd argue that your (instance) constructor is trying to do too much. I would move the 'start listening' logic into a separate method and call that from anywhere other than the instance constructor. That will make your error handling a little easier e.g.
class Listener
{
public static Listener listener = null; //singleton instance
//member variables
private HttpListener httpListener = null;
private int port = -1;
static Listener GetListener()
{
if (listener != null)
{
return listener;
}
try
{
listener = new Listener();
listener.StartListening();
return listener;
}
catch (Exception)
{
//cant listen on randomly chosen port
listener.Cleanup();
listener = null;
throw;
}
}
private Listener()
{
port = RandomlyGenerate();
httpListener = new HttpListener();
}
private void StartListening()
{
//start listening
}
private void Cleanup()
{
httpListener.Close();
httpListener = null;
port = -1;
}
}
As BartoszKP mentions in the comments, you would probably be better of with a factory pattern here.
If you are interested in having a common place for events you could place that event in the factory class, or implement a static event in the Listener class.
public class ListenerFactory {
public IListener CreateListener(URI uri, int port) {
Listener l = new Listener();
l.MessageReceived += OnMessageReceived;
// do whatever with l. loop until connection, or use l.Start() for instance
return l;
}
public static event EventHandler<MessageEventArgs> ListenerMessageReceived;
private static void OnMessageReceived(object sender, MessageEventArgs e) {
// trigger ListenerMessageReceived
}
}
public interface IListener {
event EventHandler<MessageEventArgs> MessageReceived;
void Send(byte[] data);
}
public class Listener : IListener {
// implement interface
}
Then you just call new ListenerFactory().Create(host, port); when you need a new Listener, and if you want to listen for all messages, you subscribe to ListenerFactory.MessageReceived for incoming messages.
Using this pattern, you can create several connections at once instead of relying on one class to handle all of them.
You should move the initialization code of httpListener to its own method in order to avoid recreating listener. By doing that, and adding a property for getting the listener instance, classes can use Listener.Instance.Start() to reconnect if the static constructor fails to connect.
public class Listener
{
private static Listener listener = null; //singleton instance
//member variables
private HttpListener httpListener = null;
private int port = -1;
static Listener()
{
listener = new Listener();
// start listener
try {
listener.Start();
}
catch { }
}
// Use this method in other classes to start listener if it fails
// in static constructor
public static Listener Instance { get { return listener; } }
private Listener()
{
}
public bool IsConnected {
get { return httpListener != null; }
}
public void Start()
{
if (IsConnected) { return; }
try
{
port = //randomly generate
httpListener = new HttpListener();
//start listening
}
catch(Exception ex)
{
//cant listen on randomly chosen port
httpListener = null;
port = -1;
return;
}
}
}

Categories

Resources