public virtual object didReceiveScriptMessageSync(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) { return(false); } // thread static NKScriptValue._currentContext = this.context; object result; var body = message.body as Dictionary <string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Int32.Parse(body["$target"].ToString()); if (_instances.ContainsKey(target)) { var obj = _instances[target]; if (opcode == "-") { if (target == 0) { // Dispose plugin this.unbind(); result = true; } else if (_instances.ContainsKey(target)) { obj.setNKScriptValue(null); result = true; } else { NKLogging.log(String.Format("!Invalid instance id: {0}", target)); result = false; } } else if (typeInfo.ContainsProperty(opcode)) { // Update property obj.updateNativeProperty(opcode, body["$operand"] as object); result = true; } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method result = obj.invokeNativeMethodSync(opcode, body["$operand"] as object[]); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); result = false; } } else if (opcode == "+") { // Create instance var args = body["$operand"] as object[]; var nsInstance = String.Format("{0}[{1}]", this.ns, target); _instances[target] = new NKScriptValueNative(nsInstance, this, target, args, true); result = true; } else { // else Unknown opcode var obj = _principal.plugin as NKScriptMessageHandler; if (obj != null) { result = obj.didReceiveScriptMessageSync(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); result = false; } } } else { // null body result = false; } //thread static NKScriptValue._currentContext = null; return(result); }
// HOST-MAIN PROCESS public static NKScriptMessageHandler createClient(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken) { var proxy = new NKRemotingProxy(ns, id, nativeSeqMax, message, context, cancelToken); var _ = ((NKScriptMessageHandler)proxy).didReceiveScriptMessageSync(message); return proxy; }
public object didReceiveScriptMessageSync(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) return false; // thread static NKScriptChannel._currentContext = this.context; object result; var body = message.body as Dictionary<string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Convert.ToInt32(body["$target"] as String); if (instances.ContainsKey(target)) { var obj = instances[target]; if (opcode == "-") { if (target == 0) { // Dispose plugin this.unbind(); result = true; } else if (instances.ContainsKey(target)) { obj.setNKScriptValue(null); result = true; } else { NKLogging.log(String.Format("!Invalid instance id: {0}", target)); result = false; } } else if (typeInfo.ContainsProperty(opcode)) { // Update property obj.updateNativeProperty(opcode, body["$operand"] as object); result = true; } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method result = obj.invokeNativeMethodSync(opcode, body["$operand"] as object[]); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); result = false; } } else if (opcode == "+") { // Create instance var args = body["$operand"] as Array; var ns = String.Format("{0}[{1}]", principal.ns, target); instances[target] = new NKScriptValueNative(ns, this, args); result = true; } else { // else Unknown opcode var obj = principal.plugin as NKScriptMessageHandler; if (obj != null) { result = obj.didReceiveScriptMessageSync(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); result = false; } } } else { // null body result = false; } //thread static NKScriptChannel._currentContext = null; return result; }
// 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); }
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; }
//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); }
// 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; }
public override void didReceiveScriptMessage(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) return; var body = message.body as Dictionary<string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Int32.Parse(body["$target"].ToString()); NKScriptMessageHandler proxy = null; if (_proxies.ContainsKey(target)) { proxy = _proxies[target]; } else if (target > 1500) { var targetFloor = target - (target % NKRANGEPERPROCESS); if (_proxiesNatives.ContainsKey(targetFloor)) proxy = _proxiesNatives[targetFloor]; } if (proxy != null) { if (opcode == "-") { if (target == 0) { // TRANSFER TO REMOTE, WITH SYNC var _ = proxy.didReceiveScriptMessageSync(message); this.unbind(); } else { // TRANSFER TO REMOTE, WITH SYNC var _ = proxy.didReceiveScriptMessageSync(message); // UNBIND PROXY _cancelTokens[target].Cancel(); } } else if (typeInfo.ContainsProperty(opcode)) { // ALSO TRANSFER TO REMOTE proxy.didReceiveScriptMessage(message); } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method // TRANSFER TO REMOTE ONLY proxy.didReceiveScriptMessage(message); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); } } else if (opcode == "+") { throw new NotImplementedException("+ opcode must be called using synchronous messages"); } else { // else Unknown opcode var obj = _principal.plugin as NKScriptMessageHandler; if (obj != null) { obj.didReceiveScriptMessage(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); } } } else { // null body, ignore } }
public override object didReceiveScriptMessageSync(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) return false; // thread static NKScriptValue._currentContext = this.context; object result; var body = message.body as Dictionary<string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Int32.Parse(body["$target"].ToString()); NKScriptMessageHandler proxy = null; if (_proxies.ContainsKey(target)) { proxy = _proxies[target]; } else if (target > 1500) { var targetFloor = target - (target % 10); if (_proxiesNatives.ContainsKey(targetFloor)) proxy = _proxiesNatives[targetFloor]; } if (proxy != null) { if (opcode == "-") { if (target == 0) { // TRANSFER TO REMOTE var _ = proxy.didReceiveScriptMessageSync(message); this.unbind(); result = true; } else { // TRANSFER TO REMOTE var _ = proxy.didReceiveScriptMessageSync(message); // UNBIND PROXY _cancelTokens[target].Cancel(); result = true; } } else if (typeInfo.ContainsProperty(opcode)) { // TRANSFER TO REMOTE proxy.didReceiveScriptMessageSync(message); result = true; } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method via REMOTE proxy result = proxy.didReceiveScriptMessageSync(message); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); result = false; } } else if (opcode == "+") { _instances[target] = null; int maxNativeFirst = NKScriptChannel.nativeFirstSequence - (NKScriptChannel.nativeFirstSequence % NKRANGEPERPROCESS) - 1; int minNativeFirst = (maxNativeFirst - NKRANGEPERPROCESS) + 1; NKScriptChannel.nativeFirstSequence = minNativeFirst - 1; var cancelTokenSource = new CancellationTokenSource(); _cancelTokens[target] = cancelTokenSource; proxy = NKRemoting.NKRemotingProxy.createClient(ns, id, maxNativeFirst, message, context, cancelTokenSource.Token); _proxies[target] = proxy; _proxiesNatives[minNativeFirst] = proxy; result = true; } else { // else Unknown opcode var obj = _principal.plugin as NKScriptMessageHandler; if (obj != null) { result = obj.didReceiveScriptMessageSync(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); result = false; } } } else { // null body result = false; } //thread static NKScriptValue._currentContext = null; return result; }
public void didReceiveScriptMessage(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) { return; } // thread static NKScriptChannel._currentContext = this.context; var body = message.body as Dictionary <string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Convert.ToInt32(body["$target"] as String); if (instances.ContainsKey(target)) { var obj = instances[target]; if (opcode == "-") { if (target == 0) { // Dispose plugin this.unbind(); } else if (instances.ContainsKey(target)) { obj.setNKScriptValue(null); } else { NKLogging.log(String.Format("!Invalid instance id: {0}", target)); } } else if (typeInfo.ContainsProperty(opcode)) { // Update property obj.updateNativeProperty(opcode, body["$operand"] as object); } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method obj.invokeNativeMethod(opcode, body["$operand"] as object[]); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); } } else if (opcode == "+") { // Create instance var args = body["$operand"] as Array; var ns = String.Format("{0}[{1}]", principal.ns, target); instances[target] = new NKScriptValueNative(ns, this, args); } else { // else Unknown opcode var obj = principal.plugin as NKScriptMessageHandler; if (obj != null) { obj.didReceiveScriptMessage(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); } } } else { // null body, ignore } //thread static NKScriptChannel._currentContext = null; }
public override void didReceiveScriptMessage(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) { return; } var body = message.body as Dictionary <string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Int32.Parse(body["$target"].ToString()); NKScriptMessageHandler proxy = null; if (_proxies.ContainsKey(target)) { proxy = _proxies[target]; } else if (target > 1500) { var targetFloor = target - (target % NKRANGEPERPROCESS); if (_proxiesNatives.ContainsKey(targetFloor)) { proxy = _proxiesNatives[targetFloor]; } } if (proxy != null) { if (opcode == "-") { if (target == 0) { // TRANSFER TO REMOTE, WITH SYNC var _ = proxy.didReceiveScriptMessageSync(message); this.unbind(); } else { // TRANSFER TO REMOTE, WITH SYNC var _ = proxy.didReceiveScriptMessageSync(message); // UNBIND PROXY _cancelTokens[target].Cancel(); } } else if (typeInfo.ContainsProperty(opcode)) { // ALSO TRANSFER TO REMOTE proxy.didReceiveScriptMessage(message); } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method // TRANSFER TO REMOTE ONLY proxy.didReceiveScriptMessage(message); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); } } else if (opcode == "+") { throw new NotImplementedException("+ opcode must be called using synchronous messages"); } else { // else Unknown opcode var obj = _principal.plugin as NKScriptMessageHandler; if (obj != null) { obj.didReceiveScriptMessage(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); } } } else { // null body, ignore } }
public override object didReceiveScriptMessageSync(NKScriptMessage message) { // A workaround for when postMessage(undefined) if (message.body == null) { return(false); } // thread static NKScriptValue._currentContext = this.context; object result; var body = message.body as Dictionary <string, object>; if (body != null && body.ContainsKey("$opcode")) { string opcode = body["$opcode"] as String; int target = Int32.Parse(body["$target"].ToString()); NKScriptMessageHandler proxy = null; if (_proxies.ContainsKey(target)) { proxy = _proxies[target]; } else if (target > 1500) { var targetFloor = target - (target % 10); if (_proxiesNatives.ContainsKey(targetFloor)) { proxy = _proxiesNatives[targetFloor]; } } if (proxy != null) { if (opcode == "-") { if (target == 0) { // TRANSFER TO REMOTE var _ = proxy.didReceiveScriptMessageSync(message); this.unbind(); result = true; } else { // TRANSFER TO REMOTE var _ = proxy.didReceiveScriptMessageSync(message); // UNBIND PROXY _cancelTokens[target].Cancel(); result = true; } } else if (typeInfo.ContainsProperty(opcode)) { // TRANSFER TO REMOTE proxy.didReceiveScriptMessageSync(message); result = true; } else if (typeInfo.ContainsMethod(opcode)) { // Invoke method via REMOTE proxy result = proxy.didReceiveScriptMessageSync(message); } else { NKLogging.log(String.Format("!Invalid member name: {0}", opcode)); result = false; } } else if (opcode == "+") { _instances[target] = null; int maxNativeFirst = NKScriptChannel.nativeFirstSequence - (NKScriptChannel.nativeFirstSequence % NKRANGEPERPROCESS) - 1; int minNativeFirst = (maxNativeFirst - NKRANGEPERPROCESS) + 1; NKScriptChannel.nativeFirstSequence = minNativeFirst - 1; var cancelTokenSource = new CancellationTokenSource(); _cancelTokens[target] = cancelTokenSource; proxy = NKRemoting.NKRemotingProxy.createClient(ns, id, maxNativeFirst, message, context, cancelTokenSource.Token); _proxies[target] = proxy; _proxiesNatives[minNativeFirst] = proxy; result = true; } else { // else Unknown opcode var obj = _principal.plugin as NKScriptMessageHandler; if (obj != null) { result = obj.didReceiveScriptMessageSync(message); } else { // discard unknown message NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString())); result = false; } } } else { // null body result = false; } //thread static NKScriptValue._currentContext = null; return(result); }