static private void Process(object parameter) { object[] tmp = parameter as object[]; GXServer server = tmp[0] as GXServer; HttpListenerContext context = tmp[1] as HttpListenerContext; IPrincipal user = tmp[2] as IPrincipal; try { ProcessRequest(server, context, user); } catch (HttpListenerException) { //Client has close connection. This is ok. } catch (Exception ex) { if (server.onError != null) { server.onError(server, new ErrorEventArgs(ex)); } context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; GXErrorWrapper err = new GXErrorWrapper(ex); using (TextWriter writer = new StreamWriter(context.Response.OutputStream, Encoding.ASCII)) { GXJsonParser parser = new GXJsonParser(); string data = parser.Serialize(err); context.Response.ContentLength64 = data.Length; writer.Write(data); } } }
/// <summary> /// Publish message. /// </summary> /// <param name="msg"></param> private void PublishMessage(GXMessage msg) { GXJsonParser parser = new GXJsonParser(); string str = parser.Serialize(msg); MqttApplicationMessage message = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message).Wait(); }
/// <summary> /// Parse to JSON and send to the server. /// </summary> /// <typeparam name="T">JSON message type.</typeparam> /// <param name="method">Sent JSON object as a string.</param> /// <param name="request">Request to send.</param> /// <param name="data">Async request.</param> /// <returns>Http request that is sent to the server.</returns> private HttpWebRequest Send <T>(string method, object request, GXAsyncData <T> data) { CancelOperation = false; string cmd = null; bool content = method == "POST" || method == "PUT"; //Serialize to string because we want to know length. using (TextWriter writer = new StringWriter()) { Parser.Serialize(request, writer, true, !content, false, false); cmd = writer.ToString(); } HttpWebRequest req; if (content)//If POST or PUT. { req = WebRequest.Create(Address + request.GetType().Name) as HttpWebRequest; } else //If GET or DELETE. { req = WebRequest.Create(Address + request.GetType().Name + "?" + cmd) as HttpWebRequest; } if (Timeout.TotalMilliseconds != 0) { req.ReadWriteTimeout = req.Timeout = (int)this.Timeout.TotalMilliseconds; } req.ContentType = "application/json"; req.Accept = "application/json"; req.Method = method; if (trace != null) { trace(this, new TraceEventArgs(TraceTypes.Sent, content ? cmd : null, req.Address.ToString())); } //Add basic authentication if it is used. if (!string.IsNullOrEmpty(UserName)) { req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(UserName + ":" + Password))); } if (content) { req.ContentLength = cmd.Length; //If data is send as async. if (data != null) { data.Data = cmd; data.Request = req; req.BeginGetRequestStream(delegate(IAsyncResult result) { lock (asyncOperations) { asyncOperations.Add(result.AsyncWaitHandle); } GXAsyncData <T> tmp = (GXAsyncData <T>)result.AsyncState; try { using (Stream stream = tmp.Request.EndGetRequestStream(result)) { using (var streamWriter = new StreamWriter(stream)) { streamWriter.Write(tmp.Data); streamWriter.Flush(); } } tmp.Request.BeginGetResponse(AsyncReponse <T>, tmp); } catch (Exception ex) { tmp.OnError(this, ex); } finally { lock (asyncOperations) { asyncOperations.Remove(result.AsyncWaitHandle); } } }, data); } else { using (var streamWriter = new StreamWriter(req.GetRequestStream())) { streamWriter.Write(cmd); streamWriter.Flush(); } } } else if (data != null) { req.BeginGetResponse(delegate(IAsyncResult result) { lock (asyncOperations) { asyncOperations.Add(result.AsyncWaitHandle); } GXAsyncData <T> tmp = (GXAsyncData <T>)result.AsyncState; try { T result2 = GetResponse <T>(req); if (data.OnDone != null) { data.OnDone(this, result2); } } catch (Exception ex) { tmp.OnError(this, ex); } finally { lock (asyncOperations) { asyncOperations.Remove(result.AsyncWaitHandle); } } }, data); } return(req); }
public void ProcessRequest(HttpContext context) { InvokeHandler handler; if (context.Request.ContentType.Contains("json")) { switch (context.Request.HttpMethod) { case "GET": handler = RestMethodInfo.Get; break; case "POST": handler = RestMethodInfo.Post; break; case "PUT": handler = RestMethodInfo.Put; break; case "DELETE": handler = RestMethodInfo.Delete; break; default: handler = null; break; } if (handler == null) { throw new HttpException(405, string.Format("Method '{0}' not allowed for {1}", context.Request.HttpMethod, RestMethodInfo.RequestType.Name)); } object req; if (context.Request.HttpMethod == "POST") { req = Parser.Deserialize(context.Request.InputStream, RestMethodInfo.RequestType); } else { string data = "{" + context.Request.QueryString.ToString() + "}"; req = Parser.Deserialize(data, RestMethodInfo.RequestType); } //Get Rest class from cache. GXRestService target = RestMap[RestMethodInfo.RestClassType] as GXRestService; if (target == null) { target = GXJsonParser.CreateInstance(RestMethodInfo.RestClassType) as GXRestService; RestMap[RestMethodInfo.RestClassType] = target; } //Update user and DB info. //If proxy is used. string add = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString(); if (add == null) { add = context.Request.UserHostAddress; } target.Host = Host; target.User = context.User; target.Db = Connection; object tmp = handler(target, req); string reply = Parser.Serialize(tmp); context.Response.Write(reply); context.Response.ContentType = "json"; } }
void ApplyChanges(GXDeviceProfile dp) { if (Device) { Arguments.Target = GXDevice.Create(dp.Protocol, dp.Name, ""); } else { Arguments.Target = dp; } try { GXJsonParser parser = new GXJsonParser(); GXDeviceProfileFormSettings settings = new GXDeviceProfileFormSettings(); settings.Custom = CustomCB.Checked; settings.Download = DownloadCB.Checked; settings.SearchText = SearchTB.Text; settings.Earlier = ShowEarlierVersionsCB.Checked; Arguments.Settings = parser.Serialize(settings); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } if (Arguments.OnSelect != null) { if (Arguments.UseThread) { DialogResult = DialogResult.None; Work = new GXAsyncWork(this, OnAsyncStateChange, OnSelect, null, "Selecting", null); Work.Start(); return; } else { Arguments.OnSelect(Arguments.Target, Arguments); } } DialogResult = DialogResult.OK; Close(); }
/// <summary> /// Listen clients as long as server is up and running. /// </summary> /// <param name="parameter"></param> void ListenThread(object parameter) { IPrincipal user; HttpListenerContext c = null; GXServer tmp = parameter as GXServer; HttpListener Listener = tmp.Listener; while (Listener.IsListening) { bool accept = false; string username, password; AutoResetEvent h = new AutoResetEvent(false); IAsyncResult result = Listener.BeginGetContext(delegate(IAsyncResult ListenerCallback) { HttpListener listener = (HttpListener)ListenerCallback.AsyncState; //If server is not closed. if (listener.IsListening) { bool html = false; try { c = listener.EndGetContext(ListenerCallback); } catch (Exception ex) { if (onError != null) { onError(this, new ErrorEventArgs(ex)); } h.Set(); return; } if (c.Request.HttpMethod == "GET" && c.Request.AcceptTypes != null) { foreach (var it in c.Request.AcceptTypes) { if (it == "text/html") { Thread thread = new Thread(new ParameterizedThreadStart(ShowServices)); thread.Start(new object[] { tmp, c }); html = true; accept = true; break; } if (it.Contains("image")) { html = true; accept = true; break; } } } if (!html) { GXWebServiceModule.TryAuthenticate(tmp.MessageMap, c.Request, out username, out password); //Anonymous access is allowed. if (username == null && password == null) { accept = true; user = null; } else { user = TryAuthenticate(username, password); accept = user != null; } if (accept) { Thread thread = new Thread(new ParameterizedThreadStart(Process)); thread.Start(new object[] { tmp, c, user }); } else { c.Response.StatusCode = 401; c.Response.StatusDescription = "Access Denied"; c.Response.AddHeader("WWW-Authenticate", "Basic Realm"); GXErrorWrapper err = new GXErrorWrapper(new HttpException(401, "Access Denied")); using (TextWriter writer = new StreamWriter(c.Response.OutputStream, Encoding.ASCII)) { GXJsonParser parser = new GXJsonParser(); string data = parser.Serialize(err); c.Response.ContentLength64 = data.Length; writer.Write(data); } c.Response.Close(); } } h.Set(); } }, Listener); EventWaitHandle.WaitAny(new EventWaitHandle[] { h, Closing }); if (!accept || !Listener.IsListening) { result.AsyncWaitHandle.WaitOne(1000); Closed.Set(); break; } } }
/// <summary> /// Parse to JSON and send to the server. /// </summary> /// <typeparam name="T">JSON message type.</typeparam> /// <param name="route">Additional route.</param> /// <param name="method">Sent JSON object as a string.</param> /// <param name="request">Request to send.</param> /// <param name="data">Async request.</param> /// <returns>Http request that is sent to the server.</returns> private HttpWebRequest Send <T>(string route, string method, object request, GXAsyncData <T> data) { CancelOperation = false; string cmd = null; bool content = method == "POST" || method == "PUT"; //Serialize to string because we want to know length. using (TextWriter writer = new StringWriter()) { Parser.Serialize(request, writer, true, !content, false, false); cmd = writer.ToString(); } if (string.IsNullOrEmpty(route)) { route = request.GetType().Name; } if (route[0] != '/' && Address[Address.Length - 1] != '/') { route = "/" + route; } HttpWebRequest req; if (content)//If POST or PUT. { req = WebRequest.Create(Address + route) as HttpWebRequest; } else //If GET or DELETE. { req = WebRequest.Create(Address + route + "?" + cmd) as HttpWebRequest; } #if !NET35 if (Date != DateTime.MinValue && Date != DateTime.MaxValue) { req.Date = Date.ToUniversalTime(); } #endif //!NET35 req.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.BypassCache); req.Headers.Add("Cache-Control", "no-cache"); if (Timeout.TotalMilliseconds != 0) { req.ReadWriteTimeout = req.Timeout = (int)this.Timeout.TotalMilliseconds; } req.ContentType = "application/json"; req.Accept = "application/json"; req.Method = method; if (trace != null) { trace(this, new TraceEventArgs(TraceTypes.Sent, content ? cmd : null, req.Address.ToString())); } //Add basic authentication if it is used. if (!string.IsNullOrEmpty(UserName)) { req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(UserName + ":" + Password))); } //Data must serialize because data might be non-ASCII. byte[] d; using (MemoryStream ms = new MemoryStream()) { using (var sw = new StreamWriter(ms)) { sw.Write(cmd); sw.Flush(); d = new byte[ms.Position]; ms.Position = 0; ms.Read(d, 0, d.Length); } } if (content) { req.ContentLength = d.Length; //If data is send as async. if (data != null) { data.Data = d; data.Request = req; req.BeginGetRequestStream(delegate(IAsyncResult result) { lock (asyncOperations) { asyncOperations.Add(result.AsyncWaitHandle); } GXAsyncData <T> tmp = (GXAsyncData <T>)result.AsyncState; try { using (Stream stream = tmp.Request.EndGetRequestStream(result)) { using (var streamWriter = new StreamWriter(stream)) { streamWriter.Write(tmp.Data); streamWriter.Flush(); } } tmp.Request.BeginGetResponse(AsyncReponse <T>, tmp); } catch (Exception ex) { tmp.OnError(this, ex); } finally { lock (asyncOperations) { asyncOperations.Remove(result.AsyncWaitHandle); } } }, data); } else { using (BufferedStream bs = new BufferedStream(req.GetRequestStream())) { bs.Write(d, 0, d.Length); bs.Flush(); } } } else if (data != null) { data.Data = d; req.BeginGetResponse(delegate(IAsyncResult result) { lock (asyncOperations) { asyncOperations.Add(result.AsyncWaitHandle); } GXAsyncData <T> tmp = (GXAsyncData <T>)result.AsyncState; try { T result2 = GetResponse <T>(req); if (data.OnDone != null) { data.OnDone(this, result2); } } catch (Exception ex) { tmp.OnError(this, ex); } finally { lock (asyncOperations) { asyncOperations.Remove(result.AsyncWaitHandle); } } }, data); } return(req); }
public static void Start(TraceLevel trace, string server, int port, Connection connection) { // Create a new MQTT client. var mqttClient = factory.CreateMqttClient(); int pos = 1; foreach (var it in connection.Connections) { if (it.Type == "Net") { it.Target = new GXNet() { Settings = it.Settings }; } else if (it.Type == "Serial") { it.Target = new GXSerial() { Settings = it.Settings }; } else { throw new Exception("Unknown media type." + it.Type); } if (string.IsNullOrEmpty(it.Name)) { it.Name = connection.Name + "/" + pos.ToString(); ++pos; } else { it.Name = connection.Name + "/" + it.Name; } it.Target.OnReceived += (s, e) => { string tmp = GXCommon.ToHex((byte[])e.Data, true); if (trace == TraceLevel.Verbose) { Console.WriteLine("Received: " + tmp); } foreach (var it2 in connection.Connections) { if (it2.Target == s) { GXMessage msg = new GXMessage() { id = it2.Message.id, type = (int)MesssageType.Receive, sender = it2.Name, frame = tmp }; GXJsonParser parser = new GXJsonParser(); string str = parser.Serialize(msg); var message = new MqttApplicationMessageBuilder() .WithTopic(it2.Message.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); break; } } }; } ShowInformation(connection); var options = new MqttClientOptionsBuilder() .WithTcpServer(server, port) .WithClientId(connection.Name) .Build(); mqttClient.UseApplicationMessageReceivedHandler(t => { string str = ASCIIEncoding.ASCII.GetString(t.ApplicationMessage.Payload); GXJsonParser parser = new GXJsonParser(); GXMessage msg = parser.Deserialize <GXMessage>(str); if (trace == TraceLevel.Verbose) { Console.WriteLine("---Received message"); Console.WriteLine($"+ Topic = {t.ApplicationMessage.Topic}"); Console.WriteLine($"+ Payload = {msg.frame}"); Console.WriteLine($"+ QoS = {t.ApplicationMessage.QualityOfServiceLevel}"); Console.WriteLine($"+ Retain = {t.ApplicationMessage.Retain}"); } GXMessage msg2; MqttApplicationMessage message; foreach (var it in connection.Connections) { if (it.Name == t.ApplicationMessage.Topic) { it.Message = msg; try { switch ((MesssageType)msg.type) { case MesssageType.Open: it.Target.Open(); try { //Move to mode E if optical head is used. if (it.Target is GXSerial && it.UseOpticalHead) { InitializeIEC(trace, it); } if (it.Target is IGXMedia2) { ((IGXMedia2)it.Target).ReceiveDelay = 500; } //Mark EOP so reading is faster. // it.Target.Eop = (byte)0x7e; } catch (Exception ex) { it.Target.Close(); throw ex; } msg2 = new GXMessage() { id = msg.id, type = (int)MesssageType.Open, sender = it.Name }; str = parser.Serialize(msg2); message = new MqttApplicationMessageBuilder() .WithTopic(msg.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); break; case MesssageType.Send: it.Target.Send(GXCommon.HexToBytes(msg.frame), null); break; case MesssageType.Close: it.Target.Close(); msg2 = new GXMessage() { id = msg.id, type = (int)MesssageType.Close, sender = it.Name }; str = parser.Serialize(msg2); message = new MqttApplicationMessageBuilder() .WithTopic(msg.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); break; } } catch (Exception ex) { msg2 = new GXMessage() { id = msg.id, type = (int)MesssageType.Exception, sender = it.Name, exception = ex.Message }; str = parser.Serialize(msg2); message = new MqttApplicationMessageBuilder() .WithTopic(msg.sender) .WithPayload(str) .WithExactlyOnceQoS() .Build(); mqttClient.PublishAsync(message); } break; } } }); mqttClient.UseConnectedHandler(t => { if (trace > TraceLevel.Warning) { Console.WriteLine("--- Connected with the server. " + t.AuthenticateResult.IsSessionPresent); } // Subscribe to a topic List <TopicFilter> topics = new List <TopicFilter>(); foreach (Media it in connection.Connections) { topics.Add(new TopicFilterBuilder().WithTopic(it.Name).Build()); } mqttClient.SubscribeAsync(topics.ToArray()); if (trace > TraceLevel.Warning) { Console.WriteLine("--- Subscribed. "); } }); mqttClient.UseDisconnectedHandler(t => { Console.WriteLine("--- Disconnected from the server. " + t.Exception); //Try to re-connect. while (true) { try { foreach (var it in connection.Connections) { it.Target.Close(); } Console.WriteLine("--- Try to reconnect to the server."); mqttClient.ConnectAsync(options).Wait(10000); Console.WriteLine("--- Connected with the server. "); break; } catch (Exception ex) { Console.WriteLine("--- Failed to reconnect to the server. " + ex.Message); } } }); mqttClient.ConnectAsync(options).Wait(); }
/// <summary> /// Parse to JSON and send to the server. /// </summary> /// <typeparam name="T">JSON message type.</typeparam> /// <param name="method">Sent JSON object as a string.</param> /// <param name="request">Request to send.</param> /// <param name="data">Async request.</param> /// <returns>Http request that is sent to the server.</returns> private HttpWebRequest Send <T>(string method, object request, GXAsyncData <T> data) { CancelOperation = false; string cmd = null; bool content = method == "POST" || method == "PUT"; //Serialize to string because we want to know length. using (TextWriter writer = new StringWriter()) { Parser.Serialize(request, writer, true, !content, false, false); cmd = writer.ToString(); } HttpWebRequest req; if (content)//If POST or PUT. { req = WebRequest.Create(Address + "json/reply/" + request.GetType().Name) as HttpWebRequest; } else //If GET or DELETE. { req = WebRequest.Create(Address + "json/reply/" + request.GetType().Name + "?" + cmd) as HttpWebRequest; } if (this.Timeout.TotalMilliseconds != 0) { req.Timeout = (int)this.Timeout.TotalMilliseconds; } req.ContentType = "application/json; charset=utf-8"; req.Accept = "text/json"; req.Method = method; //Add basic authentication if it is used. if (!string.IsNullOrEmpty(UserName)) { req.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(UserName + ":" + Password))); } if (content) { req.ContentLength = cmd.Length; if (data != null) { System.Threading.AutoResetEvent sent = new System.Threading.AutoResetEvent(false); data.Data = cmd; data.Request = req; //req.BeginGetRequestStream(SendAsync<T>, data); req.BeginGetRequestStream(delegate(IAsyncResult result) { GXAsyncData <T> tmp = (GXAsyncData <T>)result.AsyncState; using (Stream stream = tmp.Request.EndGetRequestStream(result)) { using (var streamWriter = new StreamWriter(stream)) { streamWriter.Write(tmp.Data); streamWriter.Flush(); } } sent.Set(); tmp.Request.BeginGetResponse(AsyncReponse <T>, tmp); }, data); sent.WaitOne(); } else { using (var streamWriter = new StreamWriter(req.GetRequestStream())) { streamWriter.Write(cmd); streamWriter.Flush(); } } } return(req); }