// MAIN PROCESS NKScriptMessageHandler void NKScriptMessageHandler.didReceiveScriptMessage(NKScriptMessage message) { var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKScriptMessage; msg.args = new[] { message.name, context.NKserialize(message.body) }; writeObject(syncPipeOut, msg); }
private void eventForwarderFromRenderer(string eventType, NKEvent nke) { var handshake = new NKRemotingMessage(); handshake.command = NKRemotingMessage.Command.NKEvent; var eventSerialized = NKData.jsonSerialize(nke); handshake.args = new string[] { eventType, eventSerialized }; writeObject(asyncPipe, handshake); }
void NKScriptContextRemotingProxy.NKevaluateJavaScript(string javaScriptString, string filename) { if (!asyncPipe.IsConnected) { return; } var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKevaluateJavaScript; msg.args = new[] { javaScriptString, filename }; writeObject(asyncPipe, msg); }
private void requestClientTeardown() { var handshake = new NKRemotingMessage(); handshake.command = NKRemotingMessage.Command.NKRemotingClose; handshake.args = new string[] { }; writeObject(syncPipeOut, handshake); try { asyncPipe.Close(); syncPipeIn.Close(); syncPipeOut.Close(); } catch { } }
private NKRemotingMessage readObject(Stream stream) { NKRemotingMessage obj = null; try { var len = _readLength(stream); if (len == 0) { return(null); } obj = _readObject(stream, len); } catch (Exception ex) { NKLogging.log("!Read Error" + ex.Message); } return(obj); }
private void writeObject(Stream stream, NKRemotingMessage obj) { lock (stream) { byte[] data; using (var memoryStream = new MemoryStream()) { _binaryFormatter.Serialize(memoryStream, obj); data = memoryStream.ToArray(); } try { _writeLength(stream, data.Length); _writeObject(stream, data); } catch (Exception ex) { Console.WriteLine("!Write Error" + ex.Message); } } }
// RENDERER NKScriptContextRemotingProxy Methods void NKScriptContextRemotingProxy.NKready() { var _channel = NKScriptChannel.getChannel(ns); context = _channel.context; _localHandlers[id] = _channel; _channel.singleInstance = true; NKEventEmitter.global.once("NKS.SingleInstanceComplete", (string e, string s) => { Task.Delay(500).ContinueWith((t) => { NKLogging.log("+[RENDERER] Window Closed"); this.cancelTokenSource.Cancel(); }); }); var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKRemotingReady; msg.args = new string[] { }; writeObject(asyncPipe, msg); NKEventEmitter.global.forward <NKEvent>(eventForwarderFromRenderer); }
object NKScriptMessageHandler.didReceiveScriptMessageSync(NKScriptMessage message) { var loger = context.NKserialize(message.body); var task = Task.Factory.StartNew(() => { var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKScriptMessageSync; msg.args = new[] { message.name, context.NKserialize(message.body) }; writeObject(syncPipeOut, msg); return(readObject(syncPipeIn)); } , cancelToken, TaskCreationOptions.None, TaskScheduler.Default); if (!task.Wait(10000, cancelToken) && !cancelToken.IsCancellationRequested) { NKLogging.log("!Renderer is not responsive " + loger); if (!process.HasExited) { process.Kill(); } return(null); } NKRemotingMessage nkr = task.Result; if (nkr == null) { return(null); } object result = null; if (nkr.args.Length > 0) { result = context.NKdeserialize(nkr.args[0]); } return(result); }
// RENDERER PROCESS PIPE EVENT LOOP private async Task _processClientMessages() { var message = await readObjectAsync(syncPipeIn); if (message == null) { NKLogging.log("!Renderer Received Empty Message"); cancelTokenSource.Cancel(); return; } if (message.command == NKRemotingMessage.Command.NKScriptMessageSync) { var name = message.args[0]; Dictionary<string, object> body = null; try { body = context.NKdeserialize(message.args[1]) as Dictionary<string, object>; } catch (Exception ex) { NKLogging.log("!Renderer Message Deserialization Error: " + ex.Message); } var nks = new NKScriptMessage(name, body); NKScriptMessageHandler handler = null; if (_localHandlers.ContainsKey(name)) handler = _localHandlers[name]; else { int target = Int32.Parse(body["$target"].ToString()); handler = NKScriptChannel.getNative(target); } if (handler != null) { var nkr = new NKRemotingMessage(); nkr.command = NKRemotingMessage.Command.NKScriptMessageSyncReply; try { var result = handler.didReceiveScriptMessageSync(nks); nkr.args = new string[] { context.NKserialize(result) }; } catch (Exception ex) { NKLogging.log("!Renderer Message Processing Error: " + ex.Message); NKLogging.log(ex.StackTrace); nkr.args = new string[] { }; } writeObject(syncPipeOut, nkr); } else { NKLogging.log("+Renderer Received Unknown Script Message Sync"); } } else if (message.command == NKRemotingMessage.Command.NKScriptMessage) { var name = message.args[0]; Dictionary<string, object> body = null; try { body = context.NKdeserialize(message.args[1]) as Dictionary<string, object>; } catch (Exception ex) { NKLogging.log("!Renderer Message Deserialization Error: " + ex.Message); } var nks = new NKScriptMessage(name, body); NKScriptMessageHandler handler = null; if (_localHandlers.ContainsKey(name)) handler = _localHandlers[name]; else { int target = Int32.Parse(body["$target"].ToString()); handler = NKScriptChannel.getNative(target); } if (handler != null) { handler.didReceiveScriptMessage(nks); } else { NKLogging.log("+Renderer Received Unknown Script Message " + message.args[1]); } } else if (message.command == NKRemotingMessage.Command.NKRemotingClose) { try { syncPipeIn.Close(); syncPipeOut.Close(); asyncPipe.Close(); } catch { } Environment.Exit(0); } else if (message.command == NKRemotingMessage.Command.NKEvent) { var eventType = message.args[0]; NKEvent eventObject = new NKEvent((IDictionary<string, object>)(NKData.jsonDeserialize(message.args[1]))); NKEventEmitter.global.emit<NKEvent>(eventType, eventObject, false); } if (!cancelToken.IsCancellationRequested) await _processClientMessages(); else return; }
// RENDERER PROCESS PIPE EVENT LOOP private async Task _processClientMessages() { var message = await readObjectAsync(syncPipeIn); if (message == null) { NKLogging.log("!Renderer Received Empty Message"); cancelTokenSource.Cancel(); return; } if (message.command == NKRemotingMessage.Command.NKScriptMessageSync) { var name = message.args[0]; Dictionary <string, object> body = null; try { body = context.NKdeserialize(message.args[1]) as Dictionary <string, object>; } catch (Exception ex) { NKLogging.log("!Renderer Message Deserialization Error: " + ex.Message); } var nks = new NKScriptMessage(name, body); NKScriptMessageHandler handler = null; if (_localHandlers.ContainsKey(name)) { handler = _localHandlers[name]; } else { int target = Int32.Parse(body["$target"].ToString()); handler = NKScriptChannel.getNative(target); } if (handler != null) { var nkr = new NKRemotingMessage(); nkr.command = NKRemotingMessage.Command.NKScriptMessageSyncReply; try { var result = handler.didReceiveScriptMessageSync(nks); nkr.args = new string[] { context.NKserialize(result) }; } catch (Exception ex) { NKLogging.log("!Renderer Message Processing Error: " + ex.Message); NKLogging.log(ex.StackTrace); nkr.args = new string[] { }; } writeObject(syncPipeOut, nkr); } else { NKLogging.log("+Renderer Received Unknown Script Message Sync"); } } else if (message.command == NKRemotingMessage.Command.NKScriptMessage) { var name = message.args[0]; Dictionary <string, object> body = null; try { body = context.NKdeserialize(message.args[1]) as Dictionary <string, object>; } catch (Exception ex) { NKLogging.log("!Renderer Message Deserialization Error: " + ex.Message); } var nks = new NKScriptMessage(name, body); NKScriptMessageHandler handler = null; if (_localHandlers.ContainsKey(name)) { handler = _localHandlers[name]; } else { int target = Int32.Parse(body["$target"].ToString()); handler = NKScriptChannel.getNative(target); } if (handler != null) { handler.didReceiveScriptMessage(nks); } else { NKLogging.log("+Renderer Received Unknown Script Message " + message.args[1]); } } else if (message.command == NKRemotingMessage.Command.NKRemotingClose) { try { syncPipeIn.Close(); syncPipeOut.Close(); asyncPipe.Close(); } catch { } Environment.Exit(0); } else if (message.command == NKRemotingMessage.Command.NKEvent) { var eventType = message.args[0]; NKEvent eventObject = new NKEvent((IDictionary <string, object>)(NKData.jsonDeserialize(message.args[1]))); NKEventEmitter.global.emit <NKEvent>(eventType, eventObject, false); } if (!cancelToken.IsCancellationRequested) { await _processClientMessages(); } else { return; } }
object NKScriptMessageHandler.didReceiveScriptMessageSync(NKScriptMessage message) { var loger = context.NKserialize(message.body); var task = Task.Factory.StartNew(() => { var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKScriptMessageSync; msg.args = new[] { message.name, context.NKserialize(message.body) }; writeObject(syncPipeOut, msg); return readObject(syncPipeIn); } , cancelToken, TaskCreationOptions.None, TaskScheduler.Default); if (!task.Wait(10000, cancelToken) && !cancelToken.IsCancellationRequested) { NKLogging.log("!Renderer is not responsive " + loger ); if (!process.HasExited) process.Kill(); return null; } NKRemotingMessage nkr = task.Result; if (nkr == null) return null; object result = null; if (nkr.args.Length>0) result = context.NKdeserialize(nkr.args[0]); return result; }
void NKScriptContextRemotingProxy.NKevaluateJavaScript(string javaScriptString, string filename) { if (!asyncPipe.IsConnected) return; var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKevaluateJavaScript; msg.args = new[] { javaScriptString, filename }; writeObject(asyncPipe, msg); }
// RENDERER NKScriptContextRemotingProxy Methods void NKScriptContextRemotingProxy.NKready() { var _channel = NKScriptChannel.getChannel(ns); context = _channel.context; _localHandlers[id] = _channel; _channel.singleInstance = true; NKEventEmitter.global.once("NKS.SingleInstanceComplete", (string e, string s) => { Task.Delay(500).ContinueWith((t) => { NKLogging.log("+[RENDERER] Window Closed"); this.cancelTokenSource.Cancel(); }); }); var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKRemotingReady; msg.args = new string[] { }; writeObject(asyncPipe, msg); NKEventEmitter.global.forward<NKEvent>(eventForwarderFromRenderer); }
//MAIN private NKRemotingProxy(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken) { this.context = context; this._localHandlers = null; this.ns = ns; this.cancelToken = cancelToken; var exe = System.Reflection.Assembly.GetEntryAssembly().Location; var path = System.IO.Path.GetDirectoryName(exe); ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo; startInfo.FileName = exe; startInfo.WorkingDirectory = path; startInfo.UseShellExecute = false; var syncPipeOut = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable); var syncPipeIn = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable); var pipeOutHandle = syncPipeOut.GetClientHandleAsString(); var pipeInHandle = syncPipeIn.GetClientHandleAsString(); this.syncPipeOut = syncPipeOut; this.syncPipeIn = syncPipeIn; startInfo.Arguments = "NKR=" + buildInitMessage(pipeOutHandle, pipeInHandle); this.id = id; process = Process.Start(startInfo); NKEventEmitter.global.emit <string>("NKS.ProcessAdded", id, false); process.EnableRaisingEvents = true; process.Exited += Process_Exited; var pipeName = Convert.ToBase64String(getUniqueKey()); var asyncPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough); this.asyncPipe = asyncPipe; NKScriptChannel.nativeFirstSequence -= 5; string nativeFirstSeq = NKScriptChannel.nativeFirstSequence.ToString(); var handshake = new NKRemotingMessage(); handshake.command = NKRemotingMessage.Command.NKRemotingHandshake; handshake.args = new string[] { pipeName, ns, id, nativeSeqMax.ToString() }; syncPipeOut.WriteByte(100); syncPipeOut.Flush(); syncPipeOut.WaitForPipeDrain(); syncPipeOut.DisposeLocalCopyOfClientHandle(); syncPipeIn.DisposeLocalCopyOfClientHandle(); writeObject(syncPipeOut, handshake); syncPipeOut.WaitForPipeDrain(); var handshakeReply = readObject(syncPipeIn); if (handshakeReply == null || handshakeReply.command != NKRemotingMessage.Command.NKRemotingHandshake) { Environment.Exit(911); } asyncPipe.WaitForConnection(); cancelToken.Register(requestClientTeardown); var nkready = readObject(asyncPipe); if (nkready == null || nkready.command != NKRemotingMessage.Command.NKRemotingReady) { Environment.Exit(910); } Task.Factory.StartNew((s) => _processServerMessages(asyncPipe), null, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default); NKEventEmitter.global.forward <NKEvent>(eventForwarderFromMain); }
//MAIN private NKRemotingProxy(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken) { this.context = context; this._localHandlers = null; this.ns = ns; this.cancelToken = cancelToken; var exe = System.Reflection.Assembly.GetEntryAssembly().Location; var path = System.IO.Path.GetDirectoryName(exe); ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo; startInfo.FileName = exe; startInfo.WorkingDirectory = path; startInfo.UseShellExecute = false; var syncPipeOut = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable); var syncPipeIn = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable); var pipeOutHandle = syncPipeOut.GetClientHandleAsString(); var pipeInHandle = syncPipeIn.GetClientHandleAsString(); this.syncPipeOut = syncPipeOut; this.syncPipeIn = syncPipeIn; startInfo.Arguments = "NKR=" + buildInitMessage(pipeOutHandle, pipeInHandle); this.id = id; process = Process.Start(startInfo); NKEventEmitter.global.emit<string>("NKS.ProcessAdded", id, false); process.EnableRaisingEvents = true; process.Exited += Process_Exited; var pipeName = Convert.ToBase64String(getUniqueKey()); var asyncPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough); this.asyncPipe = asyncPipe; NKScriptChannel.nativeFirstSequence -= 5; string nativeFirstSeq = NKScriptChannel.nativeFirstSequence.ToString(); var handshake = new NKRemotingMessage(); handshake.command = NKRemotingMessage.Command.NKRemotingHandshake; handshake.args = new string[] { pipeName, ns, id, nativeSeqMax.ToString() }; syncPipeOut.WriteByte(100); syncPipeOut.Flush(); syncPipeOut.WaitForPipeDrain(); syncPipeOut.DisposeLocalCopyOfClientHandle(); syncPipeIn.DisposeLocalCopyOfClientHandle(); writeObject(syncPipeOut, handshake); syncPipeOut.WaitForPipeDrain(); var handshakeReply = readObject(syncPipeIn); if (handshakeReply == null || handshakeReply.command != NKRemotingMessage.Command.NKRemotingHandshake) Environment.Exit(911); asyncPipe.WaitForConnection(); cancelToken.Register(requestClientTeardown); var nkready = readObject(asyncPipe); if (nkready == null || nkready.command != NKRemotingMessage.Command.NKRemotingReady) Environment.Exit(910); Task.Factory.StartNew((s)=> _processServerMessages(asyncPipe), null, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default); NKEventEmitter.global.forward<NKEvent>(eventForwarderFromMain); }