1

I am trying to find a way for extracting SID of a bosh session (ejabberd) using PID and JID so that I can use it in ejabberd_sm:unset_presence, I have searched everywhere but can't find a way to do it.

Basically, I have built a chat system using Ejabberd and Strophe and what I am trying to achieve is when user press offline button on one page all the sessions associated with that JID needs to go offline, I have extraced the PID by using ejabberd_sm:get_session_pid but can't find a way to extrct SID. I have also tried SID ! Disconnect but that disconnects the user completely which I don't want.

If anybody has done this kind of work please help me, other ideas for implementing such thing are also welcome.

Thanks

TilalHusain
  • 1,006
  • 5
  • 17
  • 36

1 Answers1

0

I did some digging on this and here's the deal. The value you get back from ejabberd_sm:get_session_pid is the ejabberd_c2s process for that user's session. But ejabberd_c2s is entirely unaware of BOSH. What you really need is the user's BOSH session ID which is maintained by the module ejabberd_http_bind.

As best I can tell there's no "nice" way to get this information out of ejabberd_c2s. I ended up doing something like this:

St = sys:get_status(Pid),
State = lists:nth(3, lists:nth(5, element(4, St))),
SocketState = element(2, State),
BindPid = element(2, element(3, SocketState)),

Now, all that gives you at the end of the day is a PID for the ejabberd_http_bind process. You can repeat the whole sordid business again, but here I suggest cheating a little:

MS = ets:fun2ms(fun(#http_bind{pid=BP, id=Id}) when BP == BindPid  -> Id  end),
mnesia:dirty_select(http_bind, MS).

As you can see, this is horrendously ugly. The nicer way to do it would be to modify ejabberd_c2s to accept a new type of sync_event that would return the socket information, and likewise modify ejabberd_http_bind to accept a similar sort of event to return the SID. And of course, both of these would be wrapped in public functions that internally make the relevant gen_fsm calls.

All that said, I'm not sure what good the BOSH SID is really going to do you. And in particular, I'm not sure what the difference between "go offline" and "disconnect" is in this scenario. But anyway, that's how you get the information.

Dan
  • 10,990
  • 7
  • 51
  • 80
  • Thanks for the information Dan, I explained in my question why I need SID, it is required in order to make a user "OFFLINE" forcefully, where Disconnect will close the connection which I don't want, I want them to stay on the connection but appear offline. – TilalHusain Sep 07 '11 at 06:48
  • It goes without saying that this is just a demonstration and is way too crude to use in real code. Instead you should start with `element(4, St)` which is documented, and then pattern match on the list to find the element which is another list starting with a process ID, then another pattern match on *that* list to find the element which matches the `state` record from `ejabberd_c2s` and so on. – Dan Sep 07 '11 at 18:38
  • This method was getting quite difficult, Instead I logged all the SID's in a mnesia table and used that for my purpose. Thanks for all the help. – TilalHusain Sep 07 '11 at 19:28