3 using Newtonsoft.Json.Linq;
\r
6 using System.Threading;
\r
7 using System.Net.Sockets;
\r
11 public class Stratum
\r
13 private Socket client;
\r
16 /// Constructor of Stratum interface class
\r
18 /// <param name="ipAddress">IPv4 address</param>
\r
19 /// <param name="port">Port number</param>
\r
20 public Stratum(string ipAddress, int port)
\r
22 // End point for the remote device
\r
23 IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipAddress), port);
\r
25 // Create TCP socket
\r
26 client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
\r
28 // Connect done event
\r
29 ManualResetEvent connectDone = new ManualResetEvent(false);
\r
31 Action<IAsyncResult> ConnectCallback = null;
\r
32 ConnectCallback = (IAsyncResult ar) =>
\r
34 // Retrieve socket from the state object
\r
35 Socket cli = (Socket)ar.AsyncState;
\r
37 // Complete the connection
\r
40 // Signal that connection has been established
\r
44 // Connect to the remote device
\r
45 client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
\r
48 connectDone.WaitOne();
\r
53 // Release the socket
\r
54 client.Shutdown(SocketShutdown.Both);
\r
58 private void Send(Socket client, String data)
\r
61 ManualResetEvent sendDone = new ManualResetEvent(false);
\r
63 Action<IAsyncResult> SendCallback = null;
\r
64 SendCallback = (IAsyncResult ar) =>
\r
66 // Retrieve the socket from the state object
\r
67 Socket cli = (Socket)ar.AsyncState;
\r
69 // Complete sending the data to the remote device
\r
70 int bytesSent = cli.EndSend(ar);
\r
72 // Signal that all bytes have been sent
\r
76 // Convert the string data to byte data using ASCII encoding.
\r
77 byte[] byteData = Encoding.ASCII.GetBytes(data);
\r
79 // Begin sending the data to the remote device.
\r
80 client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), client);
\r
87 /// Invoke remote method
\r
89 /// <typeparam name="T">Return type</typeparam>
\r
90 /// <param name="method">Method name</param>
\r
91 /// <param name="arg">Argument</param>
\r
92 /// <returns>StratumResponse object</returns>
\r
93 public StratumResponse<T> Invoke<T>(string method, object arg)
\r
95 var req = new StratumRequest()
\r
98 Params = new object[] { arg }
\r
100 return Invoke<T>(req);
\r
104 /// Invoke remote method
\r
106 /// <typeparam name="T">Return type</typeparam>
\r
107 /// <param name="method">Method name</param>
\r
108 /// <param name="args">Arguments array</param>
\r
109 /// <returns>StratumResponse object</returns>
\r
110 public StratumResponse<T> Invoke<T>(string method, object[] args)
\r
112 var req = new StratumRequest()
\r
117 return Invoke<T>(req);
\r
120 private StratumResponse<T> Invoke<T>(StratumRequest stratumReq)
\r
122 StratumResponse<T> rjson = null;
\r
124 // Serialize stratumReq into JSON string
\r
125 var reqJSON = Newtonsoft.Json.JsonConvert.SerializeObject(stratumReq) + '\n';
\r
127 // Send JSON data to the remote device.
\r
128 Send(client, reqJSON);
\r
130 // Create the reading state object.
\r
131 StratumReadState state = new StratumReadState(client);
\r
134 ManualResetEvent receiveDone = new ManualResetEvent(false);
\r
136 Action<IAsyncResult> ReceiveCallback = null;
\r
137 ReceiveCallback = (IAsyncResult ar) =>
\r
139 // Retrieve the state object and the client socket
\r
140 // from the asynchronous state object.
\r
141 StratumReadState st = (StratumReadState)ar.AsyncState;
\r
142 Socket ci = st.workSocket;
\r
144 // Read data from the remote device.
\r
145 int bytesRead = ci.EndReceive(ar);
\r
147 if (bytesRead <= 0)
\r
152 // There might be more data, so store the data received so far.
\r
153 st.sb.Append(Encoding.ASCII.GetString(st.buffer, 0, bytesRead));
\r
155 if (st.buffer[bytesRead - 1] != '\n')
\r
157 // No EOL at the end of buffer, going to get the rest of data
\r
158 ci.BeginReceive(st.buffer, 0, StratumReadState.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), st);
\r
162 string strResponse = st.sb.ToString();
\r
164 // Deserialize the response
\r
165 rjson = Newtonsoft.Json.JsonConvert.DeserializeObject<StratumResponse<T>>(strResponse);
\r
171 JObject jo = Newtonsoft.Json.JsonConvert.DeserializeObject(strResponse) as JObject;
\r
172 throw new Exception(jo["Error"].ToString());
\r
174 catch (Newtonsoft.Json.JsonSerializationException)
\r
176 throw new Exception("Inconsistent or empty response");
\r
180 // Signal that all bytes have been received.
\r
186 // Begin receiving the data from the remote device.
\r
187 client.BeginReceive(state.buffer, 0, StratumReadState.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
\r
188 receiveDone.WaitOne();
\r