SharpMining/SharpMining/StratumListener.cs

131 lines
3.0 KiB
C#

using System;
using System.Net;
using System.Collections.Generic;
using System.Threading;
using System.Net.Sockets;
using sharp.cryptonote;
using Newtonsoft.Json.Linq;
namespace SharpMining
{
public delegate void StratumConnectionAccepted(StratumListener listener, StratumConnection stratumConnection);
public class StratumListener : TcpListener
{
bool shouldExit;
List<StratumConnection> connections;
Thread thread;
Dictionary<CryptoNoteCoin, MiningPool> associatedPools;
public event StratumConnectionAccepted OnConnectionAccepted;
public StratumListener(IPEndPoint endpoint)
:base(endpoint)
{
this.initialize();
}
public StratumListener(IPAddress bind,int port)
:base(bind,port)
{
this.initialize();
}
public StratumListener(string bind, int port)
:base(IPAddress.Parse(bind),port)
{
this.initialize();
}
public StratumListener(JToken stratumConfig)
:base(IPAddress.Parse(stratumConfig["bind"].ToString()),stratumConfig["port"].ToObject<int>())
{
this.initialize();
}
private void initialize(){
this.associatedPools = new Dictionary<CryptoNoteCoin, MiningPool>();
this.connections = new List<StratumConnection>();
}
public new void Start(){
if (thread == null){
thread = new Thread(() => run());
thread.Start();
}
}
public new void Stop(){
Monitor.Enter(this);
shouldExit = true;
Monitor.Wait(this);
Monitor.Exit(this);
}
protected void ConnectionAccepted(StratumConnection connection){
if (OnConnectionAccepted != null){
OnConnectionAccepted(this,connection);
}
}
private void run(){
base.Start(5);
while (!ShouldExit){
StratumConnection connection = AcceptStratumConnection();
connection.OnConnectionClosed += (sender) => { removeConnection(connection); };
this.connections.Add(connection);
ConnectionAccepted(connection);
}
base.Stop();
Monitor.Enter(this);
this.thread = null;
foreach (StratumConnection c in this.connections){
c.Close();
}
Monitor.PulseAll(this);
Monitor.Exit(this);
}
public StratumConnection AcceptStratumConnection(){
return new StratumConnection(this,this.AcceptSocket());
}
private void removeConnection(StratumConnection connection){
this.connections.Remove(connection);
Console.WriteLine("StratumConnection lost: {0}",connection);
}
private bool ShouldExit { get { Monitor.Enter(this); bool se = this.shouldExit; Monitor.Exit(this); return se; } }
public StratumConnection[] Connections { get { return this.connections.ToArray(); } }
public MiningPool[] AssociatedPools {
get {
MiningPool[] pools = new MiningPool[this.associatedPools.Count];
this.associatedPools.Values.CopyTo(pools,0);
return pools;
}
}
public MiningPool getAssociatedPool(CryptoNoteCoin coin){
if (!this.associatedPools.ContainsKey(coin)){
return null;
}
return this.associatedPools[coin];
}
public void associatePool(MiningPool pool){
this.associatedPools[pool.Coin] = pool;
}
}
}