Pusher one to one chat structure

前端 未结 1 1043
醉酒成梦
醉酒成梦 2020-12-06 07:10

I\'m a bit confused on the presence-channels in Pusher\'s platform, as I\'m building a chat application from scratch. Now, I know some of you guys have seen ton

相关标签:
1条回答
  • 2020-12-06 07:39

    The purpose of private channels is to restrict who can subscribe to that channel. So, you can either:

    1. Use it to ensure only a users friends can subscribe to updates
    2. Use it for notifications only for that user

    In one-to-one chat I'd suggest you choose the latter (No.2).

    With this in mind I'd set out achieving one-to-one chat as follows:

    The Forum

    When users join the chat application they all subscribe to two channels:

    1. private-notifications-<user_id> where user_id is their unique user ID e.g. leggetter in my case. This channel is utilised for user-specific notifications.
    2. presence-forum for all users in that forum. The question called this presence-global.

    This is achieved as follows:

    var notifications = pusher.subscribe( 'private-notifications-user_one' );
    var forum = pusher.subscribe( 'presence-forum' );
    

    Upon subscription to each channel the channel authentication process will take place.

    Within the forum you could have a general public chat on the presence-forum/presence-global presence channel by sending and receiving messages.

    Starting one-to-one chat

    When one user (user_one) wants to have a private chat with another user (user_two) you obviously need something in the UI to trigger this. Say user_one clicks on something next to user_two that indicates they want a one-to-one chat. When this happens a request should be made to the server (the authority) to indicate that user_one wants to initiate the private chat with user_two†.

    Note: † if you chose a channel naming convention for one-to-one chat the private channel authentication could actually be used as the private one-to-one chat initiation

    When the server receives this request it can generate a unique private channel name for this one-to-one chat. A really simple way of doing this is by concatenating the user IDs e.g. private-chat-<initiating_user>-<receiving_user> (there are other considerations e.g. maybe you want to ensure the channel name is always the same between the two users). In our simple scenario the channel name would be private-chat-user_one-user_two.

    The server can then trigger a one-to-one-chat-request event on the private notification channel for each user delivering the one-to-one private chat channel name in the payload.

    // Trigger event on both user channels with one call
    var channels = [ 'private-notifications-user_one', 'private-notifications-user_two' ];
    // Additional event data could also be sent
    // e.g. more info on the initiating user
    var eventData = {
                      'channel_name': 'private-chat-user_one-user_two',
                      'initiated_by': 'user_one'
                      'chat_with'   : 'user_two'
                    };
    pusher.trigger( channels, 'one-to-one-chat-request', eventData );
    

    When user_one receives the one-to-one-chat-request they will subscribe to the eventData.channel_name channel and the auth process will take place for that channel.

    // A lookup of private chats
    // where the key is the user ID of the current user is chatting with
    var privateChats = {};
    notifications.bind( 'one-to-one-chat-request', function( data ) {
    
      // MY_USER_ID would need to be stored somewhere
      // and in this case the value would be 'user_one'.
      // expectingChatWith should make sure user_one is waiting for
      // a private chat response with the given user
      if( data.initiated_by === MY_USER_ID &&
          expectingChatWith( data.chat_with ) ) {
        startPrivateChat( data.chat_with, data.channel_name );
      }
    
    } );
    
    function startPrivateChat( withUserId, channelName ) {
      privateChats[ withUserId ] = pusher.subscribe( channelName );
    }
    

    When user_two receives the one-to-one-chat-request the user will need to be notified about the request and either accept or decline it. If the user accepts then the client-side code simply subscribes to the channel. If the user declines then a request should be sent to the server and an event triggered on private-notifications-user_one telling them their one-to-one chat request was declined. This will allow user_one to unsubscribe from the private chat channel.

    var privateChats = {};
    notifications.bind( 'one-to-one-chat-request', function( data ) {
    
      if( ... ) { ... }
      // has somebody request to chat with this user?
      else if( data.chatWith === MY_USER_ID ) {
        // Prompt the user
        // Note: more user info required
        displayChatPrompt( data );
      }
    
    } );
    
    // callback when the user accepts the chat request
    function accepted( chatUserId, channelName ) {
      startPrivateChat( chatUserId, channelName );
    }
    
    // the user doesn't want to chat
    function declined( chatUserId ) {
      // send info to the server indicating declined request
    }
    

    Private one-to-one chat success

    With both user_one and user_two subscribed to private-chat-user_one-user_two they can trigger events on the channel and participate in their private one-to-one chat.

    0 讨论(0)
提交回复
热议问题