Bug 182474 - [imchat][presence] API needed for creating conferences/group chats
Summary: [imchat][presence] API needed for creating conferences/group chats
Status: RESOLVED FIXED
Alias: None
Product: ECF
Classification: RT
Component: ecf.core (show other bugs)
Version: 1.0.1   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 1.1.0   Edit
Assignee: ecf.core-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted, plan
Depends on:
Blocks: 185816
  Show dependency tree
 
Reported: 2007-04-15 21:14 EDT by Remy Suen CLA
Modified: 2014-05-09 12:33 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Remy Suen CLA 2007-04-15 21:14:02 EDT
Currently, the presence API only supports the action of having the current user join an existing "persistent" chatroom. In MSN, Skype, and AIM/ICQ, a user can be invited to a user-created chatroom or the user can create his own and then subsequently start inviting others to join. When all participants have left, the room disappears into the nether void of the Internet never to be seen again.
Comment 1 Scott Lewis CLA 2007-04-18 17:41:20 EDT
+1 on adding this.  Can't commit to working on it right away, but only a resources issue.
Comment 2 Scott Lewis CLA 2007-04-28 02:44:41 EDT
I've added a new interface IChat with the methods below.  The idea here is that a two-way chat can/will be represented by an instance of IChat (retrieved from an as-yet-to-be-added method on IChatManager).  For providers that support it, IChat.createChatRoomContainer() will allow the dynamic creation of a chat room for n-way conversations.  providers that don't support will throw ContainerCreateExceptions.

Any thoughts/comments appreciated before implementation of API starts for providers that support (skype).

/**
 * Object representing a specific two-way chat.
 */
public interface IChat {

	/**
	 * Get the receiver for this chat.
	 * 
	 * @return ID of receiver.  Will not return <code>null</code>.
	 */
	public ID getReceiverID();

	/**
	 * Get the thread ID for this chat.
	 * 
	 * @return ID of this chat thread.  Will not return <code>null</code>.
	 */
	public ID getThreadID();

	/**
	 * Send chat message to given ID.
	 * 
	 * @param type
	 *            the IChatMessage.Type of the message. May not be null.
	 * 
	 * @param subject
	 *            the subject of the message. May be null.
	 * 
	 * @param body
	 *            the body of the message to send. May be null.
	 * 
	 * @param properties
	 *            properties associated with message. May be null.
	 * 
	 * @throws ECFException
	 *             thrown if toID is null, or currently disconnected
	 */
	public void sendChatMessage(IChatMessage.Type type, String subject,
			String body, Map properties) throws ECFException;

	
	/**
	 * Create a new IChatRoomContainer instance. This method can be used to
	 * create to a chat room identified by this two-way chat.  If supported
	 * by the provider, this allows moving from a two-way chat represented
	 * by this IChat instance to an n-way chat room container.
	 * 
	 * @return non-null IChatRoomContainer instance. Will not return
	 *         <code>null</code>.
	 * @throws ContainerCreateException
	 *             if chat room container cannot be made.
	 */
	public IChatRoomContainer createChatRoom() throws ContainerCreateException;
}





