コード例 #1
0
        public virtual async Task OnPeerResponseAsync(WebSocketConnection socket, InvocationResult invocationResult)
        {
            var socketId = WebSocketConnectionManager.GetId(socket);

            try
            {
                if (_waitingRemoteInvocations.ContainsKey(socketId) && invocationResult.Id > 0)
                {
                    if (_waitingRemoteInvocations[socketId].ContainsKey(invocationResult.Id))
                    {
                        _waitingRemoteInvocations[socketId][invocationResult.Id].SetResult(invocationResult);
                        // remove the completion source from the waiting list.
                    }
                    _waitingRemoteInvocations[socketId].Remove(invocationResult.Id);
                }
            }
            catch (Exception e)
            {
                var str = e.Message;
            }
            await Task.CompletedTask;
        }
コード例 #2
0
        public async Task <T> InvokeClientMethodAsync <T>(string socketId, string methodName, object[] arguments)
        {
            // create the method invocation descriptor.
            object methodParams = null;

            if (arguments.Length == 1)
            {
                methodParams = arguments[0];
            }
            else
            {
                methodParams = arguments;
            }
            InvocationDescriptor invocationDescriptor = new InvocationDescriptor {
                MethodName = methodName, Params = methodParams
            };
            WebSocketConnection socket = WebSocketConnectionManager.GetSocketById(socketId);

            // generate a unique identifier for this invocation.
            if (socket == null)
            {
                return(default(T));
            }
            invocationDescriptor.Id = socket.NextCmdId(); // Guid.NewGuid();

            // add ourselves to the waiting list for return values.
            TaskCompletionSource <InvocationResult> task = new TaskCompletionSource <InvocationResult>();

            // after a timeout of 60 seconds we will cancel the task and remove it from the waiting list.
            new CancellationTokenSource(1000 * 60).Token.Register(() => { _waitingRemoteInvocations[socketId].Remove(invocationDescriptor.Id); task.TrySetCanceled(); });
            if (!_waitingRemoteInvocations.ContainsKey(socketId))
            {
                _waitingRemoteInvocations[socketId] = new Dictionary <long, TaskCompletionSource <InvocationResult> >();
            }
            _waitingRemoteInvocations[socketId].Add(invocationDescriptor.Id, task);

            // send the method invocation to the client.
            var message = new Message()
            {
                MessageType = MessageType.MethodInvocation,
                //Data = JsonConvert.SerializeObject(invocationDescriptor, _jsonSerializerSettings)
                Data = JsonConvert.SerializeObject(invocationDescriptor)
            };

            await SendMessageAsync(socketId, message).ConfigureAwait(false);

            // wait for the return value elsewhere in the program.
            InvocationResult result = await task.Task;

            // ... we just got an answer.

            // if we have completed successfully:
            if (task.Task.IsCompleted)
            {
                // there was a remote exception so we throw it here.
                if (result.Exception != null)
                {
                    throw new Exception(result.Exception.Message);
                }

                // return the value.

                // support null.
                if (result.Result == null)
                {
                    return(default(T));
                }
                // cast anything to T and hope it works.
                return((T)result.Result);
            }

            // if we reach here we got cancelled or alike so throw a timeout exception.
            throw new TimeoutException(); // todo: insert fancy message here.
        }
