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; }
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. }
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; }
public virtual async Task OnUnknownAsync(WebSocketConnection socket, JObject jObject) { await Task.CompletedTask; }
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); } }
public virtual async Task PostRpcRequest(WebSocketConnection socket, InvocationDescriptor invocationDescriptor, long elapse) { await Task.CompletedTask; }
public virtual async Task PostRpcResponse(WebSocketConnection socket, InvocationResult invocationResult) { await Task.CompletedTask; }
public virtual async Task PreRpcRequest(WebSocketConnection socket, InvocationDescriptor invocationDescriptor) { await Task.CompletedTask; }
/// <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); }
/// <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; }
public void AddSocket(WebSocketConnection socket) { _sockets.TryAdd(socket.Id, socket); }
public string GetId(WebSocketConnection socket) { return(_sockets.FirstOrDefault(p => p.Value == socket).Key); }