1
votes

In play framework we can see websocket-chat application that shows us usage of Concurrent.broadcast to handle websocket messages.

But I want to use websockets to send messages to each connected websocket independently. Simpliest example is something like private messages, when user sends message like: {user: "First", to: "Second", message: "Hi"}.

I looked at object play.api.libs.iteratee.Concurrent, looks like most suitable there is Concurrent.unicast to do this. But when we have Concurrent.broadcast - we have channel where we can push messages. In case of Concurrent.unicast - we have just Enumerator.

So, how can I dispatch private messages between websockets with Play Framework 2.2 in Scala?

2

2 Answers

1
votes

I found another way to archive the private messaging problem out from the source code of the play framework sample. By using a filtered enumerator for each user:

val filteredEnumerator = enumerator &> Enumeratee.filter[JsValue]( e =>  {
    if ( (e \ "kind").as[String] == "talk") {
      val isToAll = (e \ "recipient").as[String] == "all"
      val isToRecipient = (e \ "recipient").as[String] == username
      val isFromRecipient = (e \ "user").as[String] == username
      isToAll || isToRecipient || isFromRecipient
    } else {
      true
    }
  })
  sender ! Connected(filteredEnumerator)

So, the message is being passed to the enumerator if the kind is "talk" (we only want to filter the messages), recipient is "all", recipient is the username itself or if user is the username itself so the person sent the message also sees the message.

0
votes

the reply in the Chat room application is sent to All users in the Room via:

// Send a Json event to all members public void notifyAll(String kind, String user, String text) {

So if you would like to implement a private message then you will have to implement "notify" method that will send message only to one specific user. Say something like:

// Send a Json event to all members
public void notify(String kind, String user, String userTo, String text) {
    for(WebSocket.Out<JsonNode> channel: members.values()) {

        ObjectNode event = Json.newObject();
        event.put("kind", kind);
        event.put("user", user);
        event.put("message", text);

        ArrayNode m = event.putArray("members");
        m.add(userTo);

        channel.write(event);
    }