Pubnub chat application with storage

2020-02-13 04:04发布

问题:

I'm looking to develop a chat application with Pubnub where I want to make sure all the chat messages that are send is been stored in the database and also want to send messages in chat.

I found out that I can use the Parse with pubnub to provide storage options, But I'm not sure how to setup those two in a way where the messages and images send in the chat are been stored in the database.

Anyone have done this before with pubnub and parse? Are there any other easy options available to use with pubnub instead of using parse?

回答1:

Sutha,

What you are seeking is not a trivial solution unless you are talking about a limited number of end users. So I wouldn't say there are no "easy" solutions, but there are solutions.

The reason is your server would need to listen (subscribe) to every chat channel that is active and store the messages being sent into your database. Imagine your app scaling to 1 million users (doesn't even need to get that big, but that number should help you realize how this can get tricky to scale where several server instances are listening to channels in a non-overlapping manner or with overlap but using a server queue implementation and de-duping messages).

That said, yes, there are PubNub customers that have implemented such a solution - Parse not being the key to making this happen, by the way.

You have three basic options for implementing this:

  1. Implement a solution that will allow many instances of your server to subscribe to all of the channels as they become active and store the messages as they come in. There are a lot of details to making this happen so if you are not up to this then this is not likely where you want to go.

  2. There is a way to monitor all channels that become active or inactive with PubNub Presence webhooks (enable Presence on your keys). You would use this to keep a list of all channels that your server would use to pull history (enable Storage & Playback on your keys) from in an on-demand (not completely realtime) fashion.

For every channel that goes active or inactive, your server will receive these events via the REST call (and endpoint that you implement on your server - your Parse server in this case):

  • channel active: record "start chat" timetoken in your Parse db
  • channel inactive: record "end chat" timetoken in your Parse db
  • the inactive event is the kickoff for a process that uses start/end timetokens that you recorded for that channel to get history from for channel from PubNub: pubnub.history({channel: channelName, start:startTT, end:endTT})
  • you will need to iterate on this history call until you receive < 100 messages (100 is the max number of messages you can retrieve at a time)
  • as you retrieve these messages you will save them to your Parse db

New Presence Webhooks have been added: We now have webhooks for all presence events: join, leave, timeout, state-change.

  1. Finally, you could just save each message to Parse db on success of every pubnub.publish call. I am not a Parse expert and barely know all of its capabilities but I believe they have some sort or store local then sync to cloud db option (like StackMob when that was a product), but even if not, you will save msg to Parse cloud db directly.

The code would look something like this (not complete, likely errors, figure it out or ask PubNub support for details) in your JavaScript client (on the browser).

var pubnub = PUBNUB({
    publish_key   : your_pub_key,
    subscribe_key : your_sub_key
});

var msg = ... // get the message form your UI text box or whatever

pubnub.publish({
    // this is some variable you set up when you enter a chat room
    channel: chat_channel, 
    message: msg
    callback: function(event){
        // DISCLAIMER: code pulled from [Parse example][4] 
        // but there are some object creation details
        // left out here and msg object is not
        // fully fleshed out in this sample code

        var ChatMessage = Parse.Object.extend("ChatMessage");
        var chatMsg = new ChatMessage();
        chatMsg.set("message", msg);
        chatMsg.set("user", uuid);
        chatMsg.set("channel", chat_channel);
        chatMsg.set("timetoken", event[2]);
        // this ChatMessage object can be 
        // whatever you want it to be
        chatMsg.save();
    }
    error: function (error) {
        // Handle error here, like retry until success, for example
        console.log(JSON.stringify(error));
    }

});

You might even just store the entire set of publishes (on both ends of the conversation) based on time interval, number of publishes or size of total data but be careful because either user could exit the chat and the browser without notice and you will fail to save. So the per publish save is probably best practice if a bit noisy.

I hope you find one of these techniques as a means to get started in the right direction. There are details left out so I expect you will have follow up questions.

Just some other links that might be helpful:

  • http://blog.parse.com/learn/building-a-killer-webrtc-video-chat-app-using-pubnub-parse/
  • http://www.pubnub.com/blog/realtime-collaboration-sync-parse-api-pubnub/
  • https://www.pubnub.com/knowledge-base/discussion/293/how-do-i-publish-a-message-from-parse

And we have a PubNub Parse SDK, too. :)