Skip to content

Commit

Permalink
Implement a sendRoomMessage function (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Sep 2, 2019
1 parent 4118da0 commit 83afe10
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Emulsion.Tests/Xmpp/SharpXmppHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ open Emulsion.Xmpp

[<Fact>]
let ``Message body has a proper namespace``() =
let message = SharpXmppHelper.message "cthulhu@test" "text"
let message = SharpXmppHelper.message None "cthulhu@test" "text"
let body = Seq.exactlyOne(message.Descendants())
Assert.Equal(XNamespace.Get "jabber:client", body.Name.Namespace)

Expand Down
6 changes: 0 additions & 6 deletions Emulsion/Xmpp/AsyncXmppClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ type MessageDeliveryInfo = Async<unit> // Resolves after the message is guarante
type IAsyncXmppClient =
// TODO[F]: Implement the remaining functions in SharpXmppClient

/// Enter the room, returning the in-room lifetime. Will terminate if kicked or left the room.
abstract member EnterRoom : RoomInfo -> Async<Lifetime>

/// Sends the message to the room.
abstract member SendMessage : MessageInfo -> Async<MessageDeliveryInfo>

/// Waits for the message to be delivered.
abstract member AwaitMessageDelivery : MessageDeliveryInfo -> Async<unit>

Expand Down
32 changes: 32 additions & 0 deletions Emulsion/Xmpp/SharpXmppClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ open SharpXMPP.XMPP

open Emulsion
open Emulsion.Lifetimes
open Emulsion.Xmpp
open Emulsion.Xmpp.AsyncXmppClient
open SharpXMPP.XMPP.Client.Elements

Expand Down Expand Up @@ -53,6 +54,12 @@ let private extractException (roomInfo: RoomInfo) (presence: XMPPPresence) =
|> Option.map (fun e -> Exception(sprintf "Error: %A" e))
else None

let private addMessageHandler (lifetime: Lifetime) (client: XmppClient) handler =
let handlerDelegate = XmppConnection.MessageHandler handler
client.add_Message handlerDelegate
lifetime.OnTermination(fun () -> client.remove_Message handlerDelegate)

/// Enter the room, returning the in-room lifetime. Will terminate if kicked or left the room.
let enterRoom (client: XmppClient) (lifetime: Lifetime) (roomInfo: RoomInfo): Async<Lifetime> = async {
use connectionLifetimeDefinition = lifetime.CreateNested()
let connectionLifetime = connectionLifetimeDefinition.Lifetime
Expand Down Expand Up @@ -92,3 +99,28 @@ let enterRoom (client: XmppClient) (lifetime: Lifetime) (roomInfo: RoomInfo): As
roomLifetimeDefinition.Terminate()
return ExceptionUtils.reraise ex
}

let private hasMessageId messageId message =
SharpXmppHelper.getMessageId message = Some messageId

let private awaitMessageReceival (lifetime: Lifetime) client messageId = async {
use messageLifetimeDefinition = lifetime.CreateNested()
let messageLifetime = messageLifetimeDefinition.Lifetime
let messageReceivedTask = nestedTaskCompletionSource messageLifetime
addMessageHandler lifetime client (fun _ message ->
if hasMessageId messageId message then
messageReceivedTask.SetResult()
)

do! Async.AwaitTask messageReceivedTask.Task
}

/// Sends the message to the room. Returns an object that allows to track the message receival.
let sendRoomMessage (lifetime: Lifetime) (client: XmppClient) (messageInfo: MessageInfo): Async<MessageDeliveryInfo> =
async {
let messageId = Guid.NewGuid().ToString() // TODO[F]: Move to a new function
let message = SharpXmppHelper.message (Some messageId) messageInfo.RecipientJid messageInfo.Text
let! result = Async.StartChild <| awaitMessageReceival lifetime client messageId
client.Send message
return result
}
8 changes: 7 additions & 1 deletion Emulsion/Xmpp/SharpXmppHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Namespaces =
module Attributes =
let Code = XName.Get "code"
let From = XName.Get "from"
let Id = XName.Get "id"
let Jid = XName.Get "jid"
let Stamp = XName.Get "stamp"
let To = XName.Get "to"
Expand Down Expand Up @@ -45,8 +46,10 @@ let joinRoom (client: XmppClient) (roomJid: string) (nickname: string): unit =
let room = bookmark roomJid nickname
client.BookmarkManager.Join(room)

let message (toAddr : string) (text : string) =
let message (id: string option) (toAddr: string) (text: string): XMPPMessage =
// TODO[F]: Make id a mandatory parameter?
let m = XMPPMessage()
id |> Option.iter (fun id -> m.SetAttributeValue(Id, id))
m.SetAttributeValue(Type, "groupchat")
m.SetAttributeValue(To, toAddr)
let body = XElement(Body)
Expand Down Expand Up @@ -81,6 +84,9 @@ let isGroupChatMessage(message: XMPPMessage): bool =
let isEmptyMessage(message: XMPPMessage): bool =
String.IsNullOrWhiteSpace message.Text

let getMessageId(message: XMPPMessage): string option =
getAttributeValue message Id

let parseMessage (message: XMPPMessage): Message =
let nickname =
getAttributeValue message From
Expand Down
2 changes: 1 addition & 1 deletion Emulsion/Xmpp/XmppClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ let run (logger: ILogger) (client: XmppClient): Async<unit> =

let send (settings: XmppSettings) (client: XmppClient) (message: Message): unit =
let text = sprintf "<%s> %s" message.author message.text
SharpXmppHelper.message settings.Room text
SharpXmppHelper.message None settings.Room text
|> client.Send

0 comments on commit 83afe10

Please sign in to comment.