예제 #1
0
        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="method">方法名。</param>
        /// <param name="arguments">调用的参数。</param>
        /// <returns></returns>
        public async Task <T> SendAsync <T>(string method, params object[] arguments)
        {
            var serializer = new JsonSerializer();

            var message = new InvokeMessage(method, 0, arguments);
            var json    = serializer.Serialize(message);
            var bytes   = Encoding.UTF8.GetBytes(json);

            await client.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, CancellationToken.None);

            var buffer = new byte[1024 * 4];
            var result = await client.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);

            if (result.CloseStatus.HasValue)
            {
                return(default(T));
            }

            var obj = serializer.Deserialize <InvokeMessage>(Encoding.UTF8.GetString(buffer, 0, result.Count));

            if (obj.Direction == 1)
            {
                return(obj.Arguments[0].To <T>());
            }

            return(default(T));
        }
예제 #2
0
        /// <summary>
        /// 解析方法的参数。
        /// </summary>
        /// <param name="method"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private object[] ResolveArguments(MethodInfo method, InvokeMessage message)
        {
            var parameters = method.GetParameters();

            if (parameters.Length != message.Arguments.Length)
            {
                throw new Exception($"方法 {message.Method} 参数不匹配");
            }

            //处理参数
            var arguments = new object[message.Arguments.Length];

            for (var i = 0; i < arguments.Length; i++)
            {
                if (message.Arguments[i] != null && parameters[i].ParameterType != message.Arguments[i].GetType())
                {
                    arguments[i] = message.Arguments[i].ToType(parameters[i].ParameterType);
                }
                else
                {
                    arguments[i] = message.Arguments[i];
                }
            }

            return(arguments);
        }
예제 #3
0
        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="method">方法名。</param>
        /// <param name="arguments">调用的参数。</param>
        /// <returns></returns>
        public async Task <T> SendAsync <T>(string method, params object[] arguments)
        {
            var message = new InvokeMessage(method, 0, arguments)
            {
                IsReturn = 1
            };
            var json  = Formatter.FormatMessage(message);
            var bytes = Encoding.GetBytes(json);

            await _client.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, CancellationToken.None);

            var buffer = new byte[ReceiveBufferSize];
            var result = await _client.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);

            if (result.CloseStatus.HasValue)
            {
                return(default(T));
            }

            try
            {
                var obj = Formatter.ResolveMessage(Encoding.GetString(buffer, 0, result.Count));
                if (obj != null && obj.Direction == 1)
                {
                    return(obj.Arguments[0].To <T>());
                }
            }
            catch (Exception exp)
            {
                throw new InvalidOperationException($"发送 {method} 时发生异常。", exp);
            }

            return(default(T));
        }
예제 #4
0
        public async Task SendAsync(InvokeMessage message)
        {
            var json  = context.Option.Formatter.FormatMessage(message);
            var bytes = context.Option.Encoding.GetBytes(json);

            await context.WebSocket.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, CancellationToken.None);
        }
예제 #5
0
        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <param name="method">方法名。</param>
        /// <param name="arguments">调用的参数。</param>
        /// <returns></returns>
        public async Task SendAsync(string method, params object[] arguments)
        {
            var message = new InvokeMessage(method, 0, arguments);
            var json    = Formatter.FormatMessage(message);
            var bytes   = Encoding.GetBytes(json);

            await _client.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, CancellationToken.None);
        }
예제 #6
0
        /// <summary>
        /// 格式化 <see cref="InvokeMessage"/> 对象为传输的文本。
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public virtual string FormatMessage(InvokeMessage message)
        {
            var option = new JsonSerializeOption();

            option.Converters.Add(new FullDateTimeJsonConverter());
            var serializer = new JsonSerializer(option);

            return(serializer.Serialize(message));
        }
예제 #7
0
        public Task SendAsync(InvokeMessage message)
        {
            var sub = SubscribeManagerFactory.CreateManager();

            sub.Publish(new Subject {
                Source = context.ConnectionId, Message = message
            });
            return(null);
        }
예제 #8
0
        /// <summary>
        /// 返回数据。
        /// </summary>
        /// <param name="message"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private byte[] ReturnValue(InvokeMessage message, object result)
        {
            if (message.IsReturn == 0 || result == null)
            {
                return(new byte[0]);
            }

            var retMsg = new InvokeMessage(message.Method, 1, new[] { result });

            return(acceptContext.Option.Encoding.GetBytes(acceptContext.Option.Formatter.FormatMessage(retMsg)));
        }
예제 #9
0
        async Task IClientProxy.SendAsync(string method, params object[] arguments)
        {
            var option = new JsonSerializeOption()
            {
                Indent = false
            };
            var serializer = new JsonSerializer(option);

            var message = new InvokeMessage(method, 0, arguments);
            var json    = serializer.Serialize(message);
            var bytes   = Encoding.UTF8.GetBytes(json);

            await acceptContext.WebSocket.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, CancellationToken.None);
        }
