public void SendMessage(IOCPReaderWriter IO, string Message)
        {
            var call = new IOCPRPCCall();

            call.Response = (int)ResponseType.Message;
            call.Params.Add(Message);
            Execute(IO, call);
        }
        public IOCPRPCCall Execute(IOCPReaderWriter Context, string Name, params object[] args)
        {
            var call = new IOCPRPCCall();

            call.Method = Name;
            foreach (object p in args)
            {
                call.Params.Add(p);
            }
            return(Execute(Context, call));
        }
        public IOCPRPCCall Execute(IOCPReaderWriter Context, IOCPRPCCall call)
        {
            //XmlSerializer ser = new XmlSerializer(call.GetType());
            var ms = new MemoryStream();

            //ser.Serialize(ms, call);
            Serialize(ms, call);
            // var msg = ASCIIEncoding.ASCII.GetString(ms.GetBuffer());
            // SendMessage(msg);

            var buf = new byte[ms.Length];

            //Buffer.BlockCopy(ms.GetBuffer(), 0, buf, 0, (int) ms.Length);
            ms.Position = 0;
            ms.Read(buf, 0, buf.Length);
            ms.Position = 0;

            /*
             * /// TEST CODE
             * DeSerialize(ms, call.GetType());
             * ms.Position = 0;
             * // END TEST CODE
             */
            Context.SendBuffer(buf);

            if (call.Response == (int)ResponseType.None)
            {
                call = GetResponse(call);
                if (call.Response == (int)ResponseType.Error)
                {
                    var err = new StringBuilder();
                    err.AppendLine("RPC Error:");

                    foreach (var param in call.Params)
                    {
                        err.AppendLine(param.ToString());
                    }
                    //throw new Exception(string.Format("RPC Error: {0}", call.Params[0]));
                    throw new Exception(err.ToString());
                }
            }
            else
            {
                call = null;
            }
            return(call);
        }
        public IOCPRPCCall GetResponse(IOCPRPCCall caller)
        {
            IOCPRPCCall res = null;

            while (res == null)
            {
                ProcessMessages(1000);
                lock (_responseQ)
                {
                    foreach (var r in _responseQ)
                    {
                        if (r.Id == caller.Id)
                        {
                            _responseQ.Remove(r);
                            res = r;
                            break;
                        }
                    }
                }
                //ProcessMessages();
                //_responseEvent.WaitOne(1000);
            }
            return(res);
        }
        protected override void InternalProcessMessage(IOCPReaderWriter Context, byte[] Message)
        {
            base.InternalProcessMessage(Context, Message);
            var call = new IOCPRPCCall();
            //XmlSerializer ser = new XmlSerializer(call.GetType());
            var buf = Message; //ASCIIEncoding.ASCII.GetBytes(Message);
            var ms  = new MemoryStream();

            ms.Write(buf, 0, buf.Length);
            ms.Position = 0;
            //call = (IOCPRPCCall) ser.Deserialize(ms);
            call = (IOCPRPCCall)DeSerialize(ms, call.GetType());
            var rpcContext = new RpcContext(Context.Socket, Context, this, call);

            switch ((ResponseType)call.Response)
            {
            default:
            {
                _responseQ.Add(call);
                return;
            }
            break;

            case ResponseType.Message:
            {
                if (OnMessage != null)
                {
                    OnMessage(this, rpcContext, call.Params[0].ToString());
                }
                return;
            }
            break;

            case ResponseType.None:
            {
            }
            break;
            }

            /*            if (call.Response != (int)ResponseType.None)
             *          {
             *              _responseQ.Add(call);
             *              return;
             *          }*/

            MethodHandlerContext ctx = null;

            {
                var session = _sessions.GetSession();
                try
                {
                    if (session.TryGetValue(call.Method, out ctx))
                    {
                        try
                        {
                            // THIS MIGHT BE NESSESARY FOR MULTIPLE THREADS
                            object[] outp;
                            lock (ctx.Instance)
                            {
                                var inputParams = new object[call.Params.Count + 1];
                                inputParams[0] = rpcContext;
                                for (int i = 1; i <= call.Params.Count; i++)
                                {
                                    inputParams[i] = call.Params[i - 1];
                                }
                                outp = (object[])ctx.MethodInfo.Invoke(ctx.Instance, inputParams);
                                call.SetResponse(ResponseType.Success, "");
                                call.Params.Clear();
                                foreach (object p in outp)
                                {
                                    call.Params.Add(p);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            if (e is TargetInvocationException)
                            {
                                e = ((TargetInvocationException)e).InnerException;
                            }
                            call.SetException(e);
                        }
                    }
                    else
                    {
                        call.SetResponse(ResponseType.Error, string.Format("Method not found: {0}", call.Method));
                    }
                }
                finally
                {
                    _sessions.ReleaseSession(session);
                }
            }
            Execute(Context, call);

            /* foreach (var handler in _handlers)
             * {
             *
             *   foreach (var metho in handler.GetType().GetMethods())
             *   {
             *       if (metho.Name == call.Method)
             *       {
             *           object[] outp = (object[])metho.Invoke(handler, call.Params.ToArray());
             *           call.Params.Clear();
             *           foreach (object p in outp)
             *           {
             *               call.Params.Add(p);
             *           }
             *           call.IsResponse = true;
             *           Execute(Context, call);
             *       }
             *   }
             * }*/
        }