I am trying to create a hip-chat alone... Currently figuring out what would be the best approach for enabling private messages in a chat application. Actual questions at listed at the end, but here is the general background.
Channels/Topics:
This is working fine and every thing is understood.
1. User views a list of channels to join.
2. ON JOIN user is subscribed to the topic (using onSubscribe)
3. User sends a message to channel and it is broad-casted to all.
4. ON PART user is unsubscripted from the topic
5. and so on..
Private Message (which is what the question is about):
I have couple of ideas on how to achieve this and looking for feedback:
A) RPC Approach
1. User sends an RPC to server with something like
session.call("private", {to: session/user, from: session/user, message: "My message for TO user", timestamp, etc..}).then(function (result) {
// do stuff with the result
}, function(error) {
// handle the error
});
2. Server gets the command and sends the callRequest to the receiver. This is perhaps not possible, as $id (from onCall()) is generated.
B) Using a global/internal topic
1. When user connects subscribe to a topic "system:all" (or something like that). Basically every user is subscribed to this topic.
ab.connect(
// The WebSocket URI of the WAMP server
wsuri,
function (session)
{
session.subscribe("system:all", function (topic, event){
handleSystemAll(topic, event);
})
}
...
}2. User publishes a message to "system:all" , with something like the following:
var myTopic = "system:all";
var myEvent = {eventname: "private", to: user/session, from: user/session, message: "my message"...};
sess.publish(myTopic, myEvent);3. Then on server side do something like this:
onPublish(ConnectionInterface $conn, Topic $topic, string $event)
{
if ($topic == "system:all")
{
if ($event['eventname'] == 'private')
{
$toUserConn = $this->getUserConnFromInternalStorage($event['user']);
$message = array(
'eventname' => $event['eventname'],
'message' => $event['message'],
'from' => $event['from']
);
$toUserConn->event($topic, $message);
}
}
}
4. And then finally some JS to display message to the user
function handleSystemAll(topic, event)
{
if (topic == 'system:all' && event.eventname == 'private')
console.log(event.from + ': ' + event.message);
}
Questions:
1. Is it possible for the server to initiate a callRequest() to a client, without $id?
2. Is it possible to for the server to send event() back to a client? In my testing it has not been the case (using autobahnjs). The user must be subscribed to a topic to receive message.
3. There are advantages to having the global topic, but using that for sending private message seems a bit hacky?
4. Any other ideas/feedback on how to achieve this?
Thanks for your feedback.