2011-09-06 69 views
1

我想找到一种方法来提取使用PID和JID的bosh会话(ejabberd)的SID,以便我可以在ejabberd_sm:unset_presence中使用它,我已经遍寻搜索但找不到方法来做到这一点。使用会话PID和JID提取SID

基本上,我建立了一个使用Ejabberd和Strophe的聊天系统,我试图实现的是当用户在一个页面上按下脱机按钮时,与该JID相关的所有会话都需要脱机,我已经通过PID使用ejabberd_sm:get_session_pid但无法找到提取SID的方法。我也试过SID ! Disconnect,但完全断开了我不想要的用户。

如果有人做过这种工作请帮助我,也欢迎其他实施此类事情的想法。

谢谢

回答

0

我做了一些挖掘和这里的交易。您从ejabberd_sm:get_session_pid获取的值是该用户会话的ejabberd_c2s进程。但ejabberd_c2s完全不知道BOSH。您真正需要的是用户的BOSH会话ID,它由模块ejabberd_http_bind维护。

尽我所能说,没有“好”的方法从ejabberd_c2s中获取这些信息。最后我做这样的事情:

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)), 

现在,这一切,让你在一天结束的是PID为ejabberd_http_bind过程。您可以再次重复整个肮脏的生意,但在这里我建议作弊一点:

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

正如你所看到的,这是窘况丑陋。更好的方法是修改ejabberd_c2s以接受将返回套接字信息的新类型sync_event,并同样修改ejabberd_http_bind以接受类似类型的事件以返回SID。当然,这些都将被包装在内部进行相关gen_fsm调用的公共功能中。

说了这么多,我不确定BOSH SID真的会对你有什么好处。特别是,我不确定在这种情况下“脱机”和“断开”之间有什么区别。但无论如何,这就是你如何获得信息。

+0

感谢您的信息Dan,我在我的问题中解释了为什么我需要SID,为了使用户“离线”强制需要,Disconnect将关闭我不想要的连接,我希望他们停留在连接上但显示为脱机状态。 – TilalHusain

+0

毫无疑问,这只是一个演示,而且太粗糙,不适合在真实代码中使用。相反,你应该从被记录的'element(4,St)'开始,然后在列表中进行模式匹配以找到另一个以进程ID开头的列表的元素,然后在*列表中找到另一个模式匹配与来自'ejabberd_c2s'的'state'记录相匹配的元素等等。 – Dan

+0

这种方法变得相当困难,而是我将所有的SID记录在mnesia表中,并将其用于我的目的。感谢所有的帮助。 – TilalHusain