【问题标题】:channel creation for one to one chat using Pubnub in Ionic3在 Ionic3 中使用 Pubnub 为一对一聊天创建频道
【发布时间】:2018-01-04 09:49:16
【问题描述】:

我已经使用 pubnub 在 Ionic3 中实现了聊天。它适用于群聊。用于群聊的频道是“group1-ch”。我在这里添加了我的代码。我在开发一对一聊天时遇到了一些困难。

发布服务

import {Injectable, EventEmitter} from '@angular/core';
declare var PUBNUB;
type OnMessageFn = (message, envelope, channelOrGroup, time, channel) => void;

export enum PubNubEventType {
    MESSAGE,
    CONNECT,
    DISCONNECT,
    RECONNECT,
    PUBLISHED,
    HISTORY,
    PRESENCE
}

export class PubNubEvent {
    constructor(public type: PubNubEventType, channel:string, public value: any) {}
}

@Injectable()
export class PubNubService {

    pubnub:any;

    /**
     * Call this method after platform becomes to be ready
     */
    // init() {
    constructor() {

    }
    connectionuuid(uuid){
     this.pubnub = PUBNUB({

            subscribe_key: '*********************************',
            publish_key:   '*********************************',
            uuid:uuid,
            ssl: true,
            secret_key: '**************************************'

        });
    }

    subscribe(channel:string):EventEmitter<PubNubEvent> {
        let eventEmitter:EventEmitter<PubNubEvent> = new EventEmitter<PubNubEvent>();
        this.pubnub.subscribe({
            channel : channel,
            withPresence: true,
            presence : (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.PRESENCE, channel, message));
            },
            message : (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.MESSAGE, channel, message));
            },
            connect: (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.CONNECT, channel, message));
            },
            disconnect: (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.DISCONNECT, channel, message));
            },
            reconnect: (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.RECONNECT, channel, message));
            },
            error: (error) => {
                eventEmitter.error(error);
            }, 
        });
        return eventEmitter;
    }

    publish(channel:string, message:any, store_in_history:boolean = true):EventEmitter<PubNubEvent> {
        let eventEmitter:EventEmitter<PubNubEvent> = new EventEmitter<PubNubEvent>();
        this.pubnub.publish({
            channel: channel, 
            message: message, 
            store_in_history: store_in_history, 
            callback : (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.PUBLISHED, channel, message));
            },
            // Executes on a publish error.
            error: (error) => {
                eventEmitter.error(error);
            }
        });
        return eventEmitter;
    }

    individual_chat(channel:string, message:any, store_in_history:boolean = true):EventEmitter<PubNubEvent> {
        let eventEmitter:EventEmitter<PubNubEvent> = new EventEmitter<PubNubEvent>();
        this.pubnub.publish({
            channel: channel,        
            message: message, 
            store_in_history: store_in_history, 
            callback : (message) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.PUBLISHED, channel, message));
            },
            // Executes on a publish error.
            error: (error) => {
                eventEmitter.error(error);
            }
        });
        return eventEmitter;
    }

    history(channel: string, count:number = 100, start:number = null, end:number = null, reverse:boolean = true, include_token: boolean = true):EventEmitter<PubNubEvent> {
        let eventEmitter:EventEmitter<PubNubEvent> = new EventEmitter<PubNubEvent>();
        this.pubnub.history({
            channel: channel,
            callback: (messages) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.HISTORY, channel, messages));
            },
            error: (error) => {
                eventEmitter.error(error);
            },
            count: count,
            start: start,
            end: end,
            reverse: reverse,
            include_token: include_token
        });
        return eventEmitter;
    }

    here_now(channel: string, count:number = 100, start:number = null, end:number = null, reverse:boolean = true, include_token: boolean = true):EventEmitter<PubNubEvent>{
        let eventEmitter:EventEmitter<PubNubEvent> = new EventEmitter<PubNubEvent>();
        this.pubnub.here_now({
        channel: channel,
        callback: (m) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.PRESENCE, channel, m));
            },
            error: (error) => {
                eventEmitter.error(error);
            },
            count: count,
            start: start,
            end: end,
            reverse: reverse,
            include_token: include_token
       });
        return eventEmitter;
    }
    where_now(channel: string, count:number = 100, start:number = null, end:number = null, reverse:boolean = true, include_token: boolean = true):EventEmitter<PubNubEvent>{
        let eventEmitter:EventEmitter<PubNubEvent> = new EventEmitter<PubNubEvent>();
        this.pubnub.where_now({
        uuid: channel,
        callback: (m) => {
                eventEmitter.emit(new PubNubEvent(PubNubEventType.PRESENCE, channel, m));
            },
            error: (error) => {
                eventEmitter.error(error);
            },
            count: count,
            start: start,
            end: end,
            reverse: reverse,
            include_token: include_token
       });
        return eventEmitter;
    }
}