コード例 #3
0
        public virtual async Task OnReceivedBinaryAsync(WebSocketConnection socket, byte[] receivedMessage)
        {
            InvocationDescriptor invocationDescriptor;
            InvocationResult     invocationResult;
            var timer = new Stopwatch();

            timer.Start();
            try
            {
                invocationResult = MessagePackSerializer.Deserialize <InvocationResult>(receivedMessage);
                if ((invocationResult != null) && (invocationResult.Exception != null || invocationResult.Result != null))
                {
                    await PreRpcResponse(socket, invocationResult).ConfigureAwait(false);
                    await OnPeerResponseAsync(socket, invocationResult);
                    await PostRpcResponse(socket, invocationResult).ConfigureAwait(false);

                    return;
                }
            }
            catch (Exception e)
            {
                // Ignore if is not msgrpc result
            }
            try
            {
                invocationDescriptor = MessagePackSerializer.Deserialize <InvocationDescriptor>(receivedMessage);
                if (invocationDescriptor == null)
                {
                    return;
                }
                await PreRpcRequest(socket, invocationDescriptor).ConfigureAwait(false);

                // retrieve the method invocation request.
                // if the unique identifier hasn't been set then the client doesn't want a return value.
                if (invocationDescriptor.Id == 0)
                {
                    // invoke the method only.
                    try
                    {
                        var result = await MethodInvocationStrategy.OnInvokeMethodReceivedAsync(socket, invocationDescriptor);

                        timer.Stop();
                        await PostRpcRequest(socket, invocationDescriptor, timer.ElapsedMilliseconds).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        // we consume all exceptions.
                    }
                }
                else
                {
                    try
                    {
                        var invokeResult = await MethodInvocationStrategy.OnInvokeMethodReceivedAsync(socket, invocationDescriptor);

                        if (invokeResult is InvocationResult)
                        {
                            invocationResult = (InvocationResult)invokeResult;
                        }
                        if (invokeResult != null)
                        {
                            MessagePackSerializerOptions options;
                            byte[] bytes   = MessagePackSerializer.Serialize(invokeResult);
                            var    message = new Message()
                            {
                                MessageType = MessageType.Binary,
                                Bytes       = bytes
                            };
                            await SendMessageAsync(socket, message).ConfigureAwait(false);

                            timer.Stop();
                            await PostRpcRequest(socket, invocationDescriptor, timer.ElapsedMilliseconds);
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                }
            }
            catch (Exception e)
            {
                //throw;
            }
            timer.Stop();
            await Task.CompletedTask;
        }
コード例 #4
0
 public virtual async Task OnUnknownAsync(WebSocketConnection socket, JObject jObject)
 {
     await Task.CompletedTask;
 }
コード例 #5
0
        public virtual async Task OnReceivedTextAsync(WebSocketConnection socket, string serializedMessage)
        {
            var     timer   = new Stopwatch();
            JObject jObject = null;
            InvocationDescriptor invocationDescriptor = null;
            InvocationResult     invocationResult     = null;

            timer.Start();
            try
            {
                jObject = JsonConvert.DeserializeObject <JObject>(serializedMessage);
            }
            catch (Exception e)
            {
                // ignore invalid data sent to the server.
                //socket.WebSocket.CloseOutputAsync();
                return;
            }
            try
            {
                invocationResult = jObject.ToObject <InvocationResult>();
                if ((invocationResult != null) && (invocationResult.Exception != null || invocationResult.Result != null))
                {
                    await PreRpcResponse(socket, invocationResult).ConfigureAwait(false);
                    await OnPeerResponseAsync(socket, invocationResult);
                    await PostRpcResponse(socket, invocationResult).ConfigureAwait(false);

                    return;
                }
            }
            catch (Exception e)
            {
                // Ignore if is not jsonrpc result
            }
            try
            {
                invocationDescriptor = jObject.ToObject <InvocationDescriptor>();
            }
            catch (Exception e)
            {
                // Not jsonrpc request
                //return;
            }
            // method invocation request.
            if (invocationDescriptor != null)
            {
                await PreRpcRequest(socket, invocationDescriptor).ConfigureAwait(false);

                // retrieve the method invocation request.
                // if the unique identifier hasn't been set then the client doesn't want a return value.
                if (invocationDescriptor.Id == 0)
                {
                    // invoke the method only.
                    try
                    {
                        var result = await MethodInvocationStrategy.OnInvokeMethodReceivedAsync(socket, invocationDescriptor);

                        timer.Stop();
                        await PostRpcRequest(socket, invocationDescriptor, timer.ElapsedMilliseconds).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        // we consume all exceptions.
                    }
                    timer.Start();
                }
                else
                {
                    try
                    {
                        var invokeResult = await MethodInvocationStrategy.OnInvokeMethodReceivedAsync(socket, invocationDescriptor);

                        if (invokeResult != null)
                        {
                            string json = JsonConvert.SerializeObject(invokeResult);
                            // send a message to the client containing the result.
                            var message = new Message()
                            {
                                MessageType = MessageType.MethodReturnValue,
                                Data        = json
                                              //Data = JsonConvert.SerializeObject(invokeResult, _jsonSerializerSettings)
                            };
                            await SendMessageAsync(socket, message).ConfigureAwait(false);

                            timer.Stop();
                            await PostRpcRequest(socket, invocationDescriptor, timer.ElapsedMilliseconds);
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                }
            }
            else
            {
                await OnUnknownAsync(socket, jObject);
            }
        }
コード例 #6
0
 public virtual async Task PostRpcRequest(WebSocketConnection socket, InvocationDescriptor invocationDescriptor, long elapse)
 {
     await Task.CompletedTask;
 }
コード例 #7
0
 public virtual async Task PostRpcResponse(WebSocketConnection socket, InvocationResult invocationResult)
 {
     await Task.CompletedTask;
 }
コード例 #8
0
 public virtual async Task PreRpcRequest(WebSocketConnection socket, InvocationDescriptor invocationDescriptor)
 {
     await Task.CompletedTask;
 }
コード例 #9
0
 /// <summary>
 /// Called when a client has disconnected from the server.
 /// </summary>
 /// <param name="socket">The web-socket of the client.</param>
 /// <returns>Awaitable Task.</returns>
 public virtual async Task OnDisconnected(WebSocketConnection socket)
 {
     await WebSocketConnectionManager.RemoveSocket(WebSocketConnectionManager.GetId(socket)).ConfigureAwait(false);
 }
コード例 #10
0
 /// <summary>
 /// Called when a client has connected to the server.
 /// </summary>
 /// <param name="socket">The web-socket of the client.</param>
 /// <returns>Awaitable Task.</returns>
 public virtual async Task OnConnected(WebSocketConnection socket)
 {
     WebSocketConnectionManager.AddSocket(socket);
     await Task.CompletedTask;
 }
コード例 #11
0
 public void AddSocket(WebSocketConnection socket)
 {
     _sockets.TryAdd(socket.Id, socket);
 }
コード例 #12
0
 public string GetId(WebSocketConnection socket)
 {
     return(_sockets.FirstOrDefault(p => p.Value == socket).Key);
 }