예제 #10
0
        /// <summary>
        /// 处理数据结果。
        /// </summary>
        /// <param name="type"></param>
        /// <param name="buffer"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        private byte[] HandleResult(WebSocketMessageType type, byte[] buffer, int length)
        {
            ProcessHeartBeat();

            if (type == WebSocketMessageType.Binary)
            {
                OnReceived(buffer);
            }
            else if (type == WebSocketMessageType.Text)
            {
                var serializer = new JsonSerializer();
                var content    = Encoding.UTF8.GetString(buffer, 0, length);

                try
                {
                    OnReceived(content);

                    var obj = serializer.Deserialize <InvokeMessage>(content);

                    var method = this.GetType().GetMethod(obj.Method, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                    if (method == null)
                    {
                        throw new Exception($"没有发现方法 {obj.Method}");
                    }

                    if (method.GetParameters().Length != obj.Arguments.Length)
                    {
                        throw new Exception($"方法 {obj.Method} 参数不匹配");
                    }

                    var result = method.Invoke(this, obj.Arguments);
                    if (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
                    {
                        result = method.ReturnType.GetProperty("Result").GetValue(result);
                    }

                    if (method.ReturnType != typeof(void))
                    {
                        var ret = new InvokeMessage(obj.Method, 1, new[] { result });
                        return(Encoding.UTF8.GetBytes(serializer.Serialize(ret)));
                    }
                }
                catch (Exception exp)
                {
                    OnResolveError(content, exp);
                }
            }

            return(new byte[0]);
        }
예제 #11
0
        async Task IClientProxy.SendAsync(string method, params object[] arguments)
        {
            var message = new InvokeMessage(method, 0, arguments);
            var json    = acceptContext.Option.Formatter.FormatMessage(message);
            var bytes   = acceptContext.Option.Encoding.GetBytes(json);

            try
            {
                await acceptContext.WebSocket.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, CancellationToken.None);
            }
            catch (Exception exp)
            {
                OnInvokeError(message, new WebSocketHandleException(ConnectionId, "调用客户端方法时发生异常。", exp));
            }
        }
예제 #12
0
        /// <summary>
        /// 查找调用的方法。
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private MethodInfo FindMethod(InvokeMessage message)
        {
            var methods = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(s => s.Name.Equals(message.Method, StringComparison.InvariantCultureIgnoreCase)).ToArray();

            if (methods.Length == 0)
            {
                throw new Exception($"没有找到方法 {message.Method}。");
            }

            if (methods.Length > 1)
            {
                throw new AmbiguousMatchException($"无法从多个重载方法匹配 {message.Method},只允许定义一个方法。");
            }

            return(methods[0]);
        }
예제 #13
0
        async Task IClientProxy.SendAsync(string method, params object[] arguments)
        {
            var message = new InvokeMessage(method, 0, arguments);
            var json    = AcceptContext.Option.Formatter.FormatMessage(message);
            var bytes   = AcceptContext.Option.Encoding.GetBytes(json);

            try
            {
                if (IsValidState(WebSocketState.Open, WebSocketState.CloseReceived))
                {
                    await AcceptContext.WebSocket.SendAsync(new ArraySegment <byte>(bytes, 0, bytes.Length), WebSocketMessageType.Text, true, cancelToken.Token);
                }
            }
            catch (Exception exp)
            {
                OnInvokeError(message, new WebSocketHandleException(ConnectionId, "调用客户端方法时发生异常。", exp));
            }
        }
예제 #14
0
 /// <summary>
 /// 查找调用的方法。
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 private MethodInfo FindMethod(InvokeMessage message)
 {
     return(this.GetType().GetMethod(message.Method, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase));
 }
예제 #15
0
 /// <summary>
 /// 调用方法失败时的通知。
 /// </summary>
 /// <param name="message"></param>
 /// <param name="exception">异常。</param>
 protected virtual void OnInvokeError(InvokeMessage message, Exception exception)
 {
 }
예제 #16
0
 public Task SendToUsers(InvokeMessage message)
 {
     throw new NotImplementedException();
 }
예제 #17
0
        /// <summary>
        /// 处理数据结果。
        /// </summary>
        /// <param name="type"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private byte[] HandleResult(WebSocketMessageType type, byte[] data)
        {
            ProcessHeartBeat();

            if (type == WebSocketMessageType.Binary)
            {
                OnReceived(data);
            }
            else if (type == WebSocketMessageType.Text)
            {
                var           content = acceptContext.Option.Encoding.GetString(data);
                InvokeMessage message = null;

                try
                {
                    OnReceived(content);
                    message = acceptContext.Option.Formatter.ResolveMessage(content);
                }
                catch (Exception exp)
                {
                    OnResolveError(content, exp);
                    return(null);
                }

                Type returnType = null;

                try
                {
                    var method = FindMethod(message);
                    if (method == null)
                    {
                        throw new Exception($"没有发现方法 {message.Method}");
                    }

                    var arguments = ResolveArguments(method, message);

                    var result = method.FastInvoke(this, arguments);
                    if (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
                    {
                        returnType = method.ReturnType.GetGenericArguments()[0];
                        result     = method.ReturnType.GetProperty("Result").GetValue(result);
                    }
                    else if (method.ReturnType != typeof(void))
                    {
                        returnType = method.ReturnType;
                    }

                    if (returnType != null)
                    {
                        message.IsReturn = 1;
                        return(ReturnValue(message, result));
                    }
                }
                catch (Exception exp)
                {
                    OnInvokeError(message, new WebSocketHandleException(ConnectionId, "处理接收到的数据时发生异常。", exp));
                    return(ReturnValue(message, returnType?.GetDefaultValue()));
                }
            }

            return(null);
        }
예제 #18
0
 public Task SendToGroup(InvokeMessage message)
 {
     throw new System.NotImplementedException();
 }