/// <summary> /// Sends a request to the IPC and waits for a response. /// </summary> /// <param name="request">Type of request</param> /// <param name="expectedReply">Expected type of reply</param> /// <param name="timeout">Timeout length (in MS)</param> /// <returns></returns> /// <exception cref="IpcInvalidReponseException>">The IPC sent an unexpected response</exception>" /// <exception cref="TimeoutException">The operation timed out</exception>" protected async Task <IpcMessage> SendRequest(IpcMessage request, IpcMessageType expectedReply, int timeout = 5000) { SemaphoreSlim evt = new SemaphoreSlim(0, 1); IpcMessage returnedMessage; lock (awaitingResponseLock) { awaitingResponseMessages.Add(request.MessageId, new Tuple <SemaphoreSlim, IpcMessage>(evt, null)); } Write(request); bool cancelled = !await evt.WaitAsync(timeout); lock (awaitingResponseLock) { evt.Dispose(); awaitingResponseMessages.TryGetValue(request.MessageId, out Tuple <SemaphoreSlim, IpcMessage> ret); returnedMessage = ret.Item2; awaitingResponseMessages.Remove(request.MessageId); } if (cancelled) { throw new TimeoutException(); } if (returnedMessage.MessageType != expectedReply) { throw new IpcInvalidReponseException(returnedMessage.MessageType, expectedReply); } return(returnedMessage); }
//Preprocess non-serialized data and manage standard IPC messages private void PreProcessMessage(byte[] data) { IpcMessageType type = (IpcMessageType)data[0]; if (type == IpcMessageType.AnonIpcInputData) { InputReceived?.Invoke(this, new ISInputData(data, 1)); return; } else if (type == IpcMessageType.IpcPoll) { HandlePoll(new IpcMessage(data)); return; } else if (type == IpcMessageType.IpcHostOK) { HandleHostOK(); return; } else if (type == IpcMessageType.IpcClientOK) { HandleClientOK(); return; } IpcMessage msg = null; if (type == IpcMessageType.AnonIpcClipboardData) { msg = new AnonIpc.Messages.AnonIpcClipboardDataMessage(data); } else if (type == IpcMessageType.AnonIpcDisplayConfigReply) { msg = new AnonIpc.Messages.AnonIpcDisplayConfigMessage(data); } else if (type == IpcMessageType.AnonIpcStreamReadResponse) { msg = new AnonIpc.Messages.AnonIpcReadStreamResponseMessage(data); } else if (type == IpcMessageType.AnonIpcDoDragDrop) { msg = new AnonIpc.Messages.AnonIpcDoDragDropMessage(data); } else if (type == IpcMessageType.AnonIpcFileTokenResponse) { msg = new AnonIpc.Messages.AnonIpcRequestFileTokenResponseMessage(data); } if (msg == null) { msg = new IpcMessage(data); } if (!CheckAwaitingMessages(msg)) { ProcessMessage(type, data); } }
public IpcMessage(IpcMessageType type, Guid messageId = default) { MessageType = type; if (messageId == default) { MessageId = Guid.NewGuid(); } else { MessageId = messageId; } }
protected override void ProcessMessage(IpcMessageType type, byte[] data) { if (type == IpcMessageType.AnonIpcClipboardData) { ClipboardDataReceived?.Invoke(this, new AnonIpcClipboardDataMessage(data).Data); } else if (type == IpcMessageType.AnonIpcEdgeHit) { EdgeHit?.Invoke(this, new AnonIpcEdgeHitMessage(data).HitEdge); } else if (type == IpcMessageType.AnonIpcDisplayConfigReply) { DisplayConfigUpdated?.Invoke(this, new AnonIpcDisplayConfigMessage(data).Config); } else if (type == IpcMessageType.AnonIpcLMouseStateReply) { LeftMouseStateUpdated?.Invoke(this, new AnonIpcLMouseStateMessage(data).LeftMouseState); } else if (type == IpcMessageType.AnonIpcDoDragDrop) { DataDropped?.Invoke(this, new AnonIpcDoDragDropMessage(data).DropData); } else if (type == IpcMessageType.AnonIpcDragDropCancelled) { DragDropCancelled?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcDragDropSuccess) { DragDropSuccess?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcDragDropComplete) { DragDropComplete?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcStreamReadRequest) { HandleReadStreamRequest(new AnonIpcReadStreamRequestMessage(data)); } else if (type == IpcMessageType.AnonIpcRequestFileToken) { HandleTokenRequest(new AnonIpcRequestFileTokenMessage(data)); } }
protected override void ProcessMessage(IpcMessageType type, byte[] data) { if (type == IpcMessageType.AnonIpcClipboardData) { AnonIpcClipboardDataMessage msg = new AnonIpcClipboardDataMessage(data); ClipboardDataReceived?.Invoke(this, msg.Data); } else if (type == IpcMessageType.AnonIpcCheckForDrop) { CheckForDropReceived?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcDisplayConfigRequest) { HandleDisplayConfigRequest(new IpcMessage(data)); } else if (type == IpcMessageType.AnonIpcDoDragDrop) { AnonIpcDoDragDropMessage msg = new AnonIpcDoDragDropMessage(data); DoDragDropReceived.Invoke(this, msg.DropData); } }
public IpcInvalidReponseException(IpcMessageType responseType, IpcMessageType expectedType) : base("Got invalid response type " + responseType + " (expected " + expectedType + ")") { }
/// <summary> /// Derived classes should override this method to process non serialized messages /// </summary> /// <param name="type"></param> /// <param name="data"></param> protected virtual void ProcessMessage(IpcMessageType type, byte[] data) { }