Comment 3 Remy Suen CLA 2007-04-28 07:35:01 EDT
Is the threadID intended to be the same as the IChatRoomContainer's ID?
Comment 4 Scott Lewis CLA 2007-04-28 10:29:45 EDT
(In reply to comment #3)
> Is the threadID intended to be the same as the IChatRoomContainer's ID?
> 

Yes, that was the thinking.
Comment 5 Scott Lewis CLA 2007-05-02 15:53:22 EDT
Added method IChatManager.createChat(ID targetUserID) to create instances of IChat.

/**
 * Create chat instance for given target user.
 * 
 * @param targetUser the targetUser to create chat for.  Should not be <code>null</code>.
 * If the user container is offline/disconnected. then an {@link ECFException} will
 * be thrown.  If this chat manager implementation does not support creating such chats,
 * then <code>null</code> will be returned.
 * 
 * @return IChat for given <code>targetUser</code>.  Will return <code>null</code> if
 * the underlying implementation does not support threads/specific chat instances.
 */
public IChat createChat(ID targetUser) throws ECFException;


Any thoughts/comments appreciated.  If this seems reasonable, I will begin impl on relevant providers (Skype initially).

In the mean time, all current implementations have been modified to simply return null when createChat is called.
Comment 6 Scott Lewis CLA 2007-05-04 19:12:30 EDT
API now in place in org.eclipse.ecf.presence.im.IChatManager/IChat as described in comment #2 and #5.  
Comment 7 Scott Lewis CLA 2007-05-07 13:39:48 EDT
Resolving this bug as fixed.  Created bug

https://bugs.eclipse.org/bugs/show_bug.cgi?id=185816

to provide implementation of API in Skype provider.
Comment 8 Remy Suen CLA 2007-05-19 07:43:02 EDT
Looking at it all now, I'm not entirely sure as to what purpose this IChat serves if we need to create IChatRoomContainer and then do other things with it first. You can send messages from an IChat (is an exception supposed to be thrown if the ICRC hasn't been created?) but you can't listen to the messages of this chat.
Comment 9 Scott Lewis CLA 2007-05-19 18:44:25 EDT
(In reply to comment #8)
> Looking at it all now, I'm not entirely sure as to what purpose this IChat
> serves if we need to create IChatRoomContainer and then do other things with it
> first. 

Why is this a problem?  If going from a two-way chat and turning it into a conference there has to be *some* way to add beyond original two participants...whether that be  to create a chat room container and add people (this approach), or something else (api on IChat directly).

>You can send messages from an IChat (is an exception supposed to be
> thrown if the ICRC hasn't been created?) but you can't listen to the messages
> of this chat.

The IIMMessageListener will receive IChatMessageEvents and these supply access to IChatMessage instances that have threadID the same as the IChat threadID (so they can be easily associated).  This provides a way to listen to the messages of this chat.

Another approach which could be done is to have the IChatManager.createChat have signature

IChat createChat(ID targetUser, IIMMessagerListener listener)

to associate a listener with a specific IChat instance.  Hard to say which is better...comments?

Comment 10 Remy Suen CLA 2007-05-19 19:05:43 EDT
(In reply to comment #9)
> Why is this a problem?  If going from a two-way chat and turning it into a
> conference there has to be *some* way to add beyond original two
> participants...whether that be  to create a chat room container and add people
> (this approach), or something else (api on IChat directly).

Are people supposed to be able to use sendChatMessage after the IChat has been created instantly for two-way chatting purposes? If yes, the whole setup just seems really weird to me. If I can already send messages, why would I need an IChatRoomContainer for calling connect? I don't need to connect...because I've already connected.

Think of it like a real phone conference, I can talk with someone else but then I can dial another number and invite a third person arbitrarily at any time during the conversation. The "connect" aspect here is more an issue of providing a unique identifier for that person and not really an ID for a chat room. It also makes no sense to keep calling connect targeting different user IDs each time because I'm pretty sure that that's not what the connect method is supposed to be for.
Comment 11 Scott Lewis CLA 2007-05-19 19:33:39 EDT
(In reply to comment #10)
> (In reply to comment #9)
> > Why is this a problem?  If going from a two-way chat and turning it into a
> > conference there has to be *some* way to add beyond original two
> > participants...whether that be  to create a chat room container and add people
> > (this approach), or something else (api on IChat directly).
> 
> Are people supposed to be able to use sendChatMessage after the IChat has been
> created instantly for two-way chatting purposes? If yes, the whole setup just
> seems really weird to me. If I can already send messages, why would I need an
> IChatRoomContainer for calling connect? I don't need to connect...because I've
> already connected.

In the Skype world yes.  But Skype is unlike most systems (e.g. Yahoo, XMPP...MSN I don't know) in that it supports moving from a two-way conversation to a conference 'in place' (i.e. without having a separate session).

> 
> Think of it like a real phone conference, I can talk with someone else but then
> I can dial another number and invite a third person arbitrarily at any time
> during the conversation. The "connect" aspect here is more an issue of
> providing a unique identifier for that person and not really an ID for a chat
> room. It also makes no sense to keep calling connect targeting different user
> IDs each time because I'm pretty sure that that's not what the connect method
> is supposed to be for.


Most IM systems do *not* treat two-way chats/conversations like conferences...that is, it's usually a separate connect/join operation to reach a conference.  Telephony is like this of course...you have to connect to a different number to have a conference when starting from a two-way conversation.  In such a case, connect is needed (possibly with authentication).

I'm not saying that having conferences and two-way interactions separate is a 'better' way...I like the flexibility to just add people onto a two-way conversation.  But I would like to try to have abstractions that don't have two, totally different kinds of conference sessions (i.e. IChatRoomContainer) just to accomodate both approaches...hence the API for 'converting' from an IChat to an IChatRoomContainer.

I'm open to suggestions/thoughts about alternatives.  None of this has implementation yet so we can/could do other things.


Comment 12 Remy Suen CLA 2007-05-19 19:50:21 EDT
(In reply to comment #11)
> In the Skype world yes.  But Skype is unlike most systems (e.g. Yahoo,
> XMPP...MSN I don't know) in that it supports moving from a two-way conversation
> to a conference 'in place' (i.e. without having a separate session).
For the record, MSN follows a similar model, which would kind of explain why this issue caught my eye. ;p

> Most IM systems do *not* treat two-way chats/conversations like
> conferences...that is, it's usually a separate connect/join operation to reach
> a conference.
What would the target ID for the connect method be for the protocols that don't need this?...Is what I'm lost about.
Comment 13 Scott Lewis CLA 2007-05-19 19:53:58 EDT
(In reply to comment #12)
> (In reply to comment #11)
> > In the Skype world yes.  But Skype is unlike most systems (e.g. Yahoo,
> > XMPP...MSN I don't know) in that it supports moving from a two-way conversation
> > to a conference 'in place' (i.e. without having a separate session).
> For the record, MSN follows a similar model, which would kind of explain why
> this issue caught my eye. ;p
> 
> > Most IM systems do *not* treat two-way chats/conversations like
> > conferences...that is, it's usually a separate connect/join operation to reach
> > a conference.
> What would the target ID for the connect method be for the protocols that don't
> need this?...Is what I'm lost about.
> 

I've been assuming it would be the room ID.  If already connected (e.g. skype chat), I've been assuming connect would be noop.

Comment 14 Remy Suen CLA 2007-05-19 20:08:15 EDT
(In reply to comment #13)
> > What would the target ID for the connect method be for the protocols that don't
> > need this?...Is what I'm lost about.
> > 
> 
> I've been assuming it would be the room ID.  If already connected (e.g. skype
> chat), I've been assuming connect would be noop.

Well, yes, it would be a noop in those cases but users would still need to be of the mindset that the call to connect is necessary. I guess they could always just use getConnectedName().createInstance(null) or something and pass that in.
Comment 15 Scott Lewis CLA 2007-05-20 00:59:29 EDT
One thought I had this evening. 

Perhaps it would be better to have IChatRoomContainer *not* inherit from IContainer, but rather have an explicit call like this

(proposed new method in IChatRoomContainer):

public void joinRoom(IConnectContext connectContext) throws ContainerConnectException

public void leaveRoom();

public ID getID();

public boolean isJoined();

This would make things simpler, don't you think?

Scott


(In reply to comment #14)
> (In reply to comment #13)
> > > What would the target ID for the connect method be for the protocols that don't
> > > need this?...Is what I'm lost about.
> > > 
> > 
> > I've been assuming it would be the room ID.  If already connected (e.g. skype
> > chat), I've been assuming connect would be noop.
> 
> Well, yes, it would be a noop in those cases but users would still need to be
> of the mindset that the call to connect is necessary. I guess they could always
> just use getConnectedName().createInstance(null) or something and pass that in.
> 

Comment 16 Remy Suen CLA 2007-05-20 11:36:59 EDT
(In reply to comment #15)
> public void joinRoom(IConnectContext connectContext) throws
> ContainerConnectException

So the connect context would wrap the target ID for those that need it and be ignored for those that don't (like just pass in null or whatever)?
Comment 17 Scott Lewis CLA 2007-05-20 12:51:24 EDT
(In reply to comment #16)
> (In reply to comment #15)
> > public void joinRoom(IConnectContext connectContext) throws
> > ContainerConnectException
> 
> So the connect context would wrap the target ID for those that need it and be
> ignored for those that don't (like just pass in null or whatever)?
> 

No, actually I was thinking that the targetID/roomID would be redundant...as it's already known to the IChatRoomContainer (if gotten from IChatRoomInfo, or gotten from IChat).  So it wouldn't actually be needed for a join/connect call.

Comment 18 Remy Suen CLA 2007-05-20 13:13:39 EDT
(In reply to comment #17)
> No, actually I was thinking that the targetID/roomID would be redundant...as
> it's already known to the IChatRoomContainer (if gotten from IChatRoomInfo, or
> gotten from IChat).  So it wouldn't actually be needed for a join/connect call.

I'm having problems visualizing this, can you type up some code?

Another concern I have is how a two-way chat can be aware of the fact that another user has joined.
Comment 19 Scott Lewis CLA 2007-05-20 14:50:52 EDT
(In reply to comment #18)
> (In reply to comment #17)
> > No, actually I was thinking that the targetID/roomID would be redundant...as
> > it's already known to the IChatRoomContainer (if gotten from IChatRoomInfo, or
> > gotten from IChat).  So it wouldn't actually be needed for a join/connect call.
> 
> I'm having problems visualizing this, can you type up some code?

Actually, after thinking about the implications a little I don't think this is a good idea (i.e. disinheriting IChatRoomContainer from IContainer and defining these new join/leave methods instead of connect/disconnect).  After some additional rumination (and sleep) I think it would essentially mean replacing IContainer.addListener/removeListener, getConnectedID(), connect and disconnect with very similar/identical methods. 

So without further cause, let's leave IChatRoomContainer inheriting from IContainer.

As for IChatRoomContainer.connect...I think the behavior should be:

If the IChatRoomContainer instance is created via IChatRoomInfo.createContainer(), then the targetID for connect is the desired roomID to connect to...typically the value returned from the associated IChatRoomInfo.getRoomID().  Before calling connect(targetID,cc), getConnectedID() will return null (not connected), and after it will return the roomID.

If an IChatRoomContainer is created via IChat.createChatRoomContainer(), then it will return the associated threadID/roomID via getConnected() (and so calling connect will be unnecessary/redundant).

So, code like this will work for both situations (chat rooms created via IChat or those created via IChatRoomInfo):

if (chatRoomContainer.getConnectedID() == null) {
    chatRoomContainer.connect(roomID,roomConnectContext);
}

> 
> Another concern I have is how a two-way chat can be aware of the fact that
> another user has joined.
> 

I guess I don't understand what you mean here.  Do you mean that if IChatRoomContainer is created via IChat.createChatRoomContainer() that then the chat members can be aware that others have joined?  If this is what you mean, it seems OK to me as the 'chat' has been transformed to a 'chat room' (explicitly, rather than starting out as a conference with only two members...as Skype and MSN apparently do).



  

Comment 20 Remy Suen CLA 2007-05-20 16:01:44 EDT
(In reply to comment #19)
> > Another concern I have is how a two-way chat can be aware of the fact that
> > another user has joined.
> > 
> 
> I guess I don't understand what you mean here.  Do you mean that if
> IChatRoomContainer is created via IChat.createChatRoomContainer() that then the
> chat members can be aware that others have joined?  If this is what you mean,
> it seems OK to me as the 'chat' has been transformed to a 'chat room'
> (explicitly, rather than starting out as a conference with only two
> members...as Skype and MSN apparently do).

When you call someone you're just talking to that person alone, but once you tie in someone, there are two people. Right now, this notion is hidden to the developer since you are just arbitrarily sending messages around with IChatMessageSender and IIMMessageListener and for listening to messages. But you have no idea when that link between two persons has now became a link between three persons. Does that make sense?
Comment 21 Scott Lewis CLA 2007-05-20 16:19:44 EDT
(In reply to comment #20)
> (In reply to comment #19)
> > > Another concern I have is how a two-way chat can be aware of the fact that
> > > another user has joined.
> > > 
> > 
> > I guess I don't understand what you mean here.  Do you mean that if
> > IChatRoomContainer is created via IChat.createChatRoomContainer() that then the
> > chat members can be aware that others have joined?  If this is what you mean,
> > it seems OK to me as the 'chat' has been transformed to a 'chat room'
> > (explicitly, rather than starting out as a conference with only two
> > members...as Skype and MSN apparently do).
> 
> When you call someone you're just talking to that person alone, but once you
> tie in someone, there are two people. Right now, this notion is hidden to the
> developer since you are just arbitrarily sending messages around with
> IChatMessageSender and IIMMessageListener and for listening to messages. But
> you have no idea when that link between two persons has now became a link
> between three persons. 

Unless I'm not understanding, that's what the IChat instance is supposed to do...make explicit that one has a specific 'two-way/two-person' conversation going (aka threadID for XMPP)...without this, you are right that there is nothing to distinguish target users from 'sessions/threads/conversations'.

So I think it's OK to associate the capability to create a chat room from a valid IChat instance...as if the provider doesn't support creating such a two-way 'session/thread/conversation', then it can't support creating a chat room from it (i.e. if you can't get an IChat, then then you can't make it into a chat room).

It does, however, mean more complexity for programmers, since they have to manage IChat instances (rather than just calling sendMessage/handleMessage).
Comment 22 Remy Suen CLA 2007-05-24 22:39:40 EDT
Reopening this since an IChat is incapable of knowing that it's now become a "chat room" when an additional user has joined the chat session.
Comment 23 Scott Lewis CLA 2007-05-25 12:39:24 EDT
I'm thinking of the following change/addition to handle this case (an IChat being notified asynchronously that it has become/is becoming a chat room):

Current (in IChatManager)

IChat createChat(ID targetID);

Suggested

IChat createChat(ID targetID, IIMMessageListener chatListener);

The IIMMessageListener would then be notified (with new event type) when an IChat was being changed into a chat room to satisfy the requirement for this bug.  The expectation would be that the chatListener would have to be non-null.

The IIMMessageListener would also then receive chat message events scoped to that IChat.  Making the IChat.addMessageListener unnecessary.

Thoughts/comments?




Comment 24 Scott Lewis CLA 2007-05-25 12:42:07 EDT
(In reply to comment #23)
<stuff deleted>

> The IIMMessageListener would also then receive chat message events scoped to
> that IChat.  Making the IChat.addMessageListener unnecessary.

I meant to say:  Making the IChatManager.addMessageListener unnecessary.

Comment 25 Remy Suen CLA 2007-05-25 12:45:01 EDT
(In reply to comment #24)
> I meant to say:  Making the IChatManager.addMessageListener unnecessary.

Unnecessary as in that method will be removed?
Comment 26 Scott Lewis CLA 2007-05-25 14:41:09 EDT
(In reply to comment #25)
> (In reply to comment #24)
> > I meant to say:  Making the IChatManager.addMessageListener unnecessary.
> 
> Unnecessary as in that method will be removed?
> 

We could potentially remove IChatManager.addMessageListener/removeMessageListener (and, in fact,  getChatMessageSender(), getTypingMessageSender()).  I'm a little hesitant to do so, however, as it makes the API more complex (have to call IChatManager.createChat to engage in chat)...but admittedly more consistent.

I wasn't thinking that the IChatManager methods would be removed in proposing this rather IChat would be a complete alternative to IChatManager.*.

Comment 27 Scott Lewis CLA 2007-05-26 12:22:52 EDT
(In reply to comment #26)
> (In reply to comment #25)
> > (In reply to comment #24)
> > > I meant to say:  Making the IChatManager.addMessageListener unnecessary.
> > 
> > Unnecessary as in that method will be removed?
> > 
> 
> We could potentially remove
> IChatManager.addMessageListener/removeMessageListener (and, in fact, 
> getChatMessageSender(), getTypingMessageSender()).  I'm a little hesitant to do
> so, however, as it makes the API more complex (have to call
> IChatManager.createChat to engage in chat)...but admittedly more consistent.
> 
> I wasn't thinking that the IChatManager methods would be removed in proposing
> this rather IChat would be a complete alternative to IChatManager.*.
> 

I'm going to checkin API additions this weekend (5/26-27) to implement this unless someone objects.  Please review with others if possible.
Comment 28 Scott Lewis CLA 2007-05-26 19:38:08 EDT
Checked into HEAD:

1) Changed IChatManager.createChat(ID) to IChatManager.createChat(ID,IIMMessageListener) as per comment #23.

2) Updated known (trivial) implementations of IChatManager:  xmpp, yahoo, msn, jxta

3) Added IChatRoomCreationEvent.  This event is delivered asynchronously to the IIMMessageListener of the remote IChat instance when the IChat.createChatRoomContainer() method is called (to notify the remote of the 
creation of a chat room from the IChat).

4) Added IChatMessageEvent.getChat() to allow IIMMessageListener to get the IChat associated with a chat message.  If one not available (IChat not supported by provider), then this method returns null.  Implemented this interface in ChatMessageEvent.

5) Added javadocs for all of the above and added to existing javadocs for other associated methods.

No implementation yet exists of IChat/etc.  Question: skype (bug #185186) or xmpp first?

Comment 29 Scott Lewis CLA 2007-06-20 17:12:05 EDT
Changing version target to 1.0.1.  Won't be addressed in 1.0.0.
Comment 30 Scott Lewis CLA 2007-07-22 21:00:26 EDT
API in place, but providers are not (for xmpp, skype in that order probably).  Setting target milestone to 1.1.0.
Comment 31 Scott Lewis CLA 2007-09-04 19:50:22 EDT
(In reply to comment #30)
> API in place, but providers are not (for xmpp, skype in that order probably). 
> Setting target milestone to 1.1.0.
> 

So the API for this is in place, but the implementation is not.  I'm inclined to create a new enhancement/bug for the impl (for xmpp, say) and resolve this one.  Any objections to that...or are there some other API issues that need to be dealt with on this?
Comment 32 Scott Lewis CLA 2014-05-09 12:33:30 EDT
API for this in place as per comment 28.  Resolving as fixed.  If committer or contributor resources become available to provide implementations then please create new enhancement.