我的要求

  1. 谁能告诉我如何为一对一聊天创建“频道”?
  2. 接收方如何知道发送方正在使用哪个频道?

感谢和问候

阿南德·拉杰

【问题讨论】:

  • 对这种情况有什么帮助吗?
  • 这是关于在两个用户之间发起聊天的设计模式问题。从Chat Fundamentals 开始,并查看其他Design Patterns 以获得更强大的应用程序要求。还可以考虑PubNub ChatEngine,虽然它目前没有 Ionic 实现,但是还有其他框架选项。
  • 虽然有一个 Angular 示例:github.com/pubnub/chat-engine#angular
  • @CraigConover 嗨,克雷格,感谢您的回复。假设我有(“Anand”)5 个用户(A、B、C、D、E)的列表,我想单独与每个用户聊天。所以我必须有5个不同的渠道,对吧?那么如何命名通道呢?如果我为用户 A 命名频道 AnandA,那么用户如何知道我正在通过频道“AnandA”与 A 聊天?

标签: angular ionic2 chat pubnub


【解决方案1】:

高级聊天邀请设计模式

让我使用更具体的名称:Anand、Craig、John。每个用户都应该订阅一个 inbound 频道,他们会收到有关邀请的通知:

  • Anand 订阅了inbound.anand
  • 克雷格订阅inbound.craig
  • 约翰订阅了inbound.john

如果您知道要联系的用户名,现在您可以随时知道向哪个频道发送(发布)邀请到另一个入站频道。您可以发送消息邀请他们聊天并将频道作为单独的值提供:

{
    "message": "Hi, this is Anand. I would like to invite you to chat with me.",
    "chat_channel": "abc123",
    "sender_id": "anand"
}

这只是一个简单的示例消息,可能更复杂,但重点是,您想向要邀请的人发送消息并提供频道名称(可以是随机生成的字符串或类似 andand_craig ,只要它是 Anand 和 Craig 使用唯一用户名的唯一频道名称)。

您的用户界面将为受邀用户提供一种方式来单击接受拒绝按钮来响应邀请。

  • 如果 Accept 被点击,那么受邀用户将向inbox.anand 或提供的chat_channel 发布一条消息,anand订阅,然后也订阅提供的chat_channel,开始与anand聊天。

这是一种相当简化的设计模式,但应该提供一些关于如何在两个人甚至一群人之间发起对话的见解。

有关推荐设计模式的更多详细信息:

您还可以考虑使用具有内置聊天功能的PubNub's ChatEngine framework。对于 Angular,请参阅 Simple Angular ChatEngine example

【讨论】:

  • 我已按照您的步骤进行操作。但是卡在创建动态频道的地方。
  • @Craid,您能否分享一个使用动态频道创建和接受聊天请求的示例?
  • 创建动态频道只是意味着您的应用会想出一种方法来命名新频道。例如,您可以使用 UUID 生成器(PubNub 在其 API 中有一个)。或者您可以只使用与目标用户名连接的当前用户名,但请确保这会产生唯一的频道名称,如果您的用户名是唯一的,则应该这样做。所以这真的取决于你。无论您创建的频道名称是什么,只需在目标用户入站频道的“邀请”消息中发布该频道名称即可。
  • 根据您的示例,使用相同的用户。如果 Anand 想与 Craig 聊天,则创建了一个名为“outbound-AnandCraig”的频道。通过“outbound-AnandCraig”频道向 Craig 发送邀请。我的疑问是为了接收聊天请求接收者也应该订阅''outbound-AnandCraig'',对吗?第二个疑问是发布/订阅API中是否有任何参数可以识别请求是否是第一次来?
  • 关闭,但没有。在inbox.craig 上使用outbound.anand_craig 将邀请发送给Craig(在名称之间放置一个分隔符,稍后您会感谢我),因为Craig 尚未订阅新的出站频道。出站是错误的前缀,我称之为 prchat (用于私人聊天)或类似的东西,因为它是一个双向通道。并且没有关于它是什么类型的消息的 API。每条消息都只是给 PubNub 的一条消息。您可以像 "senderid"::anand" 一样在 JSON 消息中创建自定义属性。有意义吗?
猜你喜欢
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多