/// <summary> /// ProcessAndDispatchEventsToChild implementation /// </summary> /// <param name="eventContext"></param> /// <returns></returns> internal override bool ProcessAndDispatchEventsToChild(EventContext eventContext) { //There is no child for events with sender = communication Logger.Instance.Information(string.Format("[Communication] get incoming communication event, sender: {0}, senderHref: {1}, EventResourceName: {2} EventFullHref: {3}, EventType: {4} ,LoggingContext: {5}", eventContext.SenderResourceName, eventContext.SenderHref, eventContext.EventResourceName, eventContext.EventFullHref, eventContext.EventEntity.Relationship.ToString(), eventContext.LoggingContext == null ? string.Empty : eventContext.LoggingContext.ToString())); if (string.Equals(eventContext.EventEntity.Link.Token, TokenMapper.GetTokenName(typeof(ConversationResource)))) { string conversationNormalizedUri = UriHelper.NormalizeUriWithNoQueryParameters(eventContext.EventEntity.Link.Href, eventContext.BaseUri); Conversation currentConversation = m_conversations.GetOrAdd(conversationNormalizedUri, (a) => { Logger.Instance.Information(string.Format("[Communication] Add conversation {0} LoggingContext: {1}", conversationNormalizedUri, eventContext.LoggingContext == null ? string.Empty : eventContext.LoggingContext.ToString())); ConversationResource localResource = this.ConvertToPlatformServiceResource <ConversationResource>(eventContext); //For every conversation resource, we want to make sure it is using latest rest ful client return(new Conversation(this.RestfulClient, localResource, eventContext.BaseUri, eventContext.EventFullHref, this)); } ); //Remove from cache if it is a delete operation if (eventContext.EventEntity.Relationship == EventOperation.Deleted) { Conversation removedConversation = null; Logger.Instance.Information(string.Format("[Communication] Remove conversation {0} LoggingContext: {1}", conversationNormalizedUri, eventContext.LoggingContext == null ? string.Empty : eventContext.LoggingContext.ToString())); m_conversations.TryRemove(conversationNormalizedUri, out removedConversation); } currentConversation.HandleResourceEvent(eventContext); return(true); } else if (string.Equals(eventContext.EventEntity.Link.Token, TokenMapper.GetTokenName(typeof(MessagingInvitationResource)))) { this.HandleInvitationEvent <MessagingInvitationResource>( eventContext, (localResource) => new MessagingInvitation(this.RestfulClient, localResource, eventContext.BaseUri, eventContext.EventFullHref, this) ); return(true); } else if (string.Equals(eventContext.EventEntity.Link.Token, TokenMapper.GetTokenName(typeof(AudioVideoInvitationResource)))) { this.HandleInvitationEvent <AudioVideoInvitationResource>( eventContext, (localResource) => new AudioVideoInvitation(this.RestfulClient, localResource, eventContext.BaseUri, eventContext.EventFullHref, this) ); return(true); } else if (string.Equals(eventContext.EventEntity.Link.Token, TokenMapper.GetTokenName(typeof(OnlineMeetingInvitationResource)))) { this.HandleInvitationEvent <OnlineMeetingInvitationResource>( eventContext, (localResource) => new OnlineMeetingInvitation(this.RestfulClient, localResource, eventContext.BaseUri, eventContext.EventFullHref, this) ); return(true); } else if (string.Equals(eventContext.EventEntity.Link.Token, TokenMapper.GetTokenName(typeof(ParticipantInvitationResource)))) { this.HandleInvitationEvent <ParticipantInvitationResource>( eventContext, (localResource) => new ParticipantInvitation(this.RestfulClient, localResource, eventContext.BaseUri, eventContext.EventFullHref, this) ); return(true); } //TODO: Process , audioVideoInvitation, ... else { return(false); } }
internal ConversationBridge(IRestfulClient restfulClient, ConversationBridgeResource resource, Uri baseUri, Uri resourceUri, Conversation parent) : base(restfulClient, resource, baseUri, resourceUri, parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent), "Conversation is required"); } m_bridgedParticipants = new ConcurrentDictionary <string, BridgedParticipant>(); m_bridgedParticipantTcses = new ConcurrentDictionary <string, TaskCompletionSource <BridgedParticipant> >(); }
/// <summary> /// Sets the related conversation. /// </summary> /// <param name="conversation">The conversation.</param> public void SetRelatedConversation(Conversation conversation) { this.RelatedConversation = conversation; }
/// <summary> /// Creates instances of <see cref="AudioVideoCall"/>. /// </summary> /// <param name="restfulClient"><see cref="IRestfulClient"/> to use to make outbound REST HTTP requests.</param> /// <param name="resource"><see cref="AudioVideoResource"/> corresponding to this object.</param> /// <param name="baseUri"><see cref="Uri"/> of the service.</param> /// <param name="resourceUri"><see cref="Uri"/> of <paramref name="resource"/> relative to <paramref name="baseUri"/>.</param> /// <param name="parent"><see cref="Conversation"/> of which this modality is part of.</param> internal AudioVideoCall(IRestfulClient restfulClient, AudioVideoResource resource, Uri baseUri, Uri resourceUri, Conversation parent) : base(restfulClient, resource, baseUri, resourceUri, parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent), "Conversation object is required"); } // Track call transfers m_transfers = new ConcurrentDictionary <string, Transfer>(); m_transferAddedTcses = new ConcurrentDictionary <string, TaskCompletionSource <Transfer> >(); }
internal MessagingCall(IRestfulClient restfulClient, MessagingResource resource, Uri baseUri, Uri resourceUri, Conversation parent) : base(restfulClient, resource, baseUri, resourceUri, parent) { m_outGoingmessageTcses = new ConcurrentDictionary <string, TaskCompletionSource <string> >(); if (parent == null) { throw new ArgumentNullException(nameof(parent), "Conversation is required"); } }
internal override bool ProcessAndDispatchEventsToChild(EventContext eventContext) { //No child to dispatch any more, need to dispatch to child , process locally for message type if (string.Equals(eventContext.EventEntity.Link.Token, TokenMapper.GetTokenName(typeof(MessageResource)))) { MessageResource message = this.ConvertToPlatformServiceResource <MessageResource>(eventContext); if (message != null) { if (message.Direction == Direction.Incoming) { // File incoming message received event IncomingMessageEventArgs args = new IncomingMessageEventArgs { HtmlMessage = message.HtmlMessage == null? null : message.HtmlMessage.Value as TextHtmlMessage, PlainMessage = message.TextMessage == null ? null : message.TextMessage.Value as TextPlainMessage }; Conversation conv = this.Parent as Conversation; Participant fromParticipant = conv.TryGetParticipant(message.ParticipantResourceLink.Href) as Participant; if (fromParticipant == null) { Logger.Instance.Warning("Get message from an unknown participant, probably client code bug or server bug"); } else { args.FromParticipantName = fromParticipant.Name; } IncomingMessageReceived?.Invoke(this, args); } else //For out going, just detect the completed event { if (eventContext.EventEntity.Relationship == EventOperation.Completed) { TaskCompletionSource <string> tcs = null; m_outGoingmessageTcses.TryGetValue(UriHelper.CreateAbsoluteUri(this.BaseUri, eventContext.EventEntity.Link.Href).ToString().ToLower(), out tcs); if (tcs != null) { if (eventContext.EventEntity.Status == EventStatus.Success) { tcs.TrySetResult(string.Empty); } else if (eventContext.EventEntity.Status == EventStatus.Failure) { string error = eventContext.EventEntity.Error == null ? null : eventContext.EventEntity.Error.GetErrorInformationString(); tcs.TrySetException(new RemotePlatformServiceException("Send Message failed with error" + error + eventContext.LoggingContext.ToString())); } else { Logger.Instance.Error("Do not get a valid status code for message complete event!"); tcs.TrySetException(new RemotePlatformServiceException("Send Message failed !")); } m_outGoingmessageTcses.TryRemove(eventContext.EventEntity.Link.Href.ToLower(), out tcs); } } } } return(true); } else { return(false); } }
internal Participant(IRestfulClient restfulClient, ParticipantResource resource, Uri baseUri, Uri resourceUri, Conversation parent) : base(restfulClient, resource, baseUri, resourceUri, parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent), "Conversation is required"); } }
internal ParticipantsInternal(IRestfulClient restfulClient, Uri baseUri, Uri resourceUri, Conversation parent) : base(restfulClient, null, baseUri, resourceUri, parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent), "Conversation is required"); } m_participantsCache = new ConcurrentDictionary <string, Participant>(); }