X-Git-Url: https://git.novaco.in/?p=StratumLibrary.git;a=blobdiff_plain;f=StratumLibrary%2FStratum.cs;h=9ce89358016111e915a3c4b71f844deb5e327599;hp=20b05c4d3b2f68749b8adc18bdbd0fecd720ff1f;hb=81321f81c932ab7af82b75aa8d71cda76094cf5e;hpb=d2d772d07d02da4748b7e9d222a33f8e7423a83d diff --git a/StratumLibrary/Stratum.cs b/StratumLibrary/Stratum.cs index 20b05c4..9ce8935 100644 --- a/StratumLibrary/Stratum.cs +++ b/StratumLibrary/Stratum.cs @@ -2,6 +2,7 @@ using System.Net; using System.Threading; using System.Net.Sockets; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Text; @@ -9,9 +10,11 @@ using System.Collections.Generic; namespace Stratum { - public class Stratum + public abstract class Stratum { private Socket client; + + object responsesLock = new object(); private Dictionary responses = new Dictionary(); ManualResetEvent gotResponse = new ManualResetEvent(false); @@ -94,6 +97,22 @@ namespace Stratum /// /// Return type /// Method name + /// StratumResponse object + public StratumResponse Invoke(string method) + { + var req = new StratumRequest() + { + Method = method, + Params = new object[] { } + }; + return Invoke(req); + } + + /// + /// Invoke remote method + /// + /// Return type + /// Method name /// Argument /// StratumResponse object public StratumResponse Invoke(string method, object arg) @@ -126,8 +145,7 @@ namespace Stratum private StratumResponse Invoke(StratumRequest stratumReq) { // Serialize stratumReq into JSON string - var reqJSON = Newtonsoft.Json.JsonConvert.SerializeObject(stratumReq) + '\n'; - var reqId = (string) stratumReq.Id; + var reqJSON = JsonConvert.SerializeObject(stratumReq) + '\n'; // Send JSON data to the remote device. Send(client, reqJSON); @@ -135,22 +153,28 @@ namespace Stratum // Wait for response gotResponse.WaitOne(); - // Deserialize the response - string strResponse = responses[reqId]; - StratumResponse responseObj = Newtonsoft.Json.JsonConvert.DeserializeObject>(strResponse); - responses.Remove(reqId); + var strResponse = string.Empty; + lock (responsesLock) + { + // Deserialize the response + strResponse = responses[stratumReq.Id]; + responses.Remove(stratumReq.Id); + } + + // Deserialize response into new instance of StratumResponse + StratumResponse responseObj = JsonConvert.DeserializeObject>(strResponse); // Reset the state gotResponse.Reset(); - if (object.ReferenceEquals(null, responseObj)) + if (responseObj == null) { try { - JObject jo = Newtonsoft.Json.JsonConvert.DeserializeObject(strResponse) as JObject; - throw new Exception(jo["Error"].ToString()); + JObject jResponseObj = JsonConvert.DeserializeObject(strResponse) as JObject; + throw new Exception(jResponseObj["Error"].ToString()); } - catch (Newtonsoft.Json.JsonSerializationException) + catch (JsonSerializationException) { throw new Exception("Inconsistent or empty response"); } @@ -185,27 +209,32 @@ namespace Stratum if (arStatus.buffer[bytesRead - 1] == '\n') { - string strMessage = arStatus.sb.ToString(); + var strMessage = arStatus.sb.ToString(); arStatus.sb.Clear(); try { - JObject jo = Newtonsoft.Json.JsonConvert.DeserializeObject(strMessage) as JObject; - string requestId = (string)jo["id"]; + JObject jResponse = JsonConvert.DeserializeObject(strMessage) as JObject; + var reqId = (string)jResponse["id"]; - if (!String.IsNullOrEmpty(requestId)) + if (!String.IsNullOrEmpty(reqId)) { - responses.Add(requestId, strMessage); + lock (responsesLock) + { + responses.Add(reqId, strMessage); + } gotResponse.Set(); } else { - // TODO: notifications handling - Console.WriteLine("Notification: {0}", strMessage); + StratumNotification jNotification = JsonConvert.DeserializeObject(strMessage); + + var NotifyProcessThread = new Thread(() => NotificationHandler(jNotification.Method, jNotification.Params)); + NotifyProcessThread.Start(); } } - catch (Newtonsoft.Json.JsonSerializationException e) + catch (JsonSerializationException e) { // TODO: handle parse error } @@ -217,6 +246,13 @@ namespace Stratum client.BeginReceive(state.buffer, 0, StratumReadState.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } + + /// + /// Notifications stub which is run in a separate thread. You need to override this method in the derived class. + /// + /// Method name + /// Array of values + public abstract void NotificationHandler (string NotificationMethod, JArray NotificationData); } } \ No newline at end of file