Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WebSocketHandler"/> class.
 /// </summary>
 /// <param name="webSocketConnectionManager">The web socket connection manager.</param>
 /// <param name="methodInvocationStrategy">The method invocation strategy used for incoming requests.</param>
 public WebSocketHandler(WebSocketConnectionManager webSocketConnectionManager, MethodInvocationStrategy methodInvocationStrategy)
 {
     _jsonSerializerSettings.Converters.Insert(0, new PrimitiveJsonConverter());
     WebSocketConnectionManager = webSocketConnectionManager;
     MethodInvocationStrategy   = methodInvocationStrategy;
     _pingTimer = new Timer(OnPingTimer, null, WebSocket.DefaultKeepAliveInterval, WebSocket.DefaultKeepAliveInterval);
     ulid       = NUlid.Ulid.NewUlid().ToGuid().ToString();
 }
Пример #2
0
        private async Task StartClient(Uri uri, CancellationToken token, ReconnectionType type)
        {
            // also check if connection was lost, that's probably why we get called multiple times.
            if (_clientWebSocket == null || _clientWebSocket.State != WebSocketState.Open)
            {
                // create a new web-socket so the next connect call works.
                _clientWebSocket?.Dispose();
                //var options = new ClientWebSocketOptions();
                _clientWebSocket = new ClientWebSocket();
                _clientWebSocket.Options.KeepAliveInterval = new TimeSpan(0, 0, 15, 0);

                if (!string.IsNullOrEmpty(_token))
                {
                    _clientWebSocket.Options.SetRequestHeader("Authorization", "Bearer " + _token);
                }
            }
            // don't do anything, we are already connected.
            else
            {
                return;
            }
            try
            {
                //await _clientWebSocket.ConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
                await _clientWebSocket.ConnectAsync(uri, token).ConfigureAwait(false);

                OnConnect?.Invoke(this, EventArgs.Empty);
                IsRunning = true;
                await Receive(_clientWebSocket, token, async (receivedMessage) =>
                {
                    JObject jObject = null;
                    InvocationDescriptor invocationDescriptor = null;
                    try
                    {
                        jObject = Newtonsoft.Json.JsonConvert.DeserializeObject <JObject>(receivedMessage);
                        //invocationDescriptor = JsonConvert.DeserializeObject<InvocationDescriptor>(serializedMessage);
                        invocationDescriptor = jObject.ToObject <InvocationDescriptor>();
                        //if (invocationDescriptor == null) return;
                    }
                    catch (Exception ex)
                    {
                        // ignore invalid data sent to the server.
                    }
                    if (jObject == null)
                    {
                        try
                        {
                            var obj = MethodInvocationStrategy.OnTextReceivedAsync("", receivedMessage);
                        }
                        catch (Exception ex)
                        {
                        }
                        return;
                    }
                    if (invocationDescriptor != null && invocationDescriptor.Params != null)
                    {
                        if (invocationDescriptor.Id == 0)
                        {
                            // invoke the method only.
                            try
                            {
                                await MethodInvocationStrategy.OnInvokeMethodReceivedAsync("", invocationDescriptor);
                            }
                            catch (Exception)
                            {
                                // we consume all exceptions.
                                return;
                            }
                        }
                        else
                        {
                            // invoke the method and get the result.
                            InvocationResult invokeResult;
                            try
                            {
                                // create an invocation result with the results.
                                invokeResult = new InvocationResult()
                                {
                                    Id        = invocationDescriptor.Id,
                                    Result    = await MethodInvocationStrategy.OnInvokeMethodReceivedAsync("", invocationDescriptor),
                                    Exception = null
                                };
                            }
                            // send the exception as the invocation result if there was one.
                            catch (Exception ex)
                            {
                                invokeResult = new InvocationResult()
                                {
                                    Id        = invocationDescriptor.Id,
                                    Result    = null,
                                    Exception = new RemoteException(ex)
                                };
                            }

                            // send a message to the server containing the result.
                            var message = new Message()
                            {
                                MessageType = MessageType.MethodReturnValue,
                                Data        = JsonConvert.SerializeObject(invokeResult)
                            };
                            //var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message, _jsonSerializerSettings));
                            //var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message.Data, _jsonSerializerSettings));
                            //await _clientWebSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None).ConfigureAwait(false);
                            await Send(message.Data);
                        }
                    }
                    else
                    {
                        try
                        {
                            var invocationResult = jObject.ToObject <InvocationResult>();
                            if ((invocationResult != null) && (invocationResult.Exception != null || invocationResult.Result != null))
                            {
                                // find the completion source in the waiting list.
                                if (_waitingRemoteInvocations.ContainsKey(invocationResult.Id))
                                {
                                    // set the result of the completion source so the invoke method continues executing.
                                    _waitingRemoteInvocations[invocationResult.Id].SetResult(invocationResult);
                                    // remove the completion source from the waiting list.
                                    _waitingRemoteInvocations.Remove(invocationResult.Id);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            var str = e.Message;
                        }
                    }
                });

                ActivateLastChance();
            }
            catch (Exception e)
            {
                Console.WriteLine($"{DateTime.Now} _clientWebSocket.ConnectAsync Exception: {e.Message}");
                IsRunning = false;
                await Task.Delay(ErrorReconnectTimeoutMs, _cancelation.Token).ConfigureAwait(false);
                await Reconnect(ReconnectionType.Error).ConfigureAwait(false);
            }
        }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Connection"/> class.
 /// </summary>
 /// <param name="methodInvocationStrategy">The method invocation strategy used for incoming requests.</param>
 public Connection(MethodInvocationStrategy methodInvocationStrategy)
 {
     MethodInvocationStrategy = methodInvocationStrategy;
     _jsonSerializerSettings.Converters.Insert(0, new PrimitiveJsonConverter());
 }
Пример #4
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;
        }
Пример #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
 /// <summary>
 /// Initializes a new instance of the <see cref="WebSocketHandler"/> class.
 /// </summary>
 /// <param name="webSocketConnectionManager">The web socket connection manager.</param>
 /// <param name="methodInvocationStrategy">The method invocation strategy used for incoming requests.</param>
 public WebSocketHandler(WebSocketConnectionManager webSocketConnectionManager, MethodInvocationStrategy methodInvocationStrategy)
 {
     _jsonSerializerSettings.Converters.Insert(0, new PrimitiveJsonConverter());
     WebSocketConnectionManager = webSocketConnectionManager;
     MethodInvocationStrategy   = methodInvocationStrategy;
 }